diff --git a/.github/workflows/adhoc-mac-build.yml b/.github/workflows/adhoc-mac-build.yml index 325ab73a847..03d2c76ccc0 100644 --- a/.github/workflows/adhoc-mac-build.yml +++ b/.github/workflows/adhoc-mac-build.yml @@ -33,6 +33,13 @@ name: Adhoc macOS Dev Build # Contents: Read and write. The secret names below are historical — one App, one # private key, both dev-channel repos — and rotating it stays a single operation. # Provision with `bash config/scripts/setup-hourly-release-token.sh`. +# +# The requested ref is vetted before checkout: it must be a branch or tag of this +# repo, or a commit reachable from one. PR refs are refused outright — this +# workflow runs the checked-out code next to MAC_CERTS and the notary password, +# so "just build that community PR" must not become a way to hand fork code the +# release identity. A branch here always belongs to someone with write access, +# which is the same trust the dispatch button itself already requires. on: workflow_dispatch: @@ -45,7 +52,7 @@ on: # than the one the workflow file itself is read from — normally leave the # picker on main and name your branch here, so a stale copy of this # workflow on an old branch is not what runs. - description: 'Branch, tag, or SHA to build (default: the branch selected above)' + description: 'Branch, tag, or SHA to build — must live in stablyai/orca; PR refs are refused (default: the branch selected above)' required: false default: '' type: string @@ -77,6 +84,14 @@ env: jobs: build-adhoc-mac: if: github.repository == 'stablyai/orca' + # Why an environment: it gives the signing/notary/App secrets somewhere to + # live that a stale copy of this workflow on an old branch cannot reach. + # Referencing it is a no-op until repo settings give it teeth; the intended + # follow-up is to move MAC_CERTS, MAC_CERTS_PASSWORD, APPLE_ID, + # APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID, HOURLY_RELEASE_APP_ID, and + # HOURLY_RELEASE_APP_PRIVATE_KEY into it, then pin its deployment branch + # policy to main so only main's copy of this file can read them. + environment: adhoc-mac-build runs-on: blacksmith-6vcpu-macos-15 # Why 150: it must exceed the worst case the retry budgets below can produce # (install 3x10 + publish 2x45 = 120, plus ~25 for checkout/build/verify), or @@ -85,6 +100,57 @@ jobs: env: NODE_OPTIONS: --max-old-space-size=4096 steps: + # Why vet before checkout: everything after this step runs the checked-out + # code with release signing credentials in reach. Branches and tags of this + # repo are the intended audience; refs/pull/* would smuggle in fork code, + # and a raw SHA is only accepted when some branch or tag of this repo can + # actually reach it. Resolving to a pinned SHA here also means the commit + # that was vetted is the commit that gets checked out — a push to the + # branch between the two steps cannot swap it. + - name: Vet the requested ref + id: vetted + shell: bash + env: + REQUESTED_REF: ${{ inputs.ref || github.ref_name }} + REPO_URL: https://github.com/${{ github.repository }} + run: | + set -euo pipefail + case "$REQUESTED_REF" in + refs/pull/*|pull/*) + echo "::error::Refusing to build PR ref '$REQUESTED_REF': this workflow signs with release credentials, so it only builds branches, tags, or commits of stablyai/orca. Push the code to a branch of this repo instead." + exit 1 + ;; + esac + # Bare: a work-tree repo refuses to fetch over its own checked-out + # branch. tree:0 keeps the fetch to the commit graph — no trees, no + # blobs — so this stays cheap next to the build it fronts. + scratch="$RUNNER_TEMP/vet-requested-ref" + git init -q --bare "$scratch" + git -C "$scratch" fetch -q --filter=tree:0 "$REPO_URL" '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*' + # Branch first to keep actions/checkout's old tie-break: bare + # rev-parse would prefer the tag when a branch shares its name. + sha="" + for cand in "refs/heads/$REQUESTED_REF" "refs/tags/$REQUESTED_REF" "$REQUESTED_REF"; do + if sha="$(git -C "$scratch" rev-parse --verify --quiet "$cand^{commit}")"; then + break + fi + sha="" + done + if [[ -z "$sha" ]]; then + echo "::error::'$REQUESTED_REF' does not resolve to a branch, tag, or commit of stablyai/orca." + exit 1 + fi + # The object resolving locally is not proof a branch or tag reaches + # it: a partial clone can lazily fetch a bare SHA on demand, and + # GitHub serves PR-only commits by SHA. Reachability is the actual + # trust test. + if [[ -z "$(git -C "$scratch" for-each-ref --contains "$sha" refs/heads refs/tags | head -1)" ]]; then + echo "::error::Commit $REQUESTED_REF is not reachable from any branch or tag of stablyai/orca; refusing to build it with release credentials." + exit 1 + fi + echo "Vetted $REQUESTED_REF -> $sha" + echo "sha=$sha" >>"$GITHUB_OUTPUT" + - name: Checkout the requested ref uses: actions/checkout@v6 with: @@ -92,7 +158,7 @@ jobs: # build code that has not landed, and the workflow definition itself # always comes from the dispatch ref — naming the branch here instead # applies main's current copy of this file to an arbitrary branch. - ref: ${{ inputs.ref || github.ref_name }} + ref: ${{ steps.vetted.outputs.sha }} fetch-depth: 0 # This job only reads stablyai/orca and never pushes; every write goes # to the adhoc repo through a minted App token passed by env. Not @@ -146,17 +212,26 @@ jobs: env: REF: ${{ inputs.ref || github.ref_name }} LABEL: ${{ inputs.label }} + MAIN_REPO_TOKEN: ${{ github.token }} run: | set -euo pipefail - # Why this check: the version script is read from the branch being built, + # Why this check: the version scripts are read from the branch being built, # not from main, so a branch cut before the adhoc channel landed has no - # copy of it. Say that plainly instead of failing with a module-not-found. - if [[ ! -f config/scripts/adhoc-build-version.mjs ]]; then - echo "::error::$REF has no config/scripts/adhoc-build-version.mjs; rebase it onto a main that has the adhoc channel." - exit 1 - fi + # copy of them. Say that plainly instead of failing with a module-not-found. + for script in adhoc-build-version dev-channel-base-version; do + if [[ ! -f "config/scripts/$script.mjs" ]]; then + echo "::error::$REF has no config/scripts/$script.mjs; rebase it onto a main that has the adhoc channel." + exit 1 + fi + done echo "head_sha=$(git rev-parse HEAD)" >>"$GITHUB_OUTPUT" - ORCA_ADHOC_LABEL="${LABEL:-$REF}" node config/scripts/adhoc-build-version.mjs \ + # Why the main repo's tags: package.json on a branch is as stale as the + # main it forked from, and stable patches never merge back into it. + published="$(GH_TOKEN="$MAIN_REPO_TOKEN" gh release list \ + --repo "$GITHUB_REPOSITORY" --limit 100 --exclude-drafts \ + --json tagName --jq '.[].tagName' || true)" + ORCA_PUBLISHED_VERSIONS="$published" ORCA_ADHOC_LABEL="${LABEL:-$REF}" \ + node config/scripts/adhoc-build-version.mjs \ >"$RUNNER_TEMP/adhoc-identity.txt" if ! grep -q '^name=' "$RUNNER_TEMP/adhoc-identity.txt"; then echo "::error::adhoc-build-version.mjs emitted no release name; $REF's copy of the script is out of sync with this workflow." diff --git a/.github/workflows/hourly-mac-build.yml b/.github/workflows/hourly-mac-build.yml index ebe544436a6..bc3c5a8afff 100644 --- a/.github/workflows/hourly-mac-build.yml +++ b/.github/workflows/hourly-mac-build.yml @@ -179,6 +179,7 @@ jobs: shell: bash env: GH_TOKEN: ${{ steps.app_token.outputs.token }} + MAIN_REPO_TOKEN: ${{ github.token }} run: | set -euo pipefail # Why read the highest number off existing titles rather than counting @@ -195,7 +196,19 @@ jobs: --jq '[.[] | (.name // "") | capture(" • (?[0-9]+) • ")? | .n | tonumber] | max // 0')" build_number=$(( last_number + 1 )) echo "Hourly build number $build_number (previous high: $last_number)" - ORCA_HOURLY_BUILD_NUMBER="$build_number" node config/scripts/hourly-build-version.mjs \ + # Why the main repo's tags decide the base version rather than + # package.json: main's version only moves on `release:` commits, and + # stable patches are cut from release branches that never merge back, so + # package.json can sit several patches behind what users are running. A + # separate token because GH_TOKEN above is the App's, scoped to the + # hourly repo. Empty on failure — the script then falls back to + # package.json, which is stale but never wrong enough to fail a build. + published="$(GH_TOKEN="$MAIN_REPO_TOKEN" gh release list \ + --repo "$GITHUB_REPOSITORY" --limit 100 --exclude-drafts \ + --json tagName --jq '.[].tagName' || true)" + echo "Highest published tag seen: $(head -1 <<<"$published")" + ORCA_PUBLISHED_VERSIONS="$published" \ + ORCA_HOURLY_BUILD_NUMBER="$build_number" node config/scripts/hourly-build-version.mjs \ >"$RUNNER_TEMP/hourly-identity.txt" # Why check rather than trust: the checkout above pins `ref: main`, but a # workflow_dispatch runs this file from whatever branch was dispatched. A diff --git a/README.md b/README.md index cf4da325134..b161a52b71a 100644 --- a/README.md +++ b/README.md @@ -238,10 +238,9 @@ Pair with your desktop app to monitor and steer your agents from your phone. - **Discord:** Join the community on **[Discord](https://discord.gg/fzjDKHxv8Q)**. - **Twitter / X:** Follow **[@orca_build](https://x.com/orca_build)** for updates and announcements. -- **WeChat:** If group 5 is full, you can join group 6. +- **WeChat:** Scan to join the Orca community WeChat group 7. - WeChat group 5 QR code for the Orca community - WeChat group 6 QR code for the Orca community + WeChat group 7 QR code for the Orca community - **Feedback & Ideas:** We ship fast. Missing something? [Request a new feature](https://github.com/stablyai/orca/issues). - **Privacy:** See the [privacy & telemetry docs](https://www.onorca.dev/docs/telemetry) for what anonymous usage data Orca collects and how to opt out. diff --git a/config/packaged-runtime-node-modules.cjs b/config/packaged-runtime-node-modules.cjs index 8854f866f42..71ca780d1b8 100644 --- a/config/packaged-runtime-node-modules.cjs +++ b/config/packaged-runtime-node-modules.cjs @@ -44,6 +44,14 @@ const PARCEL_WATCHER_PLATFORM_PREFIX_BY_PLATFORM = { linux: 'watcher-linux', win32: 'watcher-win32' } +const ELECTRON_ARCHITECTURE_BY_ENUM = { + 0: 'ia32', + 1: 'x64', + 2: 'arm', + 3: 'arm64', + 4: 'universal' +} +const PACKAGED_NATIVE_ARCHITECTURES = new Set(['ia32', 'x64', 'arm', 'arm64']) const TYPE_DECLARATION_ARTIFACT_RE = /\.d\.(?:c|m)?ts(?:\.map)?$/ const VERSIONED_ONNXRUNTIME_DYLIB_RE = /^libonnxruntime\.\d[\d.]*\.dylib$/ @@ -170,7 +178,7 @@ function collectPackagedRuntimePackages(electronPlatformName = process.platform) // optionalDependency (e.g. @parcel/watcher-linux-x64-glibc) that the // dependencies graph above never reaches. Include the ones installed for the // build's supported architectures; afterPack pruning trims non-target - // platforms. Without this the packaged main bundle's import of + // platform/architecture variants. Without this the packaged main bundle's import of // '@parcel/watcher' resolves at runtime but throws loading its binary. const parcelWatcherDir = packages.get('@parcel/watcher') if (parcelWatcherDir) { @@ -246,13 +254,44 @@ function verifyPackagedMainRuntimeDeps(resourcesDir, asar = require('@electron/a } function normalizeNodePtyWindowsArch(electronArch) { - if (electronArch === 'x64' || electronArch === 1) { - return 'x64' + const architecture = normalizeElectronArchitecture(electronArch) + if (architecture !== 'x64' && architecture !== 'arm64') { + throw new Error(`Unsupported packaged node-pty Windows architecture: ${architecture}`) } - if (electronArch === 'arm64' || electronArch === 3) { - return 'arm64' + return architecture +} + +function normalizeElectronArchitecture(electronArch) { + const architecture = + typeof electronArch === 'number' + ? ELECTRON_ARCHITECTURE_BY_ENUM[electronArch] + : electronArch === 'armv7l' + ? 'arm' + : electronArch + if (!PACKAGED_NATIVE_ARCHITECTURES.has(architecture)) { + throw new Error(`Unsupported packaged runtime architecture: ${String(electronArch)}`) + } + return architecture +} + +function pruneNodePtyNativeDirectories(directory, platformPrefix, electronArch, allowsSuffix) { + if (!existsSync(directory)) { + return + } + const architecture = normalizeElectronArchitecture(electronArch) + const targetPrefix = `${platformPrefix}${architecture}` + const platformPrefixes = Object.values(NODE_PTY_PREBUILD_PREFIX_BY_PLATFORM) + for (const entry of readdirSync(directory, { withFileTypes: true })) { + if (!entry.isDirectory() || !platformPrefixes.some((prefix) => entry.name.startsWith(prefix))) { + continue + } + const matchesTarget = + entry.name.startsWith(platformPrefix) && + (entry.name === targetPrefix || (allowsSuffix && entry.name.startsWith(`${targetPrefix}-`))) + if (!matchesTarget) { + rmSync(join(directory, entry.name), { recursive: true, force: true }) + } } - return process.arch === 'arm64' ? 'arm64' : 'x64' } function findNodePtyConptySourceDir(nodePtyDir, windowsArch) { @@ -308,14 +347,19 @@ function prunePackagedNodePty(resourcesDir, electronPlatformName, electronArch) const allowedPrebuildPrefix = NODE_PTY_PREBUILD_PREFIX_BY_PLATFORM[electronPlatformName] if (allowedPrebuildPrefix) { - const prebuildsDir = join(nodePtyDir, 'prebuilds') - if (existsSync(prebuildsDir)) { - for (const entry of readdirSync(prebuildsDir, { withFileTypes: true })) { - if (entry.isDirectory() && !entry.name.startsWith(allowedPrebuildPrefix)) { - rmSync(join(prebuildsDir, entry.name), { recursive: true, force: true }) - } - } - } + pruneNodePtyNativeDirectories( + join(nodePtyDir, 'prebuilds'), + allowedPrebuildPrefix, + electronArch, + false + ) + // Why: sequential cross-arch rebuilds accumulate ABI-tagged outputs here. + pruneNodePtyNativeDirectories( + join(nodePtyDir, 'bin'), + allowedPrebuildPrefix, + electronArch, + true + ) } if (electronPlatformName === 'win32') { @@ -328,7 +372,7 @@ function prunePackagedNodePty(resourcesDir, electronPlatformName, electronArch) } } -function prunePackagedParcelWatcher(resourcesDir, electronPlatformName) { +function prunePackagedParcelWatcher(resourcesDir, electronPlatformName, electronArch) { const parcelDir = join(resourcesDir, 'node_modules', '@parcel') if (!existsSync(parcelDir)) { return @@ -336,9 +380,11 @@ function prunePackagedParcelWatcher(resourcesDir, electronPlatformName) { // Why: we package every installed @parcel/watcher- optional // subpackage (supportedArchitectures fetches all), but each build only needs - // its own platform's binary. Keep the core package and the matching platform - // subpackages; drop the rest so a Linux serve doesn't ship macOS/Windows .node. + // its own platform/architecture binaries. Keep the core package and matching + // native variants; drop the rest. const keepPrefix = PARCEL_WATCHER_PLATFORM_PREFIX_BY_PLATFORM[electronPlatformName] + const architecture = normalizeElectronArchitecture(electronArch) + const targetPrefix = keepPrefix ? `${keepPrefix}-${architecture}` : null for (const entry of readdirSync(parcelDir, { withFileTypes: true })) { if (!entry.isDirectory() || entry.name === 'watcher') { continue @@ -348,7 +394,11 @@ function prunePackagedParcelWatcher(resourcesDir, electronPlatformName) { if (!entry.name.startsWith('watcher-')) { continue } - if (keepPrefix && entry.name.startsWith(keepPrefix)) { + if ( + keepPrefix && + entry.name.startsWith(keepPrefix) && + (entry.name === targetPrefix || entry.name.startsWith(`${targetPrefix}-`)) + ) { continue } rmSync(join(parcelDir, entry.name), { recursive: true, force: true }) @@ -395,8 +445,9 @@ function prunePackagedZodSources(resourcesDir) { } function prunePackagedRuntimeNodeModules(resourcesDir, electronPlatformName, electronArch) { - prunePackagedNodePty(resourcesDir, electronPlatformName, electronArch) - prunePackagedParcelWatcher(resourcesDir, electronPlatformName) + const architecture = normalizeElectronArchitecture(electronArch) + prunePackagedNodePty(resourcesDir, electronPlatformName, architecture) + prunePackagedParcelWatcher(resourcesDir, electronPlatformName, architecture) prunePackagedRuntimeTypeDeclarations(resourcesDir) prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) prunePackagedZodSources(resourcesDir) diff --git a/config/patches/@xterm__addon-serialize@0.15.0-beta.287.patch b/config/patches/@xterm__addon-serialize@0.15.0-beta.287.patch index eab0cd58452..caa96484d89 100644 --- a/config/patches/@xterm__addon-serialize@0.15.0-beta.287.patch +++ b/config/patches/@xterm__addon-serialize@0.15.0-beta.287.patch @@ -1,28 +1,64 @@ diff --git a/lib/addon-serialize.js b/lib/addon-serialize.js -index d669293d06d801ef472d5c2454ce86876e5c321f..96bb66cdc05289b6a7ce5ed64fc833624c885c57 100644 +index d669293d06d801ef472d5c2454ce86876e5c321f..18f72336a60d498f685e2cc32b7a09dbe16958e5 100644 --- a/lib/addon-serialize.js +++ b/lib/addon-serialize.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=f;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function f(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,f=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,f=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(f(i,n)>8));if(of(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=f(i,u.relativeLuminance(o>>8));if(af(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t,e,r){return Math.max(e,Math.min(t,r))}class n{constructor(t){this._buffer=t}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,o=t.end.y,l=t.start.x,a=t.end.x;this._beforeSerialize(o-n,n,o);for(let e=n;e<=o;e++){const n=this._buffer.getLine(e);if(n){const o=e===t.start.y?l:0,u=e===t.end.y?a:n.length;for(let t=o;t0&&!l(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=e.getCell(e.length-1,this._thisRowLastChar),n=e.getCell(e.length-2,this._thisRowLastSecondChar),o=s.getCell(0,this._nextRowFirstChar),a=o.getWidth()>1;let u=!1;(o.getChars()&&a?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||0===i.getWidth())&&l(i,o)&&(u=!0),a&&(n.getChars()||0===n.getWidth())&&l(i,o)&&l(n,o)&&(u=!0)),u||(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0&&(r+="",r+=`[${e.length-this._nullCellCount}C`,r+=`[${this._nullCellCount}X`,r+=`[${e.length-this._nullCellCount}D`,r+=""),this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0)}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(h(t,e))return r;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){if(t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27),t.isBold()!==e.isBold()&&r.push(t.isBold()?1:22),a(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isDim()!==e.isDim()&&r.push(t.isDim()?2:22),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,this._cursorStyle);if(i?!l(this._cursorStyle,t):n.length>0){this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${n.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}i?this._nullCellCount+=t.getWidth():(this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._currentRow+=t.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth())}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(e=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let t=0;t{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,n=void 0===r?s:i(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-n,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new c(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new f(r,t,e),n=e.onlySelection??!1,o=e.range;if(o)return s.serialize({start:{x:o.startCol,y:(o.startLine,o.startLine)},end:{x:t.cols,y:(o.endLine,o.endLine)}});if(!n){const n=r.length,o=e.scrollback,l=void 0===o?n:i(o+t.rows,0,n);return s.serialize({start:{x:0,y:n-l},end:{x:t.cols,y:n-1}})}const l=this._terminal?.getSelectionPosition();return void 0!==l?s.serialize({start:{x:l.start.x,y:l.start.y},end:{x:l.end.x,y:l.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class f extends n{constructor(t,r,s){super(t),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(h(t,e))return;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=f})(),s})()); -+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=f;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function f(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,f=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,f=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(f(i,n)>8));if(of(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=f(i,u.relativeLuminance(o>>8));if(af(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t,e,r){return Math.max(e,Math.min(t,r))}class n{constructor(t){this._buffer=t}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,o=t.end.y,l=t.start.x,a=t.end.x;this._beforeSerialize(o-n,n,o);for(let e=n;e<=o;e++){const n=this._buffer.getLine(e);if(n){const o=e===t.start.y?l:0,u=e===t.end.y?a:n.length;for(let t=o;t0&&!l(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=e.getCell(e.length-1,this._thisRowLastChar),n=e.getCell(e.length-2,this._thisRowLastSecondChar),o=s.getCell(0,this._nextRowFirstChar),a=o.getWidth()>1;let u=!1;(o.getChars()&&a?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||0===i.getWidth())&&l(i,o)&&(u=!0),a&&(n.getChars()||0===n.getWidth())&&l(i,o)&&l(n,o)&&(u=!0)),u||(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0&&(r+="",r+=`[${e.length-this._nullCellCount}C`,r+=`[${this._nullCellCount}X`,r+=`[${e.length-this._nullCellCount}D`,r+=""),this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0)}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(h(t,e))return r;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){if(t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27),/* PATCH(orca): bold(1)/dim(2) share reset 22 - clear before re-set, as one group */((b,d)=>{if(b||d){const c=b&&!t.isBold()||d&&!t.isDim();c&&r.push(22),t.isBold()&&(b||c)&&r.push(1),t.isDim()&&(d||c)&&r.push(2)}})(t.isBold()!==e.isBold(),t.isDim()!==e.isDim()),a(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,this._cursorStyle);if(i?!l(this._cursorStyle,t):n.length>0){this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${n.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}i?this._nullCellCount+=t.getWidth():(this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._currentRow+=t.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth())}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(e=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let t=0;t{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,n=void 0===r?s:i(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-n,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new c(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new f(r,t,e),n=e.onlySelection??!1,o=e.range;if(o)return s.serialize({start:{x:o.startCol,y:(o.startLine,o.startLine)},end:{x:t.cols,y:(o.endLine,o.endLine)}});if(!n){const n=r.length,o=e.scrollback,l=void 0===o?n:i(o+t.rows,0,n);return s.serialize({start:{x:0,y:n-l},end:{x:t.cols,y:n-1}})}const l=this._terminal?.getSelectionPosition();return void 0!==l?s.serialize({start:{x:l.start.x,y:l.start.y},end:{x:l.end.x,y:l.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class f extends n{constructor(t,r,s){super(t),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(h(t,e))return;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"
":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=f})(),s})()); ++!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=f;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function f(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,f=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,f=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(f(i,n)>8));if(of(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=f(i,u.relativeLuminance(o>>8));if(af(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t,e,r){return Math.max(e,Math.min(t,r))}class n{constructor(t){this._buffer=t}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,o=t.end.y,l=t.start.x,a=t.end.x;this._beforeSerialize(o-n,n,o);for(let e=n;e<=o;e++){const n=this._buffer.getLine(e);if(n){const o=e===t.start.y?l:0,u=e===t.end.y?a:n.length;for(let t=o;t0&&!l(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=e.getCell(e.length-1,this._thisRowLastChar),n=e.getCell(e.length-2,this._thisRowLastSecondChar),o=s.getCell(0,this._nextRowFirstChar),a=o.getWidth()>1;let u=!1;(o.getChars()&&(a?this._nullCellCount<=1:this._nullCellCount<=0))&&((i.getChars()||0===i.getWidth())&&l(i,o)&&(u=!0),a&&(n.getChars()||0===n.getWidth())&&l(i,o)&&l(n,o)&&(u=!0)),u||(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0&&(r+="",e.length-this._nullCellCount>0&&(r+=`[${e.length-this._nullCellCount}C`),r+=`[${this._nullCellCount}X`,e.length-this._nullCellCount>0&&(r+=`[${e.length-this._nullCellCount}D`),r+=""),this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0)}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(h(t,e))return r;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){if(t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27),/* PATCH(orca): bold(1)/dim(2) share reset 22 - clear before re-set, as one group */((b,d)=>{if(b||d){const c=b&&!t.isBold()||d&&!t.isDim();c&&r.push(22),t.isBold()&&(b||c)&&r.push(1),t.isDim()&&(d||c)&&r.push(2)}})(t.isBold()!==e.isBold(),t.isDim()!==e.isDim()),a(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),c=i&&t.isInverse()?this._buffer.getLine(r+1):void 0,p=c?.getCell(0,this._nextRowFirstChar),f=s===this._terminal.cols-1&&c?.isWrapped&&(p?.getWidth()??0)>1&&!!p&&h(t,p),a=i&&!!t.isInverse()&&!f,d=a&&(!!t.isUnderline()||!!t.isStrikethrough()||!!t.isOverline()),n=this._diffStyle(t,this._cursorStyle);if(i?a?n.length>0:!l(this._cursorStyle,t):n.length>0){this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${n.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}i&&!a?this._nullCellCount+=t.getWidth():(this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),(a?(d&&(this._currentRow+="\x1B[24;29;55m"),this._currentRow+=" ".repeat(t.getWidth()),d&&(this._currentRow+=`\x1B[0m\x1B[${this._diffStyle(t,this._defaultCell).join(";")}m`)):this._currentRow+=t.getChars()),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth())}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(e=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let t=0;t{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,n=void 0===r?s:i(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-n,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new c(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new f(r,t,e),n=e.onlySelection??!1,o=e.range;if(o)return s.serialize({start:{x:o.startCol,y:(o.startLine,o.startLine)},end:{x:t.cols,y:(o.endLine,o.endLine)}});if(!n){const n=r.length,o=e.scrollback,l=void 0===o?n:i(o+t.rows,0,n);return s.serialize({start:{x:0,y:n-l},end:{x:t.cols,y:n-1}})}const l=this._terminal?.getSelectionPosition();return void 0!==l?s.serialize({start:{x:l.start.x,y:l.start.y},end:{x:l.end.x,y:l.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class f extends n{constructor(t,r,s){super(t),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(h(t,e))return;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"
":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=f})(),s})()); //# sourceMappingURL=addon-serialize.js.map \ No newline at end of file diff --git a/lib/addon-serialize.mjs b/lib/addon-serialize.mjs -index a5c4c4dd05b7efcc23d0e45661ffd4e42da80f21..475e45b3ed228027531deea5530bd03859f4a4e0 100644 +index a5c4c4dd05b7efcc23d0e45661ffd4e42da80f21..bb46224439629de3845c0b56ab9e4cd397dfe098 100644 --- a/lib/addon-serialize.mjs +++ b/lib/addon-serialize.mjs -@@ -15,5 +15,5 @@ +@@ -14,6 +14,6 @@ + * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - var m=0,b=0,_=0,p=0;var g;(t=>{function a(r,l,s,i){return i!==void 0?`#${w(r)}${w(l)}${w(s)}${w(i)}`:`#${w(r)}${w(l)}${w(s)}`}t.toCss=a;function n(r,l,s,i=255){return(r<<24|l<<16|s<<8|i)>>>0}t.toRgba=n;function e(r,l,s,i){return{css:t.toCss(r,l,s,i),rgba:t.toRgba(r,l,s,i)}}t.toColor=e})(g||={});var N;(i=>{function a(o,u){if(p=(u.rgba&255)/255,p===1)return{css:u.css,rgba:u.rgba};let f=u.rgba>>24&255,C=u.rgba>>16&255,c=u.rgba>>8&255,h=o.rgba>>24&255,d=o.rgba>>16&255,I=o.rgba>>8&255;m=h+Math.round((f-h)*p),b=d+Math.round((C-d)*p),_=I+Math.round((c-I)*p);let L=g.toCss(m,b,_),E=g.toRgba(m,b,_);return{css:L,rgba:E}}i.blend=a;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,u,f){let C=B.ensureContrastRatio(o.rgba,u.rgba,f);if(C)return g.toColor(C>>24&255,C>>16&255,C>>8&255)}i.ensureContrastRatio=e;function t(o){let u=(o.rgba|255)>>>0;return[m,b,_]=B.toChannels(u),{css:g.toCss(m,b,_),rgba:u}}i.opaque=t;function r(o,u){return p=Math.round(u*255),[m,b,_]=B.toChannels(o.rgba),{css:g.toCss(m,b,_,p),rgba:g.toRgba(m,b,_,p)}}i.opacity=r;function l(o,u){return p=o.rgba&255,r(o,p*u/255)}i.multiplyOpacity=l;function s(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=s})(N||={});var x;(t=>{let a,n;try{let r=document.createElement("canvas");r.width=1,r.height=1;let l=r.getContext("2d",{willReadFrequently:!0});l&&(a=l,a.globalCompositeOperation="copy",n=a.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),g.toColor(m,b,_);case 5:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),p=parseInt(r.slice(4,5).repeat(2),16),g.toColor(m,b,_,p);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let l=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(l)return m=parseInt(l[1],10),b=parseInt(l[2],10),_=parseInt(l[3],10),p=Math.round((l[5]===void 0?1:parseFloat(l[5]))*255),g.toColor(m,b,_,p);if(r==="transparent")return{css:"transparent",rgba:0};if(!a||!n)throw new Error("css.toColor: Unsupported css format");if(a.fillStyle=n,a.fillStyle=r,typeof a.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(a.fillRect(0,0,1,1),[m,b,_,p]=a.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(m,b,_,p),css:r}}t.toColor=e})(x||={});var v;(e=>{function a(t){return n(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=a;function n(t,r,l){let s=t/255,i=r/255,o=l/255,u=s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),C=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return u*.2126+f*.7152+C*.0722}e.relativeLuminance2=n})(v||={});var B;(l=>{function a(s,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,u=i>>16&255,f=i>>8&255,C=s>>24&255,c=s>>16&255,h=s>>8&255;return m=C+Math.round((o-C)*p),b=c+Math.round((u-c)*p),_=h+Math.round((f-h)*p),g.toRgba(m,b,_)}l.blend=a;function n(s,i,o){let u=v.relativeLuminance(s>>8),f=v.relativeLuminance(i>>8);if(R(u,f)>8));if(I>8));return I>E?d:L}return d}let c=t(s,i,o),h=R(u,v.relativeLuminance(c>>8));if(h>8));return h>I?c:d}return c}}l.ensureContrastRatio=n;function e(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I0||h>0||d>0);)c-=Math.max(0,Math.ceil(c*.1)),h-=Math.max(0,Math.ceil(h*.1)),d-=Math.max(0,Math.ceil(d*.1)),I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));return(c<<24|h<<16|d<<8|255)>>>0}l.reduceLuminance=e;function t(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I>>0}l.increaseLuminance=t;function r(s){return[s>>24&255,s>>16&255,s>>8&255,s&255]}l.toChannels=r})(B||={});function w(a){let n=a.toString(16);return n.length<2?"0"+n:n}function R(a,n){return a{let a=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let t=n[e/36%6|0],r=n[e/6%6|0],l=n[e%6];a.push({css:g.toCss(t,r,l),rgba:g.toRgba(t,r,l)})}for(let e=0;e<24;e++){let t=8+e*10;a.push({css:g.toCss(t,t,t),rgba:g.toRgba(t,t,t)})}return a})());function A(a,n,e){return Math.max(n,Math.min(a,e))}function z(a){switch(a){case"&":return"&";case"<":return"<"}return a}var S=class{constructor(n){this._buffer=n}serialize(n,e){let t=this._buffer.getNullCell(),r=this._buffer.getNullCell(),l=t,s=n.start.y,i=n.end.y,o=n.start.x,u=n.end.x;this._beforeSerialize(i-s,s,i);for(let f=s;f<=i;f++){let C=this._buffer.getLine(f);if(C){let c=f===n.start.y?o:0,h=f===n.end.y?u:C.length;for(let d=c;d0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`);let r="";if(!t){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let l=this._buffer.getLine(e),s=this._buffer.getLine(e+1);if(!s.isWrapped)r=`\r +-var m=0,b=0,_=0,p=0;var g;(t=>{function a(r,l,s,i){return i!==void 0?`#${w(r)}${w(l)}${w(s)}${w(i)}`:`#${w(r)}${w(l)}${w(s)}`}t.toCss=a;function n(r,l,s,i=255){return(r<<24|l<<16|s<<8|i)>>>0}t.toRgba=n;function e(r,l,s,i){return{css:t.toCss(r,l,s,i),rgba:t.toRgba(r,l,s,i)}}t.toColor=e})(g||={});var N;(i=>{function a(o,u){if(p=(u.rgba&255)/255,p===1)return{css:u.css,rgba:u.rgba};let f=u.rgba>>24&255,C=u.rgba>>16&255,c=u.rgba>>8&255,h=o.rgba>>24&255,d=o.rgba>>16&255,I=o.rgba>>8&255;m=h+Math.round((f-h)*p),b=d+Math.round((C-d)*p),_=I+Math.round((c-I)*p);let L=g.toCss(m,b,_),E=g.toRgba(m,b,_);return{css:L,rgba:E}}i.blend=a;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,u,f){let C=B.ensureContrastRatio(o.rgba,u.rgba,f);if(C)return g.toColor(C>>24&255,C>>16&255,C>>8&255)}i.ensureContrastRatio=e;function t(o){let u=(o.rgba|255)>>>0;return[m,b,_]=B.toChannels(u),{css:g.toCss(m,b,_),rgba:u}}i.opaque=t;function r(o,u){return p=Math.round(u*255),[m,b,_]=B.toChannels(o.rgba),{css:g.toCss(m,b,_,p),rgba:g.toRgba(m,b,_,p)}}i.opacity=r;function l(o,u){return p=o.rgba&255,r(o,p*u/255)}i.multiplyOpacity=l;function s(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=s})(N||={});var x;(t=>{let a,n;try{let r=document.createElement("canvas");r.width=1,r.height=1;let l=r.getContext("2d",{willReadFrequently:!0});l&&(a=l,a.globalCompositeOperation="copy",n=a.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),g.toColor(m,b,_);case 5:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),p=parseInt(r.slice(4,5).repeat(2),16),g.toColor(m,b,_,p);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let l=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(l)return m=parseInt(l[1],10),b=parseInt(l[2],10),_=parseInt(l[3],10),p=Math.round((l[5]===void 0?1:parseFloat(l[5]))*255),g.toColor(m,b,_,p);if(r==="transparent")return{css:"transparent",rgba:0};if(!a||!n)throw new Error("css.toColor: Unsupported css format");if(a.fillStyle=n,a.fillStyle=r,typeof a.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(a.fillRect(0,0,1,1),[m,b,_,p]=a.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(m,b,_,p),css:r}}t.toColor=e})(x||={});var v;(e=>{function a(t){return n(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=a;function n(t,r,l){let s=t/255,i=r/255,o=l/255,u=s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),C=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return u*.2126+f*.7152+C*.0722}e.relativeLuminance2=n})(v||={});var B;(l=>{function a(s,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,u=i>>16&255,f=i>>8&255,C=s>>24&255,c=s>>16&255,h=s>>8&255;return m=C+Math.round((o-C)*p),b=c+Math.round((u-c)*p),_=h+Math.round((f-h)*p),g.toRgba(m,b,_)}l.blend=a;function n(s,i,o){let u=v.relativeLuminance(s>>8),f=v.relativeLuminance(i>>8);if(R(u,f)>8));if(I>8));return I>E?d:L}return d}let c=t(s,i,o),h=R(u,v.relativeLuminance(c>>8));if(h>8));return h>I?c:d}return c}}l.ensureContrastRatio=n;function e(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I0||h>0||d>0);)c-=Math.max(0,Math.ceil(c*.1)),h-=Math.max(0,Math.ceil(h*.1)),d-=Math.max(0,Math.ceil(d*.1)),I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));return(c<<24|h<<16|d<<8|255)>>>0}l.reduceLuminance=e;function t(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I>>0}l.increaseLuminance=t;function r(s){return[s>>24&255,s>>16&255,s>>8&255,s&255]}l.toChannels=r})(B||={});function w(a){let n=a.toString(16);return n.length<2?"0"+n:n}function R(a,n){return a{let a=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let t=n[e/36%6|0],r=n[e/6%6|0],l=n[e%6];a.push({css:g.toCss(t,r,l),rgba:g.toRgba(t,r,l)})}for(let e=0;e<24;e++){let t=8+e*10;a.push({css:g.toCss(t,t,t),rgba:g.toRgba(t,t,t)})}return a})());function A(a,n,e){return Math.max(n,Math.min(a,e))}function z(a){switch(a){case"&":return"&";case"<":return"<"}return a}var S=class{constructor(n){this._buffer=n}serialize(n,e){let t=this._buffer.getNullCell(),r=this._buffer.getNullCell(),l=t,s=n.start.y,i=n.end.y,o=n.start.x,u=n.end.x;this._beforeSerialize(i-s,s,i);for(let f=s;f<=i;f++){let C=this._buffer.getLine(f);if(C){let c=f===n.start.y?o:0,h=f===n.end.y?u:C.length;for(let d=c;d0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`);let r="";if(!t){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let l=this._buffer.getLine(e),s=this._buffer.getLine(e+1);if(!s.isWrapped)r=`\r -`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{r="";let i=l.getCell(l.length-1,this._thisRowLastChar),o=l.getCell(l.length-2,this._thisRowLastSecondChar),u=s.getCell(0,this._nextRowFirstChar),f=u.getWidth()>1,C=!1;(u.getChars()&&f?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||i.getWidth()===0)&&F(i,u)&&(C=!0),f&&(o.getChars()||o.getWidth()===0)&&F(i,u)&&F(o,u)&&(C=!0)),C||(r="-".repeat(this._nullCellCount+1),r+="\x1B[1D\x1B[1X",this._nullCellCount>0&&(r+="\x1B[A",r+=`\x1B[${l.length-this._nullCellCount}C`,r+=`\x1B[${this._nullCellCount}X`,r+=`\x1B[${l.length-this._nullCellCount}D`,r+="\x1B[B"),this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0)}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(e,t){let r=[];if(U(e,t))return r;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i)if(e.isAttributeDefault())t.isAttributeDefault()||r.push(0);else{if(l){let o=e.getFgColor();e.isFgRGB()?r.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?r.push(38,5,o):r.push(o&8?90+(o&7):30+(o&7)):r.push(39)}if(s){let o=e.getBgColor();e.isBgRGB()?r.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?r.push(48,5,o):r.push(o&8?100+(o&7):40+(o&7)):r.push(49)}if(i){if(e.isInverse()!==t.isInverse()&&r.push(e.isInverse()?7:27),e.isBold()!==t.isBold()&&r.push(e.isBold()?1:22),O(e,t))e.isUnderline()!==t.isUnderline()&&r.push(e.isUnderline()?4:24);else{let o=e.getUnderlineStyle();if(o===0)r.push(24);else if(o===1&&e.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+o),!e.isUnderlineColorDefault()){let u=e.getUnderlineColor();e.isUnderlineColorRGB()?r.push("58:2::"+(u>>>16&255)+":"+(u>>>8&255)+":"+(u&255)):r.push("58:5:"+u)}}e.isOverline()!==t.isOverline()&&r.push(e.isOverline()?53:55),e.isBlink()!==t.isBlink()&&r.push(e.isBlink()?5:25),e.isInvisible()!==t.isInvisible()&&r.push(e.isInvisible()?8:28),e.isItalic()!==t.isItalic()&&r.push(e.isItalic()?3:23),e.isDim()!==t.isDim()&&r.push(e.isDim()?2:22),e.isStrikethrough()!==t.isStrikethrough()&&r.push(e.isStrikethrough()?9:29)}}return r}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,this._cursorStyle);if(i?!F(this._cursorStyle,e):o.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l,this._currentRow+=`\x1B[${o.join(";")}m`;let f=this._buffer.getLine(r);f!==void 0&&(f.getCell(l,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=l)}i?this._nullCellCount+=e.getWidth():(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),this._currentRow+=e.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l+e.getWidth())}_serializeString(e){let t=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(t=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let i=0;i{c>0?r+=`\x1B[${c}C`:c<0&&(r+=`\x1B[${-c}D`)};u&&((c=>{c>0?r+=`\x1B[${c}B`:c<0&&(r+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let l=this._terminal._core._inputHandler._curAttrData,s=this._diffStyle(l,this._cursorStyle);return s.length>0&&(r+=`\x1B[${s.join(";")}m`),r}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,t){let r=e.length,l=t===void 0?r:A(t+n.rows,0,r);return this._serializeBufferByRange(n,e,{start:r-l,end:r-1},!1)}_serializeBufferByRange(n,e,t,r){return new y(e,n).serialize({start:{x:0,y:typeof t.start=="number"?t.start:t.start.line},end:{x:n.cols,y:typeof t.end=="number"?t.end:t.end.line}},r)}_serializeBufferAsHTML(n,e){let t=n.buffer.active,r=new D(t,n,e),l=e.onlySelection??!1,s=e.range;if(s)return r.serialize({start:{x:s.startCol,y:(typeof s.startLine=="number",s.startLine)},end:{x:n.cols,y:(typeof s.endLine=="number",s.endLine)}});if(!l){let o=t.length,u=e.scrollback,f=u===void 0?o:A(u+n.rows,0,o);return r.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?r.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,t=e.scrollTop,r=e.scrollBottom;return t!==0||r!==n.rows-1?`\x1B[${t+1};${r+1}r`:""}_serializeModes(n){let e="",t=n.modes;if(t.applicationCursorKeysMode&&(e+="\x1B[?1h"),t.applicationKeypadMode&&(e+="\x1B[?66h"),t.bracketedPasteMode&&(e+="\x1B[?2004h"),t.insertMode&&(e+="\x1B[4h"),t.originMode&&(e+="\x1B[?6h"),t.reverseWraparoundMode&&(e+="\x1B[?45h"),t.sendFocusMode&&(e+="\x1B[?1004h"),t.wraparoundMode===!1&&(e+="\x1B[?7l"),t.mouseTrackingMode!=="none")switch(t.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return t.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let t=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${t}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},D=class extends S{constructor(e,t,r){super(e);this._terminal=t;this._options=r;this._currentRow="";this._htmlContent="";t._core._themeService?this._ansiColors=t._core._themeService.colors.ansi:this._ansiColors=k}_beforeSerialize(e,t,r){this._htmlContent+="
";let l="#000000",s="#ffffff";(this._options.includeGlobalBackground??!1)&&(l=this._terminal.options.theme?.foreground??"#ffffff",s=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+l+";"),i.push("background-color: "+s+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,t){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,t){let r=t?e.getFgColor():e.getBgColor();if(t?e.isFgRGB():e.isBgRGB())return"#"+[r>>16&255,r>>8&255,r&255].map(s=>s.toString(16).padStart(2,"0")).join("");if(t?e.isFgPalette():e.isBgPalette())return this._ansiColors[r].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let t=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[t>>16&255,t>>8&255,t&255].map(l=>l.toString(16).padStart(2,"0")).join(""):this._ansiColors[t].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,t){let r=[];if(U(e,t))return;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i){let o=this._getHexColor(e,!0);o&&r.push("color: "+o+";");let u=this._getHexColor(e,!1);u&&r.push("background-color: "+u+";"),e.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&r.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&r.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let C=this._getUnderlineColor(e);C&&r.push("text-decoration-color: "+C+";")}return e.isInvisible()&&r.push("visibility: hidden;"),e.isItalic()&&r.push("font-style: italic;"),e.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,t);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=z(e.getChars())}_serializeString(){return this._htmlContent}};export{D as HTMLSerializeHandler,H as SerializeAddon}; -+`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{r="";let i=l.getCell(l.length-1,this._thisRowLastChar),o=l.getCell(l.length-2,this._thisRowLastSecondChar),u=s.getCell(0,this._nextRowFirstChar),f=u.getWidth()>1,C=!1;(u.getChars()&&f?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||i.getWidth()===0)&&F(i,u)&&(C=!0),f&&(o.getChars()||o.getWidth()===0)&&F(i,u)&&F(o,u)&&(C=!0)),C||(r="-".repeat(this._nullCellCount+1),r+="\x1B[1D\x1B[1X",this._nullCellCount>0&&(r+="\x1B[A",r+=`\x1B[${l.length-this._nullCellCount}C`,r+=`\x1B[${this._nullCellCount}X`,r+=`\x1B[${l.length-this._nullCellCount}D`,r+="\x1B[B"),this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0)}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(e,t){let r=[];if(U(e,t))return r;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i)if(e.isAttributeDefault())t.isAttributeDefault()||r.push(0);else{if(l){let o=e.getFgColor();e.isFgRGB()?r.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?r.push(38,5,o):r.push(o&8?90+(o&7):30+(o&7)):r.push(39)}if(s){let o=e.getBgColor();e.isBgRGB()?r.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?r.push(48,5,o):r.push(o&8?100+(o&7):40+(o&7)):r.push(49)}if(i){if(e.isInverse()!==t.isInverse()&&r.push(e.isInverse()?7:27),/* PATCH(orca): bold(1)/dim(2) share reset 22 - clear before re-set, as one group */((b,d)=>{if(b||d){const c=b&&!e.isBold()||d&&!e.isDim();c&&r.push(22),e.isBold()&&(b||c)&&r.push(1),e.isDim()&&(d||c)&&r.push(2)}})(e.isBold()!==t.isBold(),e.isDim()!==t.isDim()),O(e,t))e.isUnderline()!==t.isUnderline()&&r.push(e.isUnderline()?4:24);else{let o=e.getUnderlineStyle();if(o===0)r.push(24);else if(o===1&&e.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+o),!e.isUnderlineColorDefault()){let u=e.getUnderlineColor();e.isUnderlineColorRGB()?r.push("58:2::"+(u>>>16&255)+":"+(u>>>8&255)+":"+(u&255)):r.push("58:5:"+u)}}e.isOverline()!==t.isOverline()&&r.push(e.isOverline()?53:55),e.isBlink()!==t.isBlink()&&r.push(e.isBlink()?5:25),e.isInvisible()!==t.isInvisible()&&r.push(e.isInvisible()?8:28),e.isItalic()!==t.isItalic()&&r.push(e.isItalic()?3:23),e.isStrikethrough()!==t.isStrikethrough()&&r.push(e.isStrikethrough()?9:29)}}return r}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,this._cursorStyle);if(i?!F(this._cursorStyle,e):o.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l,this._currentRow+=`\x1B[${o.join(";")}m`;let f=this._buffer.getLine(r);f!==void 0&&(f.getCell(l,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=l)}i?this._nullCellCount+=e.getWidth():(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),this._currentRow+=e.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l+e.getWidth())}_serializeString(e){let t=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(t=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let i=0;i{c>0?r+=`\x1B[${c}C`:c<0&&(r+=`\x1B[${-c}D`)};u&&((c=>{c>0?r+=`\x1B[${c}B`:c<0&&(r+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let l=this._terminal._core._inputHandler._curAttrData,s=this._diffStyle(l,this._cursorStyle);return s.length>0&&(r+=`\x1B[${s.join(";")}m`),r}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,t){let r=e.length,l=t===void 0?r:A(t+n.rows,0,r);return this._serializeBufferByRange(n,e,{start:r-l,end:r-1},!1)}_serializeBufferByRange(n,e,t,r){return new y(e,n).serialize({start:{x:0,y:typeof t.start=="number"?t.start:t.start.line},end:{x:n.cols,y:typeof t.end=="number"?t.end:t.end.line}},r)}_serializeBufferAsHTML(n,e){let t=n.buffer.active,r=new D(t,n,e),l=e.onlySelection??!1,s=e.range;if(s)return r.serialize({start:{x:s.startCol,y:(typeof s.startLine=="number",s.startLine)},end:{x:n.cols,y:(typeof s.endLine=="number",s.endLine)}});if(!l){let o=t.length,u=e.scrollback,f=u===void 0?o:A(u+n.rows,0,o);return r.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?r.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,t=e.scrollTop,r=e.scrollBottom;return t!==0||r!==n.rows-1?`\x1B[${t+1};${r+1}r`:""}_serializeModes(n){let e="",t=n.modes;if(t.applicationCursorKeysMode&&(e+="\x1B[?1h"),t.applicationKeypadMode&&(e+="\x1B[?66h"),t.bracketedPasteMode&&(e+="\x1B[?2004h"),t.insertMode&&(e+="\x1B[4h"),t.originMode&&(e+="\x1B[?6h"),t.reverseWraparoundMode&&(e+="\x1B[?45h"),t.sendFocusMode&&(e+="\x1B[?1004h"),t.wraparoundMode===!1&&(e+="\x1B[?7l"),t.mouseTrackingMode!=="none")switch(t.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return t.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let t=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${t}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},D=class extends S{constructor(e,t,r){super(e);this._terminal=t;this._options=r;this._currentRow="";this._htmlContent="";t._core._themeService?this._ansiColors=t._core._themeService.colors.ansi:this._ansiColors=k}_beforeSerialize(e,t,r){this._htmlContent+="
";let l="#000000",s="#ffffff";(this._options.includeGlobalBackground??!1)&&(l=this._terminal.options.theme?.foreground??"#ffffff",s=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+l+";"),i.push("background-color: "+s+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,t){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,t){let r=t?e.getFgColor():e.getBgColor();if(t?e.isFgRGB():e.isBgRGB())return"#"+[r>>16&255,r>>8&255,r&255].map(s=>s.toString(16).padStart(2,"0")).join("");if(t?e.isFgPalette():e.isBgPalette())return this._ansiColors[r].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let t=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[t>>16&255,t>>8&255,t&255].map(l=>l.toString(16).padStart(2,"0")).join(""):this._ansiColors[t].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,t){let r=[];if(U(e,t))return;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i){let o=this._getHexColor(e,!0);o&&r.push("color: "+o+";");let u=this._getHexColor(e,!1);u&&r.push("background-color: "+u+";"),e.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&r.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&r.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let C=this._getUnderlineColor(e);C&&r.push("text-decoration-color: "+C+";")}return e.isInvisible()&&r.push("visibility: hidden;"),e.isItalic()&&r.push("font-style: italic;"),e.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,t);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=z(e.getChars())}_serializeString(){return this._htmlContent}};export{D as HTMLSerializeHandler,H as SerializeAddon}; ++var m=0,b=0,_=0,p=0;var g;(t=>{function a(r,l,s,i){return i!==void 0?`#${w(r)}${w(l)}${w(s)}${w(i)}`:`#${w(r)}${w(l)}${w(s)}`}t.toCss=a;function n(r,l,s,i=255){return(r<<24|l<<16|s<<8|i)>>>0}t.toRgba=n;function e(r,l,s,i){return{css:t.toCss(r,l,s,i),rgba:t.toRgba(r,l,s,i)}}t.toColor=e})(g||={});var N;(i=>{function a(o,u){if(p=(u.rgba&255)/255,p===1)return{css:u.css,rgba:u.rgba};let f=u.rgba>>24&255,C=u.rgba>>16&255,c=u.rgba>>8&255,h=o.rgba>>24&255,d=o.rgba>>16&255,I=o.rgba>>8&255;m=h+Math.round((f-h)*p),b=d+Math.round((C-d)*p),_=I+Math.round((c-I)*p);let L=g.toCss(m,b,_),E=g.toRgba(m,b,_);return{css:L,rgba:E}}i.blend=a;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,u,f){let C=B.ensureContrastRatio(o.rgba,u.rgba,f);if(C)return g.toColor(C>>24&255,C>>16&255,C>>8&255)}i.ensureContrastRatio=e;function t(o){let u=(o.rgba|255)>>>0;return[m,b,_]=B.toChannels(u),{css:g.toCss(m,b,_),rgba:u}}i.opaque=t;function r(o,u){return p=Math.round(u*255),[m,b,_]=B.toChannels(o.rgba),{css:g.toCss(m,b,_,p),rgba:g.toRgba(m,b,_,p)}}i.opacity=r;function l(o,u){return p=o.rgba&255,r(o,p*u/255)}i.multiplyOpacity=l;function s(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=s})(N||={});var x;(t=>{let a,n;try{let r=document.createElement("canvas");r.width=1,r.height=1;let l=r.getContext("2d",{willReadFrequently:!0});l&&(a=l,a.globalCompositeOperation="copy",n=a.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),g.toColor(m,b,_);case 5:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),p=parseInt(r.slice(4,5).repeat(2),16),g.toColor(m,b,_,p);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let l=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(l)return m=parseInt(l[1],10),b=parseInt(l[2],10),_=parseInt(l[3],10),p=Math.round((l[5]===void 0?1:parseFloat(l[5]))*255),g.toColor(m,b,_,p);if(r==="transparent")return{css:"transparent",rgba:0};if(!a||!n)throw new Error("css.toColor: Unsupported css format");if(a.fillStyle=n,a.fillStyle=r,typeof a.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(a.fillRect(0,0,1,1),[m,b,_,p]=a.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(m,b,_,p),css:r}}t.toColor=e})(x||={});var v;(e=>{function a(t){return n(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=a;function n(t,r,l){let s=t/255,i=r/255,o=l/255,u=s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),C=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return u*.2126+f*.7152+C*.0722}e.relativeLuminance2=n})(v||={});var B;(l=>{function a(s,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,u=i>>16&255,f=i>>8&255,C=s>>24&255,c=s>>16&255,h=s>>8&255;return m=C+Math.round((o-C)*p),b=c+Math.round((u-c)*p),_=h+Math.round((f-h)*p),g.toRgba(m,b,_)}l.blend=a;function n(s,i,o){let u=v.relativeLuminance(s>>8),f=v.relativeLuminance(i>>8);if(R(u,f)>8));if(I>8));return I>E?d:L}return d}let c=t(s,i,o),h=R(u,v.relativeLuminance(c>>8));if(h>8));return h>I?c:d}return c}}l.ensureContrastRatio=n;function e(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I0||h>0||d>0);)c-=Math.max(0,Math.ceil(c*.1)),h-=Math.max(0,Math.ceil(h*.1)),d-=Math.max(0,Math.ceil(d*.1)),I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));return(c<<24|h<<16|d<<8|255)>>>0}l.reduceLuminance=e;function t(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I>>0}l.increaseLuminance=t;function r(s){return[s>>24&255,s>>16&255,s>>8&255,s&255]}l.toChannels=r})(B||={});function w(a){let n=a.toString(16);return n.length<2?"0"+n:n}function R(a,n){return a{let a=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let t=n[e/36%6|0],r=n[e/6%6|0],l=n[e%6];a.push({css:g.toCss(t,r,l),rgba:g.toRgba(t,r,l)})}for(let e=0;e<24;e++){let t=8+e*10;a.push({css:g.toCss(t,t,t),rgba:g.toRgba(t,t,t)})}return a})());function A(a,n,e){return Math.max(n,Math.min(a,e))}function z(a){switch(a){case"&":return"&";case"<":return"<"}return a}var S=class{constructor(n){this._buffer=n}serialize(n,e){let t=this._buffer.getNullCell(),r=this._buffer.getNullCell(),l=t,s=n.start.y,i=n.end.y,o=n.start.x,u=n.end.x;this._beforeSerialize(i-s,s,i);for(let f=s;f<=i;f++){let C=this._buffer.getLine(f);if(C){let c=f===n.start.y?o:0,h=f===n.end.y?u:C.length;for(let d=c;d0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`);let r="";if(!t){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let l=this._buffer.getLine(e),s=this._buffer.getLine(e+1);if(!s.isWrapped)r=`\r ++`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{r="";let i=l.getCell(l.length-1,this._thisRowLastChar),o=l.getCell(l.length-2,this._thisRowLastSecondChar),u=s.getCell(0,this._nextRowFirstChar),f=u.getWidth()>1,C=!1;(u.getChars()&&(f?this._nullCellCount<=1:this._nullCellCount<=0))&&((i.getChars()||i.getWidth()===0)&&F(i,u)&&(C=!0),f&&(o.getChars()||o.getWidth()===0)&&F(i,u)&&F(o,u)&&(C=!0)),C||(r="-".repeat(this._nullCellCount+1),r+="\x1B[1D\x1B[1X",this._nullCellCount>0&&(r+="\x1B[A",l.length-this._nullCellCount>0&&(r+=`\x1B[${l.length-this._nullCellCount}C`),r+=`\x1B[${this._nullCellCount}X`,l.length-this._nullCellCount>0&&(r+=`\x1B[${l.length-this._nullCellCount}D`),r+="\x1B[B"),this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0)}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(e,t){let r=[];if(U(e,t))return r;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i)if(e.isAttributeDefault())t.isAttributeDefault()||r.push(0);else{if(l){let o=e.getFgColor();e.isFgRGB()?r.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?r.push(38,5,o):r.push(o&8?90+(o&7):30+(o&7)):r.push(39)}if(s){let o=e.getBgColor();e.isBgRGB()?r.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?r.push(48,5,o):r.push(o&8?100+(o&7):40+(o&7)):r.push(49)}if(i){if(e.isInverse()!==t.isInverse()&&r.push(e.isInverse()?7:27),/* PATCH(orca): bold(1)/dim(2) share reset 22 - clear before re-set, as one group */((b,d)=>{if(b||d){const c=b&&!e.isBold()||d&&!e.isDim();c&&r.push(22),e.isBold()&&(b||c)&&r.push(1),e.isDim()&&(d||c)&&r.push(2)}})(e.isBold()!==t.isBold(),e.isDim()!==t.isDim()),O(e,t))e.isUnderline()!==t.isUnderline()&&r.push(e.isUnderline()?4:24);else{let o=e.getUnderlineStyle();if(o===0)r.push(24);else if(o===1&&e.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+o),!e.isUnderlineColorDefault()){let u=e.getUnderlineColor();e.isUnderlineColorRGB()?r.push("58:2::"+(u>>>16&255)+":"+(u>>>8&255)+":"+(u&255)):r.push("58:5:"+u)}}e.isOverline()!==t.isOverline()&&r.push(e.isOverline()?53:55),e.isBlink()!==t.isBlink()&&r.push(e.isBlink()?5:25),e.isInvisible()!==t.isInvisible()&&r.push(e.isInvisible()?8:28),e.isItalic()!==t.isItalic()&&r.push(e.isItalic()?3:23),e.isStrikethrough()!==t.isStrikethrough()&&r.push(e.isStrikethrough()?9:29)}}return r}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",f=i&&e.isInverse()?this._buffer.getLine(r+1):void 0,g=f?.getCell(0,this._nextRowFirstChar),C=l===this._terminal.cols-1&&f?.isWrapped&&(g?.getWidth()??0)>1&&!!g&&U(e,g),q=i&&!!e.isInverse()&&!C,d=q&&(!!e.isUnderline()||!!e.isStrikethrough()||!!e.isOverline()),o=this._diffStyle(e,this._cursorStyle);if(i?q?o.length>0:!F(this._cursorStyle,e):o.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l,this._currentRow+=`\x1B[${o.join(";")}m`;let f=this._buffer.getLine(r);f!==void 0&&(f.getCell(l,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=l)}i&&!q?this._nullCellCount+=e.getWidth():(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),(q?(d&&(this._currentRow+="\x1B[24;29;55m"),this._currentRow+=" ".repeat(e.getWidth()),d&&(this._currentRow+=`\x1B[0m\x1B[${this._diffStyle(e,this._defaultCell).join(";")}m`)):this._currentRow+=e.getChars()),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l+e.getWidth())}_serializeString(e){let t=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(t=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let i=0;i{c>0?r+=`\x1B[${c}C`:c<0&&(r+=`\x1B[${-c}D`)};u&&((c=>{c>0?r+=`\x1B[${c}B`:c<0&&(r+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let l=this._terminal._core._inputHandler._curAttrData,s=this._diffStyle(l,this._cursorStyle);return s.length>0&&(r+=`\x1B[${s.join(";")}m`),r}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,t){let r=e.length,l=t===void 0?r:A(t+n.rows,0,r);return this._serializeBufferByRange(n,e,{start:r-l,end:r-1},!1)}_serializeBufferByRange(n,e,t,r){return new y(e,n).serialize({start:{x:0,y:typeof t.start=="number"?t.start:t.start.line},end:{x:n.cols,y:typeof t.end=="number"?t.end:t.end.line}},r)}_serializeBufferAsHTML(n,e){let t=n.buffer.active,r=new D(t,n,e),l=e.onlySelection??!1,s=e.range;if(s)return r.serialize({start:{x:s.startCol,y:(typeof s.startLine=="number",s.startLine)},end:{x:n.cols,y:(typeof s.endLine=="number",s.endLine)}});if(!l){let o=t.length,u=e.scrollback,f=u===void 0?o:A(u+n.rows,0,o);return r.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?r.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,t=e.scrollTop,r=e.scrollBottom;return t!==0||r!==n.rows-1?`\x1B[${t+1};${r+1}r`:""}_serializeModes(n){let e="",t=n.modes;if(t.applicationCursorKeysMode&&(e+="\x1B[?1h"),t.applicationKeypadMode&&(e+="\x1B[?66h"),t.bracketedPasteMode&&(e+="\x1B[?2004h"),t.insertMode&&(e+="\x1B[4h"),t.originMode&&(e+="\x1B[?6h"),t.reverseWraparoundMode&&(e+="\x1B[?45h"),t.sendFocusMode&&(e+="\x1B[?1004h"),t.wraparoundMode===!1&&(e+="\x1B[?7l"),t.mouseTrackingMode!=="none")switch(t.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return t.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let t=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${t}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},D=class extends S{constructor(e,t,r){super(e);this._terminal=t;this._options=r;this._currentRow="";this._htmlContent="";t._core._themeService?this._ansiColors=t._core._themeService.colors.ansi:this._ansiColors=k}_beforeSerialize(e,t,r){this._htmlContent+="
";let l="#000000",s="#ffffff";(this._options.includeGlobalBackground??!1)&&(l=this._terminal.options.theme?.foreground??"#ffffff",s=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+l+";"),i.push("background-color: "+s+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,t){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,t){let r=t?e.getFgColor():e.getBgColor();if(t?e.isFgRGB():e.isBgRGB())return"#"+[r>>16&255,r>>8&255,r&255].map(s=>s.toString(16).padStart(2,"0")).join("");if(t?e.isFgPalette():e.isBgPalette())return this._ansiColors[r].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let t=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[t>>16&255,t>>8&255,t&255].map(l=>l.toString(16).padStart(2,"0")).join(""):this._ansiColors[t].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,t){let r=[];if(U(e,t))return;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i){let o=this._getHexColor(e,!0);o&&r.push("color: "+o+";");let u=this._getHexColor(e,!1);u&&r.push("background-color: "+u+";"),e.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&r.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&r.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let C=this._getUnderlineColor(e);C&&r.push("text-decoration-color: "+C+";")}return e.isInvisible()&&r.push("visibility: hidden;"),e.isItalic()&&r.push("font-style: italic;"),e.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,t);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=z(e.getChars())}_serializeString(){return this._htmlContent}};export{D as HTMLSerializeHandler,H as SerializeAddon}; //# sourceMappingURL=addon-serialize.mjs.map diff --git a/src/SerializeAddon.ts b/src/SerializeAddon.ts -index e1728feb219c362dfa2ecb602ff99f830d520757..672fdd5b86d73d8694446138835bbeccd43cfaae 100644 +index e1728feb219c362dfa2ecb602ff99f830d520757..beaff8dd2c985a1e7378d42683c9940865057d6a 100644 --- a/src/SerializeAddon.ts +++ b/src/SerializeAddon.ts -@@ -310,7 +310,20 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -148,6 +148,7 @@ class StringSerializeHandler extends BaseSerializeHandler { + + // this is a null cell for reference for checking whether background is empty or not + private _backgroundCell: IBufferCell = this._buffer.getNullCell(); ++ private _defaultCell: IBufferCell = this._buffer.getNullCell(); + + private _firstRow: number = 0; + private _lastCursorRow: number = 0; +@@ -214,7 +215,7 @@ class StringSerializeHandler extends BaseSerializeHandler { + if ( + // you must output character to cause overflow, control sequence can't do this + nextRowFirstChar.getChars() && +- isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0 ++ (isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0) + ) { + if ( + // the last character can't be null, +@@ -251,9 +252,14 @@ class StringSerializeHandler extends BaseSerializeHandler { + if (this._nullCellCount > 0) { + // do these because we filled the last several null slot, which we shouldn't + rowSeparator += '\u001b[A'; +- rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}C`; ++ const contentCellCount = currentLine.length - this._nullCellCount; ++ if (contentCellCount > 0) { ++ rowSeparator += `\u001b[${contentCellCount}C`; ++ } + rowSeparator += `\u001b[${this._nullCellCount}X`; +- rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}D`; ++ if (contentCellCount > 0) { ++ rowSeparator += `\u001b[${contentCellCount}D`; ++ } + rowSeparator += '\u001b[B'; + } + +@@ -310,7 +316,20 @@ class StringSerializeHandler extends BaseSerializeHandler { } if (flagsChanged) { if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); } @@ -44,7 +80,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..672fdd5b86d73d8694446138835bbecc if (!equalUnderline(cell, oldCell)) { const style = cell.getUnderlineStyle(); if (style === UnderlineStyle.NONE) { -@@ -337,7 +350,7 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -337,7 +356,7 @@ class StringSerializeHandler extends BaseSerializeHandler { if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); } if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); } if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); } @@ -53,3 +89,58 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..672fdd5b86d73d8694446138835bbecc if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); } } } +@@ -356,12 +375,21 @@ class StringSerializeHandler extends BaseSerializeHandler { + + // this cell don't have content + const isEmptyCell = cell.getChars() === ''; ++ const nextLine = isEmptyCell && cell.isInverse() ? this._buffer.getLine(row + 1) : undefined; ++ const nextRowFirstCell = nextLine?.getCell(0, this._nextRowFirstChar); ++ // A pending wide glyph recreates its own final-column padding during replay. ++ const isWideWrapPadding = col === this._terminal.cols - 1 && ++ nextLine?.isWrapped && ++ (nextRowFirstCell?.getWidth() ?? 0) > 1 && ++ !!nextRowFirstCell && attributesEquals(cell, nextRowFirstCell); ++ // Cursor movement cannot reproduce an inverse cell's visible background. ++ const materializeEmptyCell = isEmptyCell && !!cell.isInverse() && !isWideWrapPadding; + + const sgrSeq = this._diffStyle(cell, this._cursorStyle); + +- // the empty cell style is only assumed to be changed when background changed, because +- // foreground is always 0. +- const styleChanged = isEmptyCell ? !equalBg(this._cursorStyle, cell) : sgrSeq.length > 0; ++ const styleChanged = isEmptyCell ++ ? materializeEmptyCell ? sgrSeq.length > 0 : !equalBg(this._cursorStyle, cell) ++ : sgrSeq.length > 0; + + /** + * handles style change +@@ -395,7 +423,7 @@ class StringSerializeHandler extends BaseSerializeHandler { + /** + * handles actual content + */ +- if (isEmptyCell) { ++ if (isEmptyCell && !materializeEmptyCell) { + this._nullCellCount += cell.getWidth(); + } else { + if (this._nullCellCount > 0) { +@@ -411,7 +439,19 @@ class StringSerializeHandler extends BaseSerializeHandler { + this._nullCellCount = 0; + } + +- this._currentRow += cell.getChars(); ++ if (materializeEmptyCell) { ++ const hasDecoration = !!cell.isUnderline() || !!cell.isStrikethrough() || !!cell.isOverline(); ++ if (hasDecoration) { ++ this._currentRow += '\u001b[24;29;55m'; ++ } ++ this._currentRow += ' '.repeat(cell.getWidth()); ++ if (hasDecoration) { ++ const restoreSgrSeq = this._diffStyle(cell, this._defaultCell); ++ this._currentRow += `\u001b[0m\u001b[${restoreSgrSeq.join(';')}m`; ++ } ++ } else { ++ this._currentRow += cell.getChars(); ++ } + + // update cursor + this._lastContentCursorRow = this._lastCursorRow = row; diff --git a/config/patches/@xterm__xterm@6.1.0-beta.287.patch b/config/patches/@xterm__xterm@6.1.0-beta.287.patch index 7cffe3f39f0..2a74b066172 100644 --- a/config/patches/@xterm__xterm@6.1.0-beta.287.patch +++ b/config/patches/@xterm__xterm@6.1.0-beta.287.patch @@ -1,40 +1,36 @@ diff --git a/lib/xterm.js b/lib/xterm.js -index 9602d2a2abbdd6eb1ed884dd2cdcace32d1bb1a3..a85075dcbea89c342500838a66b40f2ff6c21c0f 100644 +index 9602d2a2abbdd6eb1ed884dd2cdcace32d1bb1a3..89c478f49958c88e87dbca0cb0dfb5a4ea3de31d 100644 --- a/lib/xterm.js +++ b/lib/xterm.js @@ -1,2 +1,2 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(globalThis,()=>(()=>{"use strict";var e={2840(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=r.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this._register(new c.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this._register(this._terminal.onResize(e=>this._handleResize(e.rows))),this._register(this._terminal.onRender(e=>this._refreshRows(e.start,e.end))),this._register(this._terminal.onScroll(()=>this._refreshRows())),this._register(this._terminal.onA11yChar(e=>this._handleChar(e))),this._register(this._terminal.onLineFeed(()=>this._handleChar("\n"))),this._register(this._terminal.onA11yTab(e=>this._handleTab(e))),this._register(this._terminal.onKey(e=>this._handleKey(e.key))),this._register(this._terminal.onBlur(()=>this._clearLiveRegion())),this._register(this._renderService.onDimensionsChange(()=>this._refreshRowsDimensions())),this._register((0,f.addDisposableListener)(r,"selectionchange",()=>this._handleSelectionChange())),this._register(this._coreBrowserService.onDprChange(()=>this._refreshRowsDimensions())),this._refreshRowsDimensions(),this._refreshRows(),this._register((0,d.toDisposable)(()=>{this._accessibilityContainer.remove(),this._rowElements.length=0}))}_handleTab(e){for(let t=0;t0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,"\n"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent=l.tooMuchOutput.get())))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.lines.get(i.ydisp+r),t=[],o=e?.translateToString(!0,void 0,void 0,t)||"",n=(i.ydisp+r+1).toString(),a=this._rowElements[r];a&&(0===o.length?(a.textContent=" ",this._rowColumns.set(a,[0,1])):(a.textContent=o,this._rowColumns.set(a,t)),a.setAttribute("aria-posinset",n),a.setAttribute("aria-setsize",s),this._alignRowWidth(a))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent===l.tooMuchOutput.get()&&this._clearLiveRegion(),this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute("aria-posinset")===(0===t?"1":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,o;if(0===t?(r=i,o=this._rowElements.pop(),this._rowContainer.removeChild(o)):(r=this._rowElements.shift(),o=i,this._rowContainer.removeChild(r)),r.removeEventListener("focus",this._topBoundaryFocusListener),o.removeEventListener("focus",this._bottomBoundaryFocusListener),0===t){const e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement("afterbegin",e)}else{const e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._terminal.scrollLines(0===t?-1:1),this._rowElements[0===t?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleSelectionChange(){if(0===this._rowElements.length)return;const e=this._coreBrowserService.mainDocument.getSelection();if(!e)return;if(e.isCollapsed)return void(this._rowContainer.contains(e.anchorNode)&&this._terminal.clearSelection());if(!e.anchorNode||!e.focusNode)return void console.error("anchorNode and/or focusNode are null");let t={node:e.anchorNode,offset:e.anchorOffset},i={node:e.focusNode,offset:e.focusOffset};if((t.node.compareDocumentPosition(i.node)&Node.DOCUMENT_POSITION_PRECEDING||t.node===i.node&&t.offset>i.offset)&&([t,i]=[i,t]),t.node.compareDocumentPosition(this._rowElements[0])&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_FOLLOWING)&&(t={node:this._rowElements[0].childNodes[0],offset:0}),!this._rowContainer.contains(t.node))return;const s=this._rowElements.slice(-1)[0];if(i.node.compareDocumentPosition(s)&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_PRECEDING)&&(i={node:s,offset:s.textContent?.length??0}),!this._rowContainer.contains(i.node))return;const r=({node:e,offset:t})=>{const i=e instanceof Text?e.parentNode:e;let s=parseInt(i?.getAttribute("aria-posinset"),10)-1;if(isNaN(s))return console.warn("row is invalid. Race condition?"),null;const r=this._rowColumns.get(i);if(!r)return console.warn("columns is null. Race condition?"),null;let o=t=this._terminal.cols&&(++s,o=0),{row:s,column:o}},o=r(t),n=r(i);if(o&&n){if(o.row>n.row||o.row===n.row&&o.column>=n.column)throw new Error("invalid range");this._terminal.select(o.column,o.row,(n.row-o.row)*this._terminal.cols-o.column+n.column)}}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener("focus",this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;ee;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const e=this._coreBrowserService.mainDocument.createElement("div");return e.setAttribute("role","listitem"),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){Object.assign(this._accessibilityContainer.style,{width:`${this._renderService.dimensions.css.canvas.width}px`,fontSize:`${this._terminal.options.fontSize}px`}),this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;ethis._onBell.fire())),this._register(this._inputHandler.onRequestRefreshRows(e=>this.refresh(e?.start??0,e?.end??this.rows-1))),this._register(this._inputHandler.onRequestSendFocus(()=>this._reportFocus())),this._register(this._inputHandler.onRequestReset(()=>this.reset())),this._register(this._inputHandler.onRequestWindowsOptionsReport(e=>this._reportWindowsOptions(e))),this._register(this._inputHandler.onColor(e=>this._handleColorEvent(e))),this._register(I.EventUtils.forward(this._inputHandler.onCursorMove,this._onCursorMove)),this._register(I.EventUtils.forward(this._inputHandler.onTitleChange,this._onTitleChange)),this._register(I.EventUtils.forward(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this._register(I.EventUtils.forward(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this._register(this._bufferService.onResize(e=>this._afterResize(e.cols,e.rows))),this._register((0,N.toDisposable)(()=>{this._customKeyEventHandler=void 0,this.element?.parentNode?.removeChild(this.element)}))}_handleColorEvent(e){if(this._themeService)for(const t of e){let e,i;switch(t.index){case 256:e="foreground",i="10";break;case 257:e="background",i="11";break;case 258:e="cursor",i="12";break;default:e="ansi",i="4;"+t.index}switch(t.type){case 0:const s=E.color.toColorRGB("ansi"===e?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`]${i};${(0,M.toRgbString)(s)}\\`);break;case 1:if("ansi"===e)this._themeService.modifyColors(e=>e.ansi[t.index]=E.channels.toColor(...t.color));else{const i=e;this._themeService.modifyColors(e=>e[i]=E.channels.toColor(...t.color))}break;case 2:this._themeService.restoreColor(t.index)}}}_reportColorScheme(){if(!this._themeService)return;const e=E.rgb.relativeLuminance(this._themeService.colors.background.rgba>>8)>8)?1:2;this.coreService.triggerDataEvent(`[?997;${e}n`)}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(P.AccessibilityManager,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.add("focus"),this._showCursor(),this._onFocus.fire()}blur(){return this.textarea?.blur()}_handleTextAreaBlur(){this.textarea.value="",this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.remove("focus"),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;const e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;const i=Math.min(this.buffer.x,this.cols-1),s=this._renderService.dimensions.css.cell.height,r=t.getWidth(i),o=this._renderService.dimensions.css.cell.width*r,n=this.buffer.y*this._renderService.dimensions.css.cell.height,a=i*this._renderService.dimensions.css.cell.width;this.textarea.style.left=a+"px",this.textarea.style.top=n+"px",this.textarea.style.width=o+"px",this.textarea.style.height=s+"px",this.textarea.style.lineHeight=s+"px",this.textarea.style.zIndex="-5"}_initGlobal(){this._bindKeys(),this._register((0,H.addDisposableListener)(this.element,"copy",e=>{this.hasSelection()&&(0,a.copyHandler)(e,this._selectionService)}));const e=e=>(0,a.handlePasteEvent)(e,this.textarea,this.coreService,this.optionsService);this._register((0,H.addDisposableListener)(this.textarea,"paste",e)),this._register((0,H.addDisposableListener)(this.element,"paste",e)),x.isFirefox?this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>{2===e.button&&(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})):this._register((0,H.addDisposableListener)(this.element,"contextmenu",e=>{(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})),x.isLinux&&this._register((0,H.addDisposableListener)(this.element,"auxclick",e=>{1===e.button&&(0,a.moveTextAreaUnderMouseCursor)(e,this.textarea,this.screenElement)}))}_bindKeys(){this._register((0,H.addDisposableListener)(this.textarea,"keyup",e=>this._keyUp(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keydown",e=>this._keyDown(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keypress",e=>this._keyPress(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"compositionstart",()=>{this._syncTextArea(),this._compositionHelper.compositionstart(),this._compositionHelper.updateCompositionElements()})),this._register((0,H.addDisposableListener)(this.textarea,"compositionupdate",e=>this._compositionHelper.compositionupdate(e))),this._register((0,H.addDisposableListener)(this.textarea,"compositionend",()=>this._compositionHelper.compositionend())),this._register((0,H.addDisposableListener)(this.textarea,"input",e=>this._inputEvent(e),!0)),this._register(this.onRender(()=>this._compositionHelper.updateCompositionElements()))}open(e){if(!e)throw new Error("Terminal requires a parent element.");if(e.isConnected||this._logService.debug("Terminal.open was called on an element that was not attached to the DOM"),this.element?.ownerDocument.defaultView&&this._coreBrowserService)return void(this.element.ownerDocument.defaultView!==this._coreBrowserService.window&&(this._coreBrowserService.window=this.element.ownerDocument.defaultView));this._document=e.ownerDocument,this.options.documentOverride&&this.options.documentOverride instanceof Document&&(this._document=this.optionsService.rawOptions.documentOverride),this.element=this._document.createElement("div"),this.element.dir="ltr",this.element.classList.add("terminal"),this.element.classList.add("xterm"),this.element.classList.toggle("allow-transparency",this.options.allowTransparency),this._register(this.optionsService.onSpecificOptionChange("allowTransparency",e=>this.element.classList.toggle("allow-transparency",e))),e.appendChild(this.element);const t=this._document.createDocumentFragment();this._viewportElement=this._document.createElement("div"),this._viewportElement.classList.add("xterm-viewport"),t.appendChild(this._viewportElement),this.screenElement=this._document.createElement("div"),this.screenElement.classList.add("xterm-screen"),this._register((0,H.addDisposableListener)(this.screenElement,"mousemove",e=>this.updateCursorStyle(e))),this._helperContainer=this._document.createElement("div"),this._helperContainer.classList.add("xterm-helpers"),this.screenElement.appendChild(this._helperContainer),t.appendChild(this.screenElement);const i=this.textarea=this._document.createElement("textarea");this.textarea.classList.add("xterm-helper-textarea"),this.textarea.setAttribute("aria-label",h.promptLabel.get()),x.isChromeOS||this.textarea.setAttribute("aria-multiline","false"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.tabIndex=0,this._register(this.optionsService.onSpecificOptionChange("disableStdin",()=>i.readOnly=this.optionsService.rawOptions.disableStdin)),this.textarea.readOnly=this.optionsService.rawOptions.disableStdin,this._coreBrowserService=this._register(this._instantiationService.createInstance(g.CoreBrowserService,this.textarea,e.ownerDocument.defaultView??window,this._document??("undefined"!=typeof window?window.document:null))),this._instantiationService.setService(C.ICoreBrowserService,this._coreBrowserService),this._register((0,H.addDisposableListener)(this.textarea,"focus",e=>this._handleTextAreaFocus(e))),this._register((0,H.addDisposableListener)(this.textarea,"blur",()=>this._handleTextAreaBlur())),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(p.CharSizeService,this._document,this._helperContainer),this._instantiationService.setService(C.ICharSizeService,this._charSizeService),this._themeService=this._instantiationService.createInstance(k.ThemeService),this._instantiationService.setService(C.IThemeService,this._themeService),this._register(this._inputHandler.onRequestColorSchemeQuery(()=>this._reportColorScheme())),this._register(this._themeService.onChangeColors(()=>{this.coreService.decPrivateModes.colorSchemeUpdates&&this._reportColorScheme()})),this._characterJoinerService=this._instantiationService.createInstance(v.CharacterJoinerService),this._instantiationService.setService(C.ICharacterJoinerService,this._characterJoinerService),this._renderService=this._register(this._instantiationService.createInstance(w.RenderService,this.rows,this.screenElement)),this._instantiationService.setService(C.IRenderService,this._renderService),this._register(this._renderService.onRenderedViewportChange(e=>this._onRender.fire(e))),this._register(this._renderService.onDimensionsChange(e=>this._onDimensionsChange.fire({css:{canvas:{...e.css.canvas},cell:{...e.css.cell}},device:{canvas:{...e.device.canvas},cell:{...e.device.cell},char:{...e.device.char}}}))),this.onResize(e=>this._renderService.resize(e.cols,e.rows)),this._compositionView=this._document.createElement("div"),this._compositionView.classList.add("composition-view"),this._compositionHelper=this._instantiationService.createInstance(u.CompositionHelper,this.textarea,this._compositionView),this._helperContainer.appendChild(this._compositionView),this._mouseCoordsService=this._instantiationService.createInstance(S.MouseCoordsService),this._instantiationService.setService(C.IMouseCoordsService,this._mouseCoordsService);const s=this._linkifier.value=this._register(this._instantiationService.createInstance(O.Linkifier,this.screenElement));this.element.appendChild(t);try{this._onWillOpen.fire(this.element)}catch(e){this._logService.error("onWillOpen handler threw an exception",e)}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._register(this.onCursorMove(()=>{this._renderService.handleCursorMove(),this._syncTextArea()})),this._register(this.onResize(()=>{this._renderService.handleResize(this.cols,this.rows),this._syncTextArea()})),this._register(this.onBlur(()=>this._renderService.handleBlur())),this._register(this.onFocus(()=>this._renderService.handleFocus())),this._viewport=this._register(this._instantiationService.createInstance(c.Viewport,this.element,this.screenElement)),this._register(this._viewport.onRequestScrollLines(e=>{super.scrollLines(e,!1),this.refresh(0,this.rows-1)})),this._selectionService=this._register(this._instantiationService.createInstance(y.SelectionService,this.element,this.screenElement,s)),this._instantiationService.setService(C.ISelectionService,this._selectionService),this._mouseService=this._instantiationService.createInstance(b.MouseService),this._instantiationService.setService(C.IMouseService,this._mouseService),this._register(this._selectionService.onRequestScrollLines(e=>this.scrollLines(e.amount,e.suppressScrollEvent))),this._register(this._selectionService.onSelectionChange(()=>this._onSelectionChange.fire())),this._register(this._selectionService.onRequestRedraw(e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode))),this._register(this._selectionService.onLinuxMouseSelection(e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()})),this._register(I.EventUtils.any(this._onScroll.event,this._inputHandler.onScroll)(()=>{this._selectionService.refresh(),this._viewport?.queueSync()})),this._register(this._instantiationService.createInstance(d.BufferDecorationRenderer,this.screenElement)),this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>this._selectionService.handleMouseDown(e))),this.mouseStateService.areMouseEventsActive&&!this.options.mouseEventsRequireAlt?(this._selectionService.disable(),this.element.classList.add("enable-mouse-events")):(this._selectionService.enable(),this.element.classList.remove("enable-mouse-events")),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(P.AccessibilityManager,this)),this._register(this.optionsService.onSpecificOptionChange("screenReaderMode",e=>this._handleScreenReaderModeOptionChange(e)));const r=this.options.scrollbar?.showScrollbar??!0,o=this.options.scrollbar?.width;r&&o&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange("scrollbar",e=>{const t=(e?.showScrollbar??!0)&&!!e?.width;!this._overviewRulerRenderer&&t&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement)))}),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this._mouseService.bindMouse({element:this.element,screenElement:this.screenElement,document:this._document,handleTouchScroll:e=>this._viewport?.handleTouchScroll(e)},e=>this._register(e),()=>this.focus())}_createRenderer(){return this._instantiationService.createInstance(f.DomRenderer,this,this._document,this.element,this.screenElement,this._viewportElement,this._helperContainer,this.linkifier)}refresh(e,t,i=!1){this._renderService?.refreshRows(e,t,i)}updateCursorStyle(e){this._selectionService?.shouldColumnSelect(e)?this.element.classList.add("column-select"):this.element.classList.remove("column-select")}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t){this._viewport?this._viewport.scrollLines(e):super.scrollLines(e,t),this.refresh(0,this.rows-1)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){e&&this._viewport?this._viewport.scrollToLine(this.buffer.ybase,!0):this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}paste(e){(0,a.paste)(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}attachCustomWheelEventHandler(e){this.mouseStateService.setCustomWheelEventHandler(e)}registerLinkProvider(e){return this._linkProviderService.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");const t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return!!this._selectionService&&this._selectionService.hasSelection}select(e,t,i){this._selectionService.setSelection(e,t,i)}getSelection(){return this._selectionService?this._selectionService.selectionText:""}getSelectionPosition(){if(this._selectionService&&this._selectionService.hasSelection)return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){this._selectionService?.clearSelection()}selectAll(){this._selectionService?.selectAll()}selectLines(e,t){this._selectionService?.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;const t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(!0),!1;t||"Dead"!==e.key&&"AltGraph"!==e.key||(this._unprocessedDeadKey=!0);const i=this._keyboardService.evaluateKeyDown(e);if(this.updateCursorStyle(e),3===i.type||2===i.type){const t=this.rows-1;return this.scrollLines(2===i.type?-t:t),e.preventDefault(),e.stopPropagation(),!1}if(1===i.type&&this.selectAll(),this._isThirdLevelShift(this.browser,e))return!0;if(i.cancel&&(e.preventDefault(),e.stopPropagation()),!i.key)return!0;if(!this._keyboardService.useKitty&&!this._keyboardService.useWin32InputMode&&e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&1===e.key.length&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)return!0;if(this._unprocessedDeadKey)return this._unprocessedDeadKey=!1,!0;""!==i.key&&"\r"!==i.key||(this.textarea.value="");const s=this._keyboardService.useWin32InputMode&&W(e);if(this._onKey.fire({key:i.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(i.key,!s),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey)return e.preventDefault(),e.stopPropagation(),!1;this._keyDownHandled=!0}_isThirdLevelShift(e,t){const i=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState("AltGraph");return"keypress"===t.type?i:i&&(!t.keyCode||t.keyCode>47)}_keyUp(e){if(this._keyDownSeen=!1,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return;W(e)||this.focus();const t=this._keyboardService.evaluateKeyUp(e);if(t?.key){const i=this._keyboardService.useWin32InputMode&&W(e);this.coreService.triggerDataEvent(t.key,!i)}this.updateCursorStyle(e),this._keyPressHandled=!1}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled)return!1;if(this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;if(e.charCode)t=e.charCode;else if(null===e.which||void 0===e.which)t=e.keyCode;else{if(0===e.which||0===e.charCode)return!1;t=e.which}return!(!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)||(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,0))}_inputEvent(e){if(e.data&&"insertText"===e.inputType&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;const t=e.data;return this.coreService.triggerDataEvent(t,!0),!0}return!1}resize(e,t){e!==this.cols||t!==this.rows?super.resize(e,t):this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure()}_afterResize(e,t){this._charSizeService?.measure()}clear(){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;efunction(e){const t=l(e);for(t.animFrameRequested=!1,t.current=t.next,t.next=[],t.inAnimationFrameRunner=!0;t.current.length>0;)t.current.sort(a.sort),t.current.shift().execute();t.inAnimationFrameRunner=!1}(e))),r};const s=i(3132);function r(e){const t=e;if(t?.ownerDocument?.defaultView)return t.ownerDocument.defaultView;const i=e;return i?.view?i.view:window}class o{constructor(e,t,i,s){this._node=e,this._type=t,this._handler=i,this._options=s,e.addEventListener(t,i,s)}dispose(){this._node&&this._handler&&(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}}function n(e,t,i,s){return new o(e,t,i,s)}t.eventType={CLICK:"click",MOUSE_DOWN:"mousedown",MOUSE_OVER:"mouseover",MOUSE_LEAVE:"mouseleave",KEY_DOWN:"keydown",KEY_UP:"keyup",INPUT:"input",BLUR:"blur",FOCUS:"focus",CHANGE:"change",POINTER_DOWN:"pointerdown",POINTER_MOVE:"pointermove",POINTER_UP:"pointerup",MOUSE_WHEEL:"wheel",WHEEL:"wheel"};class a{constructor(e,t){this._runner=e,this.priority=t,this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(e){console.error(e)}}static sort(e,t){return t.priority-e.priority}}const h=new Map;function l(e){let t=h.get(e);return t||(t={next:[],current:[],animFrameRequested:!1,inAnimationFrameRunner:!1},h.set(e,t)),t}class c extends s.IntervalTimer{constructor(e){super(),this._defaultTarget=e?r(e):void 0}cancelAndSet(e,t,i){super.cancelAndSet(e,t,i??this._defaultTarget??window)}}t.WindowIntervalTimer=c},8906(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Linkifier=void 0;const o=i(4812),n=i(6501),a=i(7098),h=i(8636),l=i(4159);let c=class extends o.Disposable{get currentLink(){return this._currentLink}constructor(e,t,i,s,r){super(),this._element=e,this._mouseCoordsService=t,this._renderService=i,this._bufferService=s,this._linkProviderService=r,this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this._register(new h.Emitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this._register(new h.Emitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this._register((0,o.toDisposable)(()=>{(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0,this._lastMouseEvent=void 0,this._activeProviderReplies?.clear()})),this._register(this._bufferService.onResize(()=>{this._clearCurrentLink(),this._wasResized=!0})),this._register((0,l.addDisposableListener)(this._element,"mouseleave",()=>{this._isMouseOut=!0,this._clearCurrentLink()})),this._register((0,l.addDisposableListener)(this._element,"mousemove",this._handleMouseMove.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mousedown",this._handleMouseDown.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mouseup",this._handleMouseUp.bind(this)))}_handleMouseMove(e){this._lastMouseEvent=e;const t=this._positionFromMouseEvent(e,this._element);if(!t)return;this._isMouseOut=!1;const i=e.composedPath();for(let e=0;e{e?.forEach(e=>{e.link.dispose&&e.link.dispose()})}),this._activeProviderReplies=new Map,this._activeLine=e.y);let i=!1;for(const[s,r]of this._linkProviderService.linkProviders.entries())if(t){const t=this._activeProviderReplies?.get(s);t&&(i=this._checkLinkProviderResult(s,e,i))}else r.provideLinks(e.y,t=>{if(this._isMouseOut)return;const r=t?.map(e=>({link:e}));this._activeProviderReplies?.set(s,r),i=this._checkLinkProviderResult(s,e,i),this._activeProviderReplies?.size===this._linkProviderService.linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)})}_removeIntersectingLinks(e,t){const i=new Set;for(let s=0;se?this._bufferService.cols:s.link.range.end.x;for(let e=o;e<=n;e++){if(i.has(e)){r.splice(t--,1);break}i.add(e)}}}}_checkLinkProviderResult(e,t,i){if(!this._activeProviderReplies)return i;const s=this._activeProviderReplies.get(e);let r=!1;for(let t=0;tthis._linkAtPosition(e.link,t));e&&(i=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviderService.linkProviders.length&&!i)for(let e=0;ethis._linkAtPosition(e.link,t));if(s){i=!0,this._handleNewLink(s);break}}return i}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._currentLink)return;const t=this._positionFromMouseEvent(e,this._element);var i,s;t&&this._mouseDownLink&&(i=this._mouseDownLink.link,s=this._currentLink.link,i.text===s.text&&i.range.start.x===s.range.start.x&&i.range.start.y===s.range.start.y&&i.range.end.x===s.range.end.x&&i.range.end.y===s.range.end.y)&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){this._currentLink&&this._lastMouseEvent&&(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0)}_handleNewLink(e){if(!this._lastMouseEvent)return;const t=this._positionFromMouseEvent(this._lastMouseEvent,this._element);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:void 0===e.link.decorations||e.link.decorations.underline,pointerCursor:void 0===e.link.decorations||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>this._currentLink?.state?.decorations.pointerCursor,set:e=>{this._currentLink?.state&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&this._element.classList.toggle("xterm-cursor-pointer",e))}},underline:{get:()=>this._currentLink?.state?.decorations.underline,set:t=>{this._currentLink?.state&&this._currentLink?.state?.decorations.underline!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e=>{if(!this._currentLink)return;const t=0===e.start?0:e.start+1+this._bufferService.buffer.ydisp,i=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=i&&(this._clearCurrentLink(t,i),this._lastMouseEvent)){const e=this._positionFromMouseEvent(this._lastMouseEvent,this._element);e&&this._askForLink(e,!1)}})))}_linkHover(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add("xterm-cursor-pointer")),t.hover&&t.hover(i,t.text)}_fireUnderlineEvent(e,t){const i=e.range,s=this._bufferService.buffer.ydisp,r=this._createLinkUnderlineEvent(i.start.x-1,i.start.y-s-1,i.end.x,i.end.y-s-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(r)}_linkLeave(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove("xterm-cursor-pointer")),t.leave&&t.leave(i,t.text)}_linkAtPosition(e,t){const i=e.range.start.y*this._bufferService.cols+e.range.start.x,s=e.range.end.y*this._bufferService.cols+e.range.end.x,r=t.y*this._bufferService.cols+t.x;return i<=r&&r<=s}_positionFromMouseEvent(e,t){const i=this._mouseCoordsService.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(i)return{x:i[0],y:i[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,i,s,r){return{x1:e,y1:t,x2:i,y2:s,cols:this._bufferService.cols,fg:r}}};t.Linkifier=c,t.Linkifier=c=s([r(1,a.IMouseCoordsService),r(2,a.IRenderService),r(3,n.IBufferService),r(4,a.ILinkProviderService)],c)},7721(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.tooMuchOutput=t.promptLabel=void 0;let i="Terminal input";const s={get:()=>i,set:e=>i=e};t.promptLabel=s;let r="Too much output to announce, navigate to rows manually to read";const o={get:()=>r,set:e=>r=e};t.tooMuchOutput=o},3285(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkProvider=void 0;const o=i(3055),n=i(6501);let a=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i,this._workCell=new o.CellData}provideLinks(e,t){const i=this._bufferService.buffer.lines.get(e-1);if(!i)return void t(void 0);const s=[],r=this._optionsService.rawOptions.linkHandler,o=this._workCell,n=i.getTrimmedLength();let a=-1,l=-1,c=!1;for(let t=0;tr?r.activate(e,t,d):h(0,t),hover:(e,t)=>r?.hover?.(e,t,d),leave:(e,t)=>r?.leave?.(e,t,d)})}c=!1,o.hasExtendedAttrs()&&o.extended.urlId?(l=t,a=o.extended.urlId):(l=-1,a=-1)}}t(s)}_getRangeWithLineWrap(e,t,i,s){let r=e,o=t,n=e,a=i;for(;0===o;){const e=this._bufferService.buffer.lines.get(r-1);if(!e?.isWrapped)break;const t=this._bufferService.buffer.lines.get(r-2);if(!t)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,i-1,s))break;let n=i-1;for(;n>0&&this._hasUrlId(t,n-1,s);)n--;r--,o=n}for(;;){const e=this._bufferService.buffer.lines.get(n-1);if(!e)break;if(a!==e.getTrimmedLength())break;const t=this._bufferService.buffer.lines.get(n);if(!t?.isWrapped)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,0,s))break;let r=1;for(;rthis._innerRefresh()),this._animationFrame}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return void this._runRefreshCallbacks();const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(const e of this._refreshCallbacks)e(0);this._refreshCallbacks=[]}}},4292(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.TimeBasedDebouncer=void 0,t.TimeBasedDebouncer=class{constructor(e,t=1e3){this._renderCallback=e,this._debounceThresholdMS=t,this._lastRefreshMs=0,this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0),this._additionalRefreshRequested=!1}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t;const s=performance.now();if(s-this._lastRefreshMs>=this._debounceThresholdMS)void 0!==this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0,this._additionalRefreshRequested=!1),this._lastRefreshMs=s,this._innerRefresh();else if(!this._additionalRefreshRequested){const e=s-this._lastRefreshMs,t=this._debounceThresholdMS-e;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout(()=>{this._lastRefreshMs=performance.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0},t)}}_innerRefresh(){if(void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return;const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t)}}},9302(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_ANSI_COLORS=void 0;const s=i(4103);t.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const e=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],t=[0,95,135,175,215,255];for(let i=0;i<216;i++){const r=t[i/36%6|0],o=t[i/6%6|0],n=t[i%6];e.push({css:s.channels.toCss(r,o,n),rgba:s.channels.toRgba(r,o,n)})}for(let t=0;t<24;t++){const i=8+10*t;e.push({css:s.channels.toCss(i,i,i),rgba:s.channels.toRgba(i,i,i)})}return e})())},4017(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Viewport=void 0;const o=i(7098),n=i(4812),a=i(6501),h=i(4159),l=i(8566),c=i(8636),d=i(7880);let _=class extends n.Disposable{constructor(e,t,i,s,r,o,a,_,u){super(),this._bufferService=i,this._coreService=r,this._optionsService=_,this._renderService=u,this._onRequestScrollLines=this._register(new c.Emitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._isSyncing=!1,this._isHandlingScroll=!1,this._suppressOnScrollHandler=!1,this._needsSyncOnRender=!1;const f=this._register(new d.Scrollable({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:e=>(0,h.scheduleAtNextAnimationFrame)(s.window,e)}));this._register(this._optionsService.onSpecificOptionChange("smoothScrollDuration",()=>{f.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)})),this._scrollableElement=this._register(new l.SmoothScrollableElement(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,verticalHasArrows:this._optionsService.rawOptions.scrollbar?.showArrows??!1,...this._getChangeOptions()},f)),this._register(this._optionsService.onMultipleOptionChange(["scrollSensitivity","fastScrollSensitivity","scrollbar"],()=>this._scrollableElement.updateOptions(this._getChangeOptions()))),this._register(o.onProtocolChange(e=>{this._scrollableElement.updateOptions({handleMouseWheel:!(16&e)})})),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{e.style.backgroundColor=a.colors.background.css,this._scrollableElement.getDomNode().style.backgroundColor=a.colors.background.css})),e.appendChild(this._scrollableElement.getDomNode()),this._register((0,n.toDisposable)(()=>this._scrollableElement.getDomNode().remove())),this._styleElement=s.mainDocument.createElement("style"),t.appendChild(this._styleElement),this._register((0,n.toDisposable)(()=>this._styleElement.remove())),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{this._styleElement.textContent=[".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {",` background: ${a.colors.scrollbarSliderBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {",` background: ${a.colors.scrollbarSliderHoverBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {",` background: ${a.colors.scrollbarSliderActiveBackground.css};`,"}"].join("\n")})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(e=>this._handleScroll(e)))}scrollLines(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){const e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,i=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:i,verticalHasArrows:t}}queueSync(e){void 0!==e&&(this._latestYDisp=e),void 0===this._queuedAnimationFrame&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){this._renderService&&!this._isSyncing&&(this._coreService.decPrivateModes.synchronizedOutput?this._needsSyncOnRender=!0:(this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1))}_handleScroll(e){if(!this._renderService)return;if(this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;const t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),i=t-this._bufferService.buffer.ydisp;0!==i&&(this._latestYDisp=t,this._onRequestScrollLines.fire(i)),this._isHandlingScroll=!1}handleTouchScroll(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};t.Viewport=_,t.Viewport=_=s([r(2,a.IBufferService),r(3,o.ICoreBrowserService),r(4,a.ICoreService),r(5,a.IMouseStateService),r(6,o.IThemeService),r(7,a.IOptionsService),r(8,o.IRenderService)],_)},4196(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferDecorationRenderer=void 0;const o=i(7098),n=i(4812),a=i(6501);let h=class extends n.Disposable{constructor(e,t,i,s,r){super(),this._screenElement=e,this._bufferService=t,this._coreBrowserService=i,this._decorationService=s,this._renderService=r,this._decorationElements=new Map,this._altBufferIsActive=!1,this._dimensionsChanged=!1,this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(e=>this._removeDecoration(e))),this._register((0,n.toDisposable)(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){void 0===this._animationFrame&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(const e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){const t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer","top"===e?.options?.layer),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",t.style.top=(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height+"px",t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;const i=e.options.x??0;return i&&i>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){const t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let i=this._decorationElements.get(e);i||(i=this._createElement(e),e.element=i,this._decorationElements.set(e,i),this._container.appendChild(i),e.onDispose(()=>{this._decorationElements.delete(e),i.remove()})),i.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(i.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,i.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",i.style.top=t*this._renderService.dimensions.css.cell.height+"px",i.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(i)}}_refreshXPosition(e,t=e.element){if(!t)return;const i=e.options.x??0;"right"===(e.options.anchor||"left")?t.style.right=i?i*this._renderService.dimensions.css.cell.width+"px":"":t.style.left=i?i*this._renderService.dimensions.css.cell.width+"px":""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};t.BufferDecorationRenderer=h,t.BufferDecorationRenderer=h=s([r(1,a.IBufferService),r(2,o.ICoreBrowserService),r(3,a.IDecorationService),r(4,o.IRenderService)],h)},957(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ColorZoneStore=void 0,t.ColorZoneStore=class{constructor(){this._zones=[],this._zonePool=[],this._zonePoolIndex=0,this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(e){if(e.options.overviewRulerOptions){for(const t of this._zones)if(t.color===e.options.overviewRulerOptions.color&&t.position===e.options.overviewRulerOptions.position){if(this._lineIntersectsZone(t,e.marker.line))return;if(this._lineAdjacentToZone(t,e.marker.line,e.options.overviewRulerOptions.position))return void this._addLineToZone(t,e.marker.line)}if(this._zonePoolIndex=e.startBufferLine&&t<=e.endBufferLine}_lineAdjacentToZone(e,t,i){return t>=e.startBufferLine-this._linePadding[i||"full"]&&t<=e.endBufferLine+this._linePadding[i||"full"]}_addLineToZone(e,t){e.startBufferLine=Math.min(e.startBufferLine,t),e.endBufferLine=Math.max(e.endBufferLine,t)}}},9925(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OverviewRulerRenderer=void 0;const o=i(957),n=i(7098),a=i(4812),h=i(6501),l={full:0,left:0,center:0,right:0},c={full:0,left:0,center:0,right:0},d={full:0,left:0,center:0,right:0};let _=class extends a.Disposable{get _width(){const e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??1?e?.width??0:0}constructor(e,t,i,s,r,n,h,l){super(),this._viewportElement=e,this._screenElement=t,this._bufferService=i,this._decorationService=s,this._renderService=r,this._optionsService=n,this._themeService=h,this._coreBrowserService=l,this._colorZoneStore=new o.ColorZoneStore,this._shouldUpdateDimensions=!0,this._shouldUpdateAnchor=!0,this._lastKnownBufferLength=0,this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register((0,a.toDisposable)(()=>this._canvas?.remove()));const c=this._canvas.getContext("2d");if(!c)throw new Error("Ctx cannot be null");this._ctx=c,this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register((0,a.toDisposable)(()=>{void 0!==this._animationFrame&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}_refreshDrawConstants(){const e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);c.full=this._canvas.width,c.left=e,c.center=t,c.right=e,this._refreshDrawHeightConstants(),d.full=1,d.left=1,d.center=1+c.left,d.right=1+c.left+c.center}_refreshDrawHeightConstants(){l.full=Math.round(2*this._coreBrowserService.dpr);const e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);l.left=t,l.center=t,l.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;const e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(const e of this._decorationService.decorations)this._colorZoneStore.addDecoration(e);this._ctx.lineWidth=1,this._renderRulerOutline();const e=this._colorZoneStore.zones;for(const t of e)"full"!==t.position&&this._renderColorZone(t);for(const t of e)"full"===t.position&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect(d[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-l[e.position||"full"]/2),c[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+l[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};t.OverviewRulerRenderer=_,t.OverviewRulerRenderer=_=s([r(2,h.IBufferService),r(3,h.IDecorationService),r(4,n.IRenderService),r(5,h.IOptionsService),r(6,n.IThemeService),r(7,n.ICoreBrowserService)],_)},3618(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CompositionHelper=void 0;const o=i(7098),n=i(6501);let a=class{get isComposing(){return this._isComposing}constructor(e,t,i,s,r,o){this._textarea=e,this._compositionView=t,this._bufferService=i,this._optionsService=s,this._coreService=r,this._renderService=o,this._isComposing=!1,this._isSendingComposition=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent=""}compositionstart(){this._isComposing=!0;const e=this._textarea.selectionStart??this._textarea.value.length,t=this._textarea.selectionEnd??e;this._compositionPosition.start=Math.min(e,t),this._compositionPosition.end=Math.max(e,t),this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionView.classList.add("active")}compositionupdate(e){this._compositionView.textContent=`‎${e.data}‎`,this.updateCompositionElements(),setTimeout(()=>{const e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)},0)}compositionend(){this._finalizeComposition(!0)}keydown(e){if(this._isComposing||this._isSendingComposition){if(20===e.keyCode||229===e.keyCode)return!1;if(16===e.keyCode||17===e.keyCode||18===e.keyCode)return!1;this._finalizeComposition(!1)}return 229!==e.keyCode||(this._handleAnyTextareaChanges(),!1)}_finalizeComposition(e){if(this._compositionView.classList.remove("active"),this._isComposing=!1,e){const e={start:this._compositionPosition.start,end:this._compositionPosition.end},t=this._compositionSuffix;this._isSendingComposition=!0,setTimeout(()=>{if(this._isSendingComposition){let i;if(this._isSendingComposition=!1,e.start+=this._dataAlreadySent.length,this._isComposing)i=this._textarea.value.substring(e.start,this._compositionPosition.start);else{const s=this._textarea.value,r=t.length>0&&s.endsWith(t)?s.length-t.length:s.length;i=s.substring(e.start,Math.max(e.start,r))}i.length>0&&this._coreService.triggerDataEvent(i,!0)}},0)}else{this._isSendingComposition=!1;const e=this._textarea.value.substring(this._compositionPosition.start,this._compositionPosition.end);this._coreService.triggerDataEvent(e,!0)}}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;const e=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){const t=this._textarea.value,i=t.replace(e,"");this._dataAlreadySent=i,t.length>e.length?this._coreService.triggerDataEvent(i,!0):t.lengththis.updateCompositionElements(!0),0)}}};t.CompositionHelper=a,t.CompositionHelper=a=s([r(2,n.IBufferService),r(3,n.IOptionsService),r(4,n.ICoreService),r(5,o.IRenderService)],a)},5251(e,t){function i(e,t,i){const s=i.getBoundingClientRect(),r=e.getComputedStyle(i),o=parseInt(r.getPropertyValue("padding-left"),10),n=parseInt(r.getPropertyValue("padding-top"),10);return[t.clientX-s.left-o,t.clientY-s.top-n]}Object.defineProperty(t,"__esModule",{value:!0}),t.getCoordsRelativeToElement=i,t.getCoords=function(e,t,s,r,o,n,a,h,l){if(!n)return;const c=i(e,t,s);return c[0]=Math.ceil((c[0]+(l?a/2:0))/a),c[1]=Math.ceil(c[1]/h),c[0]=Math.min(Math.max(c[0],1),r+(l?1:0)),c[1]=Math.min(Math.max(c[1],1),o),c}},9686(e,t){function i(e,t,i,o){const h=e-s(e,i),l=t-s(t,i),c=Math.abs(h-l)-function(e,t,i){let o=0;const n=e-s(e,i),a=t-s(t,i);for(let s=0;s=0&&et?"A":"B"}function o(e,t,i,s,r,o){let n=e,a=t,h="";for(;(n!==i||a!==s)&&a>=0&&ao.cols-1?(h+=o.buffer.translateBufferLineToString(a,!1,e,n),n=0,e=0,a++):!r&&n<0&&(h+=o.buffer.translateBufferLineToString(a,!1,0,e+1),n=o.cols-1,e=n,a--);return h+o.buffer.translateBufferLineToString(a,!1,e,n)}function n(e,t){return""+(t?"O":"[")+e}function a(e,t){e=Math.floor(e);let i="";for(let s=0;s0?h-s(h,l):t;const _=h,u=function(e,t,r,o,n,a){let h;return h=i(t,o,n,a).length>0?o-s(o,n):t,e=r&&he?"D":"C",a(Math.abs(l-e),n(d,h));d=c>t?"D":"C";const _=Math.abs(c-t);return a(function(e,t){return t.cols-e}(c>t?e:l,r)+(_-1)*r.cols+1+((c>t?l:e)-1),n(d,h))}},6081(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._core.options[e],i=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(const e in this._core.options){const s={get:t.bind(this,e),set:i.bind(this,e)};Object.defineProperty(this._publicOptions,e,s)}}_checkReadonlyOptions(e){if(f.includes(e))throw new Error(`Option "${e}" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw new Error("You must set the allowProposedApi option to true to use proposed API")}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get onDimensionsChange(){return this._core.onDimensionsChange}get element(){return this._core.element}get screenElement(){return this._core.screenElement}get parser(){return this._parser??=new _.ParserApi(this._core)}get unicode(){return this._checkProposedApi(),new u.UnicodeApi(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer??=this._register(new d.BufferNamespaceApi(this._core))}get markers(){return this._core.markers}get modes(){const e=this._core.coreService.decPrivateModes;let t="none";switch(this._core.mouseStateService.activeProtocol){case"X10":t="x10";break;case"VT200":t="vt200";break;case"DRAG":t="drag";break;case"ANY":t="any"}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,showCursor:!this._core.coreService.isCursorHidden,synchronizedOutputMode:e.synchronizedOutput,win32InputMode:e.win32InputMode,wraparoundMode:e.wraparound}}get dimensions(){return this._core.dimensions}get options(){return this._publicOptions}set options(e){for(const t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}input(e,t=!0){this._core.input(e,t)}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}attachCustomWheelEventHandler(e){this._core.attachCustomWheelEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){return this._verifyPositiveIntegers(e.x??0,e.width??0,e.height??0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,i){this._verifyIntegers(e,t,i),this._core.select(e,t,i)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write("\r\n",t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return{get promptLabel(){return a.promptLabel.get()},set promptLabel(e){a.promptLabel.set(e)},get tooMuchOutput(){return a.tooMuchOutput.get()},set tooMuchOutput(e){a.tooMuchOutput.set(e)}}}_verifyIntegers(...e){for(p of e)if(p===1/0||isNaN(p)||p%1!=0)throw new Error("This API only accepts integers")}_verifyPositiveIntegers(...e){for(p of e)if(p&&(p===1/0||isNaN(p)||p%1!=0||p<0))throw new Error("This API only accepts positive integers")}}t.Terminal=v},3955(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRenderer=void 0;const o=i(1433),n=i(2744),a=i(9176),h=i(6181),l=i(2274),c=i(654),d=i(7098),_=i(4103),u=i(4812),f=i(6501),p=i(8636),v=i(4159);let g=1,m=class extends u.Disposable{constructor(e,t,i,s,r,a,d,_,f,m,b,w,y,C){super(),this._terminal=e,this._document=t,this._element=i,this._screenElement=s,this._viewportElement=r,this._helperContainer=a,this._linkifier2=d,this._charSizeService=f,this._optionsService=m,this._bufferService=b,this._coreService=w,this._coreBrowserService=y,this._themeService=C,this._terminalClass=g++,this._rowElements=[],this._selectionRenderModel=(0,l.createSelectionRenderModel)(),this._lastSelectionColumnMode=!1,this._rowHasBlinkingCells=[],this._rowHasBlinkingCellsCount=0,this._onRequestRedraw=this._register(new p.Emitter),this.onRequestRedraw=this._onRequestRedraw.event,this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=(0,h.createRenderDimensions)(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(e=>this._injectCss(e))),this._injectCss(this._themeService.colors),this._rowFactory=_.createInstance(o.DomRendererRowFactory,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(e=>this._handleLinkHover(e))),this._register(this._linkifier2.onHideLinkUnderline(e=>this._handleLinkLeave(e))),this._cursorBlinkStateManager=new S(this._rowContainer,this._coreBrowserService),this._register((0,v.addDisposableListener)(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register((0,u.toDisposable)(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new c.TextBlinkStateManager(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register((0,u.toDisposable)(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new n.WidthCache,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){const e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(const e of this._rowElements)e.style.width=`${this.dimensions.css.canvas.width}px`,e.style.height=`${this.dimensions.css.cell.height}px`,e.style.lineHeight=`${this.dimensions.css.cell.height}px`,e.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));const t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${_.color.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;const i=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,r=`blink_block_${this._terminalClass}`;t+=`@keyframes ${i} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${r} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${i} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(const[i,s]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${i} { color: ${s.css}; }${this._terminalSelector} .xterm-fg-${i}.xterm-dim { color: ${_.color.multiplyOpacity(s,.5).css}; }${this._terminalSelector} .xterm-bg-${i} { background-color: ${s.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR} { color: ${_.color.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR}.xterm-dim { color: ${_.color.multiplyOpacity(_.color.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${a.INVERTED_DEFAULT_COLOR} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){const e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let e=this._rowElements.length;e<=t;e++){const e=this._document.createElement("div");this._rowContainer.appendChild(e),this._rowElements.push(e),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,i){const s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,i);let r=0,o=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(r=this._selectionRenderModel.viewportCappedStartRow,o=this._selectionRenderModel.viewportCappedEndRow));let n=0,a=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,i),this._selectionRenderModel.hasSelection){const s=this._selectionRenderModel.viewportStartRow,r=this._selectionRenderModel.viewportEndRow,o=this._selectionRenderModel.viewportCappedStartRow,h=this._selectionRenderModel.viewportCappedEndRow;n=o,a=h;const l=this._document.createDocumentFragment();if(i){const i=e[0]>t[0];l.appendChild(this._createSelectionElement(o,i?t[0]:e[0],i?e[0]:t[0],h-o+1))}else{const i=s===o?e[0]:0,n=o===r?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(o,i,n));const a=h-o-1;if(l.appendChild(this._createSelectionElement(o+1,0,this._bufferService.cols,a)),o!==h){const e=r===h?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(h,0,e))}}this._selectionContainer.appendChild(l)}let h=Math.min(r,n),l=Math.max(o,a);if(l>=0){h=Math.max(h,0),l=Math.min(l,s-1);const e=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&e>=0&&ethis.dimensions.css.canvas.width&&(n=this.dimensions.css.canvas.width-o),r.style.height=s*this.dimensions.css.cell.height+"px",r.style.top=e*this.dimensions.css.cell.height+"px",r.style.left=`${o}px`,r.style.width=`${n}px`,r}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(const e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){const i=this._bufferService.buffer,s=i.ybase+i.y,r=Math.min(i.x,this._bufferService.cols-1),o=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,n=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,a=this._optionsService.rawOptions.cursorInactiveStyle,h={hasBlinkingCells:!1};for(let l=e;l<=t;l++){const e=l+i.ydisp,t=this._rowElements[l];if(!t)continue;const c=i.lines.get(e);c?(t.replaceChildren(...this._rowFactory.createRow(c,e,e===s,n,a,r,o,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,h)),this._setRowBlinkState(l,h.hasBlinkingCells)):(t.replaceChildren(),this._setRowBlinkState(l,!1))}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,i,s,r,o){i<0&&(e=0),s<0&&(t=0);const n=this._bufferService.rows-1;i=Math.max(Math.min(i,n),0),s=Math.max(Math.min(s,n),0),r=Math.min(r,this._bufferService.cols);const a=this._bufferService.buffer,h=a.ybase+a.y,l=Math.min(a.x,r-1),c=this._optionsService.rawOptions.cursorBlink,d=this._optionsService.rawOptions.cursorStyle,_=this._optionsService.rawOptions.cursorInactiveStyle,u={hasBlinkingCells:!1};for(let n=i;n<=s;++n){const f=n+a.ydisp,p=this._rowElements[n];if(!p)continue;const v=a.lines.get(f);v?(p.replaceChildren(...this._rowFactory.createRow(v,f,f===h,d,_,l,c,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,o?n===i?e:0:-1,o?(n===s?t:r)-1:-1,u)),this._setRowBlinkState(n,u.hasBlinkingCells)):(p.replaceChildren(),this._setRowBlinkState(n,!1))}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};t.DomRenderer=m,t.DomRenderer=m=s([r(7,f.IInstantiationService),r(8,d.ICharSizeService),r(9,f.IOptionsService),r(10,f.IBufferService),r(11,f.ICoreService),r(12,d.ICoreBrowserService),r(13,d.IThemeService)],m);class S{constructor(e,t){this._rowContainer=e,this._coreBrowserService=t,this._isIdlePaused=!1,this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){void 0!==this._idleTimeout&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}}},1433(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRendererRowFactory=void 0;const o=i(9176),n=i(8938),a=i(3055),h=i(6501),l=i(4103),c=i(7098),d=i(945),_=i(6181),u=i(5451);let f=class{constructor(e,t,i,s,r,o,n){this._document=e,this._characterJoinerService=t,this._optionsService=i,this._coreBrowserService=s,this._coreService=r,this._decorationService=o,this._themeService=n,this._workCell=new a.CellData,this._columnSelectMode=!1,this.defaultSpacing=0}handleSelectionChanged(e,t,i){this._selectionStart=e,this._selectionEnd=t,this._columnSelectMode=i}createRow(e,t,i,s,r,a,h,c,_,f,p,v,g){const m=[];g&&(g.hasBlinkingCells=!1);const S=this._characterJoinerService.getJoinedCharacters(t),b=this._themeService.colors;let w,y=e.getNoBgTrimmedLength();i&&y=A,F=I,W=this._workCell;if(S.length>0&&I===S[0][0]&&N){const s=S.shift(),r=this._isCellInSelection(s[0],t);for(C=s[0]+1;C=s[1],N?(H=!0,W=new d.JoinedCellData(this._workCell,e.translateToString(!0,s[0],s[1]),s[1]-s[0]),F=s[1]-1,y=W.getWidth()):A=s[1]}const z=this._isCellInSelection(I,t),K=i&&I===a,U=O&&I>=p&&I<=v;g&&W.isBlink()&&(g.hasBlinkingCells=!0),!c&&W.isBlink()&&P.push("xterm-blink-hidden");let j=!1;this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{j=!0});let $=W.getChars()||n.WHITESPACE_CELL_CHAR;if(" "===$&&(W.isUnderline()||W.isOverline())&&($=" "),k=y*_-f.get($,W.isBold(),W.isItalic()),w){if(D&&(z&&T||!z&&!T&&W.bg===L)&&(z&&T&&b.selectionForeground||W.fg===x)&&W.extended.ext===R&&U===M&&k===B&&!K&&!H&&!j&&N){W.isInvisible()?E+=n.WHITESPACE_CELL_CHAR:E+=$,D++;continue}D&&(w.textContent=E),w=this._document.createElement("span"),D=0,E=""}else w=this._document.createElement("span");if(L=W.bg,x=W.fg,R=W.extended.ext,M=U,B=k,T=z,H&&a>=I&&a<=F&&(a=I),!this._coreService.isCursorHidden&&K&&this._coreService.isCursorInitialized)if(P.push("xterm-cursor"),this._coreBrowserService.isFocused)h&&P.push("xterm-cursor-blink"),P.push("bar"===s?"xterm-cursor-bar":"underline"===s?"xterm-cursor-underline":"xterm-cursor-block");else if(r)switch(r){case"outline":P.push("xterm-cursor-outline");break;case"block":P.push("xterm-cursor-block");break;case"bar":P.push("xterm-cursor-bar");break;case"underline":P.push("xterm-cursor-underline")}if(W.isBold()&&P.push("xterm-bold"),W.isItalic()&&P.push("xterm-italic"),W.isDim()&&P.push("xterm-dim"),E=W.isInvisible()?n.WHITESPACE_CELL_CHAR:W.getChars()||n.WHITESPACE_CELL_CHAR,W.isUnderline()&&(P.push(`xterm-underline-${W.extended.underlineStyle}`)," "===E&&(E=" "),!W.isUnderlineColorDefault()))if(W.isUnderlineColorRGB())w.style.textDecorationColor=`rgb(${u.AttributeData.toColorRGB(W.getUnderlineColor()).join(",")})`;else{let e=W.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&W.isBold()&&e<8&&(e+=8),w.style.textDecorationColor=b.ansi[e].css}W.isOverline()&&(P.push("xterm-overline")," "===E&&(E=" ")),W.isStrikethrough()&&P.push("xterm-strikethrough"),U&&(w.style.textDecoration="underline");let q=W.getFgColor(),V=W.getFgColorMode(),X=W.getBgColor(),Y=W.getBgColorMode();const G=!!W.isInverse();if(G){const e=q;q=X,X=e;const t=V;V=Y,Y=t}let J,Z,Q,ee=!1;switch(this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{"top"!==e.options.layer&&ee||(e.backgroundColorRGB&&(Y=50331648,X=e.backgroundColorRGB.rgba>>8&16777215,J=e.backgroundColorRGB),e.foregroundColorRGB&&(V=50331648,q=e.foregroundColorRGB.rgba>>8&16777215,Z=e.foregroundColorRGB),ee="top"===e.options.layer)}),!ee&&z&&(J=this._coreBrowserService.isFocused?b.selectionBackgroundOpaque:b.selectionInactiveBackgroundOpaque,X=J.rgba>>8&16777215,Y=50331648,ee=!0,b.selectionForeground&&(V=50331648,q=b.selectionForeground.rgba>>8&16777215,Z=b.selectionForeground)),ee&&P.push("xterm-decoration-top"),Y){case 16777216:case 33554432:Q=b.ansi[X],P.push(`xterm-bg-${X}`);break;case 50331648:Q=l.channels.toColor(X>>16,X>>8&255,255&X),this._addStyle(w,`background-color:#${(X>>>0).toString(16).padStart(6,"0")}`);break;default:G?(Q=b.foreground,P.push(`xterm-bg-${o.INVERTED_DEFAULT_COLOR}`)):Q=b.background}switch(J||W.isDim()&&(J=l.color.multiplyOpacity(Q,.5)),V){case 16777216:case 33554432:W.isBold()&&q<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(q+=8),this._applyMinimumContrast(w,Q,b.ansi[q],W,J,void 0)||P.push(`xterm-fg-${q}`);break;case 50331648:const e=l.channels.toColor(q>>16&255,q>>8&255,255&q);this._applyMinimumContrast(w,Q,e,W,J,Z)||this._addStyle(w,`color:#${q.toString(16).padStart(6,"0")}`);break;default:this._applyMinimumContrast(w,Q,b.foreground,W,J,Z)||G&&P.push(`xterm-fg-${o.INVERTED_DEFAULT_COLOR}`)}P.length&&(w.className=P.join(" "),P.length=0),K||H||j||!N?w.textContent=E:D++,k!==this.defaultSpacing&&(w.style.letterSpacing=`${k}px`),m.push(w),I=F}return w&&D&&(w.textContent=E),m}_applyMinimumContrast(e,t,i,s,r,o){if(1===this._optionsService.rawOptions.minimumContrastRatio||(0,_.treatGlyphAsBackgroundColor)(s.getCode()))return!1;const n=this._getContrastCache(s);let a;if(r||o||(a=n.getColor(t.rgba,i.rgba)),void 0===a){const e=this._optionsService.rawOptions.minimumContrastRatio/(s.isDim()?2:1);a=l.color.ensureContrastRatio(r??t,o??i,e),n.setColor((r??t).rgba,(o??i).rgba,a??null)}return!!a&&(this._addStyle(e,`color:${a.css}`),!0)}_getContrastCache(e){return e.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(e,t){e.setAttribute("style",`${e.getAttribute("style")||""}${t};`)}_isCellInSelection(e,t){const i=this._selectionStart,s=this._selectionEnd;return!(!i||!s)&&(this._columnSelectMode?i[0]<=s[0]?e>=i[0]&&t>=i[1]&&e=i[1]&&e>=s[0]&&t<=s[1]:t>i[1]&&t=i[0]&&e=i[0])}};t.DomRendererRowFactory=f,t.DomRendererRowFactory=f=s([r(1,c.ICharacterJoinerService),r(2,h.IOptionsService),r(3,c.ICoreBrowserService),r(4,h.ICoreService),r(5,h.IDecorationService),r(6,c.IThemeService)],f)},2744(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WidthCache=void 0;const s=i(6181);t.WidthCache=class{constructor(e=()=>new r){this._flat=new Float32Array(256),this._font="",this._fontSize=0,this._weight="normal",this._weightBold="bold",this._canvasElements=[],this._canvasElements=[e(),e(),e(),e()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(e,t,i,s){e===this._font&&t===this._fontSize&&i===this._weight&&s===this._weightBold||(this._font=e,this._fontSize=t,this._weight=i,this._weightBold=s,this._canvasElements[0].setFont(e,t,i,!1),this._canvasElements[1].setFont(e,t,s,!1),this._canvasElements[2].setFont(e,t,i,!0),this._canvasElements[3].setFont(e,t,s,!0),this.clear())}get(e,t,i){let s;if(!t&&!i&&1===e.length&&(s=e.charCodeAt(0))<256){if(-9999!==this._flat[s])return this._flat[s];const t=this._measure(e,0);return t>0&&(this._flat[s]=t),t}let r=e;t&&(r+="B"),i&&(r+="I");let o=this._holey.get(r);if(void 0===o){let s=0;t&&(s|=1),i&&(s|=2),o=this._measure(e,s),o>0&&this._holey.set(r,o)}return o}_measure(e,t){return this._canvasElements[t].measure(e)}};class r{constructor(){"undefined"!=typeof OffscreenCanvas?(this._canvas=new OffscreenCanvas(1,1),this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d")))}setFont(e,t,i,s){const r=s?"italic":"";this._ctx.font=`${r} ${i} ${t}px ${e}`.trim()}measure(e){return this._ctx.measureText(e).width}}},9176(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.INVERTED_DEFAULT_COLOR=void 0,t.INVERTED_DEFAULT_COLOR=257},6181(e,t){function i(e){return 57508<=e&&e<=57558}function s(e){return e>=128512&&e<=128591||e>=127744&&e<=128511||e>=128640&&e<=128767||e>=9728&&e<=9983||e>=9984&&e<=10175||e>=65024&&e<=65039||e>=129280&&e<=129535||e>=127462&&e<=127487}Object.defineProperty(t,"__esModule",{value:!0}),t.throwIfFalsy=function(e){if(!e)throw new Error("value must not be falsy");return e},t.isPowerlineGlyph=i,t.isRestrictedPowerlineGlyph=function(e){return 57520<=e&&e<=57527},t.isEmoji=s,t.allowRescaling=function(e,t,r,o){return 1===t&&r>Math.ceil(1.5*o)&&void 0!==e&&e>255&&!s(e)&&!i(e)&&!function(e){return 57344<=e&&e<=63743}(e)},t.treatGlyphAsBackgroundColor=function(e){return i(e)||function(e){return 9472<=e&&e<=9631}(e)},t.createRenderDimensions=function(){return{css:{canvas:{width:0,height:0},cell:{width:0,height:0}},device:{canvas:{width:0,height:0},cell:{width:0,height:0},char:{width:0,height:0,left:0,top:0}}}},t.computeNextVariantOffset=function(e,t,i=0){return(e-(2*Math.round(t)-i))%(2*Math.round(t))}},2274(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.createSelectionRenderModel=function(){return new i};class i{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(e,t,i,s=!1){if(this.selectionStart=t,this.selectionEnd=i,!t||!i||t[0]===i[0]&&t[1]===i[1])return void this.clear();const r=e.buffers.active.ydisp,o=t[1]-r,n=i[1]-r,a=Math.max(o,0),h=Math.min(n,e.rows-1);a>=e.rows||h<0?this.clear():(this.hasSelection=!0,this.columnSelectMode=s,this.viewportStartRow=o,this.viewportEndRow=n,this.viewportCappedStartRow=a,this.viewportCappedEndRow=h,this.startCol=t[0],this.endCol=i[0])}isCellSelected(e,t,i){return!!this.hasSelection&&(i-=e.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?t>=this.startCol&&i>=this.viewportCappedStartRow&&t=this.viewportCappedStartRow&&t>=this.endCol&&i<=this.viewportCappedEndRow:i>this.viewportStartRow&&i=this.startCol&&t=this.startCol)}}},654(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TextBlinkStateManager=void 0;const s=i(4812);class r extends s.Disposable{constructor(e,t,i){super(),this._renderCallback=e,this._coreBrowserService=t,this._optionsService=i,this._intervalDuration=0,this._blinkOn=!0,this._needsBlinkInViewport=!1,this._isViewportVisible=!0,this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",e=>{this.setIntervalDuration(e)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register((0,s.toDisposable)(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(void 0!==this._interval)return;const e=this._blinkOn;return this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),void(e||this._renderCallback())}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){void 0!==this._interval&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}}t.TextBlinkStateManager=r},8501(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._domNodePointerDown(e)))}_createArrow(e){const t=this._register(new c.ScrollbarArrow(e));return this.domNode.domNode.appendChild(t.bgDomNode),this.domNode.domNode.appendChild(t.domNode),t}_createSlider(e,t,i,s){this.slider=new h.FastDomNode(document.createElement("div")),this.slider.setClassName("xterm-slider"),this.slider.setPosition("absolute"),this.slider.setTop(e),this.slider.setLeft(t),"number"==typeof i&&this.slider.setWidth(i),"number"==typeof s&&this.slider.setHeight(s),this.slider.setLayerHinting(!0),this.slider.setContain("strict"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(a.addDisposableListener(this.slider.domNode,a.eventType.POINTER_DOWN,e=>{0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))})),this._onclick(this.slider.domNode,e=>{e.leftButton&&e.stopPropagation()})}_handleElementSize(e){return this._scrollbarState.setVisibleSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollSize(e){return this._scrollbarState.setScrollSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollPosition(e){return this._scrollbarState.setScrollPosition(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(e){e.target===this.domNode.domNode&&this._handlePointerDown(e)}delegatePointerDown(e){const t=this.domNode.domNode.getClientRects()[0].top,i=t+this._scrollbarState.getSliderPosition(),s=t+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),r=this._sliderPointerPosition(e);i<=r&&r<=s?0===e.button&&(e.preventDefault(),this._sliderPointerDown(e)):this._handlePointerDown(e)}_handlePointerDown(e){let t,i;if(e.target===this.domNode.domNode&&"number"==typeof e.offsetX&&"number"==typeof e.offsetY)t=e.offsetX,i=e.offsetY;else{const s=a.getDomNodePagePosition(this.domNode.domNode);t=e.pageX-s.left,i=e.pageY-s.top}const s=this._pointerDownRelativePosition(t,i);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(s):this._scrollbarState.getDesiredScrollPositionFromOffset(s)),0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))}_sliderPointerDown(e){if(!(e.target&&e.target instanceof Element))return;const t=this._sliderPointerPosition(e),i=this._sliderOrthogonalPointerPosition(e),s=this._scrollbarState.clone();this.slider.toggleClassName("xterm-active",!0),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{const r=this._sliderOrthogonalPointerPosition(e),o=Math.abs(r-i);if(u.isWindows&&o>140)return void this._setDesiredScrollPositionNow(s.getScrollPosition());const n=this._sliderPointerPosition(e)-t;this._setDesiredScrollPositionNow(s.getDesiredScrollPositionFromDelta(n))},()=>{this.slider.toggleClassName("xterm-active",!1),this._host.handleDragEnd()}),this._host.handleDragStart()}_setDesiredScrollPositionNow(e){const t={};this.writeScrollPosition(t,e),this._scrollable.setScrollPositionNow(t)}updateScrollbarSize(e){this._updateScrollbarSize(e),this._scrollbarState.setScrollbarSize(e),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}}t.AbstractScrollbar=f},1203(e,t){function i(e){return"number"==typeof e?`${e}px`:e}Object.defineProperty(t,"__esModule",{value:!0}),t.FastDomNode=void 0,t.FastDomNode=class{constructor(e){this.domNode=e,this._width="",this._height="",this._top="",this._left="",this._bottom="",this._right="",this._className="",this._position="",this._layerHint=!1,this._contain="none"}setWidth(e){const t=i(e);this._width!==t&&(this._width=t,this.domNode.style.width=this._width)}setHeight(e){const t=i(e);this._height!==t&&(this._height=t,this.domNode.style.height=this._height)}setTop(e){const t=i(e);this._top!==t&&(this._top=t,this.domNode.style.top=this._top)}setLeft(e){const t=i(e);this._left!==t&&(this._left=t,this.domNode.style.left=this._left)}setBottom(e){const t=i(e);this._bottom!==t&&(this._bottom=t,this.domNode.style.bottom=this._bottom)}setRight(e){const t=i(e);this._right!==t&&(this._right=t,this.domNode.style.right=this._right)}setClassName(e){this._className!==e&&(this._className=e,this.domNode.className=this._className)}toggleClassName(e,t){this.domNode.classList.toggle(e,t),this._className=this.domNode.className}setPosition(e){this._position!==e&&(this._position=e,this.domNode.style.position=this._position)}setLayerHinting(e){this._layerHint!==e&&(this._layerHint=e,this.domNode.style.transform=e?"translate3d(0px, 0px, 0px)":"")}setContain(e){this._contain!==e&&(this._contain=e,this.domNode.style.contain=this._contain)}setAttribute(e,t){this.domNode.setAttribute(e,t)}}},928(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{try{e.releasePointerCapture(t)}catch{}}))}catch{o=a.getWindow(e)}this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_MOVE,e=>{e.buttons===i?(e.preventDefault(),this._pointerMoveCallback(e)):this.stopMonitoring(!0)})),this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_UP,e=>this.stopMonitoring(!0)))}}},9699(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.HorizontalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition();if(super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(t.horizontalHasArrows?t.horizontalScrollbarSize:0,2===t.horizontal?0:t.horizontalScrollbarSize,2===t.vertical?0:t.verticalScrollbarSize,s.width,s.scrollWidth,o.scrollLeft),visibility:t.horizontal,extraScrollbarClassName:"xterm-horizontal",scrollable:e,scrollByPage:t.scrollByPage}),t.horizontalHasArrows)throw new Error("horizontalHasArrows is not supported in xterm.js");this._createSlider(Math.floor((t.horizontalScrollbarSize-t.horizontalSliderSize)/2),0,void 0,t.horizontalSliderSize)}_updateSlider(e,t){this.slider.setWidth(e),this.slider.setLeft(t)}_renderDomNode(e,t){this.domNode.setWidth(e),this.domNode.setHeight(t),this.domNode.setLeft(0),this.domNode.setBottom(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollWidth)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollLeft)||this._shouldRender,this._shouldRender=this._handleElementSize(e.width)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return e}_sliderPointerPosition(e){return e.pageX}_sliderOrthogonalPointerPosition(e){return e.pageY}_updateScrollbarSize(e){this.slider.setHeight(e)}writeScrollPosition(e,t){e.scrollLeft=t}updateOptions(e){this.updateScrollbarSize(2===e.horizontal?0:e.horizontalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._visibilityController.setVisibility(e.horizontal),this._scrollByPage=e.scrollByPage}}t.HorizontalScrollbar=o},3988(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;ni&&(s=i-t),s<0&&(s=0),r<0&&(r=0),n+r>o&&(n=o-r),n<0&&(n=0),this.width=t,this.scrollWidth=i,this.scrollLeft=s,this.height=r,this.scrollHeight=o,this.scrollTop=n}equals(e){return this.rawScrollLeft===e.rawScrollLeft&&this.rawScrollTop===e.rawScrollTop&&this.width===e.width&&this.scrollWidth===e.scrollWidth&&this.scrollLeft===e.scrollLeft&&this.height===e.height&&this.scrollHeight===e.scrollHeight&&this.scrollTop===e.scrollTop}withScrollDimensions(e,t){return new o(this._forceIntegerValues,void 0!==e.width?e.width:this.width,void 0!==e.scrollWidth?e.scrollWidth:this.scrollWidth,t?this.rawScrollLeft:this.scrollLeft,void 0!==e.height?e.height:this.height,void 0!==e.scrollHeight?e.scrollHeight:this.scrollHeight,t?this.rawScrollTop:this.scrollTop)}withScrollPosition(e){return new o(this._forceIntegerValues,this.width,this.scrollWidth,void 0!==e.scrollLeft?e.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,void 0!==e.scrollTop?e.scrollTop:this.rawScrollTop)}createScrollEvent(e,t){const i=this.width!==e.width,s=this.scrollWidth!==e.scrollWidth,r=this.scrollLeft!==e.scrollLeft,o=this.height!==e.height,n=this.scrollHeight!==e.scrollHeight,a=this.scrollTop!==e.scrollTop;return{inSmoothScrolling:t,oldWidth:e.width,oldScrollWidth:e.scrollWidth,oldScrollLeft:e.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:e.height,oldScrollHeight:e.scrollHeight,oldScrollTop:e.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:i,scrollWidthChanged:s,scrollLeftChanged:r,heightChanged:o,scrollHeightChanged:n,scrollTopChanged:a}}}t.ScrollState=o;class n extends r.Disposable{constructor(e){super(),this._scrollableBrand=void 0,this._onScroll=this._register(new s.Emitter),this.onScroll=this._onScroll.event,this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new o(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){const i=this._state.withScrollDimensions(e,t);this._setState(i,Boolean(this._smoothScrolling)),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){const t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(0!==this._smoothScrollDuration){if(this._smoothScrolling){e={scrollLeft:void 0===e.scrollLeft?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:void 0===e.scrollTop?this._smoothScrolling.to.scrollTop:e.scrollTop};const i=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===i.scrollLeft&&this._smoothScrolling.to.scrollTop===i.scrollTop)return;let s;s=t?new l(this._smoothScrolling.from,i,this._smoothScrolling.startTime,this._smoothScrolling.duration):l.start(this._state,i,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{const t=this._state.withScrollPosition(e);this._smoothScrolling=l.start(this._state,t,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}else this.setScrollPositionNow(e)}hasPendingScrollAnimation(){return Boolean(this._smoothScrolling)}_performSmoothScrolling(){if(!this._smoothScrolling)return;const e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);return this._setState(t,!0),this._smoothScrolling?e.isDone?(this._smoothScrolling.dispose(),void(this._smoothScrolling=null)):void(this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})):void 0}_setState(e,t){const i=this._state;i.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(i,t)))}}t.Scrollable=n;class a{constructor(e,t,i){this.scrollLeft=e,this.scrollTop=t,this.isDone=i}}function h(e,t){const i=t-e;return function(t){return e+i*(1-(s=1-t,Math.pow(s,3)));var s}}class l{constructor(e,t,i,s){this.from=e,this.to=t,this.duration=s,this.startTime=i,this.animationFrameDisposable=null,this._initAnimations()}_initAnimations(){this._scrollLeft=this._initAnimation(this.from.scrollLeft,this.to.scrollLeft,this.to.width),this._scrollTop=this._initAnimation(this.from.scrollTop,this.to.scrollTop,this.to.height)}_initAnimation(e,t,i){if(Math.abs(e-t)>2.5*i){let n,a;return e0&&Math.abs(e.deltaY)>0)return 1;let i=.5;if(this._isAlmostInt(e.deltaX)&&this._isAlmostInt(e.deltaY)||(i+=.25),t){const s=Math.abs(e.deltaX),r=Math.abs(e.deltaY),o=Math.abs(t.deltaX),n=Math.abs(t.deltaY),a=Math.max(Math.min(s,o),1),h=Math.max(Math.min(r,n),1),l=Math.max(s,o),c=Math.max(r,n);l%a===0&&c%h===0&&(i-=.5)}return Math.min(Math.max(i,0),1)}_isAlmostInt(e){return Math.abs(Math.round(e)-e)<.01}}S.INSTANCE=new S;class b extends _.Widget{get options(){return this._options}constructor(e,t,i){let s;super(),this._onScroll=this._register(new f.Emitter),this.onScroll=this._onScroll.event,t=t??{};const r=!i;i?s=i:(t.mouseWheelSmoothScroll=!1,s=new g.Scrollable({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:t=>a.scheduleAtNextAnimationFrame(a.getWindow(e),t)})),this._options=function(e){const t={lazyRender:void 0!==e.lazyRender&&e.lazyRender,className:void 0!==e.className?e.className:"",useShadows:void 0===e.useShadows||e.useShadows,handleMouseWheel:void 0===e.handleMouseWheel||e.handleMouseWheel,flipAxes:void 0!==e.flipAxes&&e.flipAxes,consumeMouseWheelIfScrollbarIsNeeded:void 0!==e.consumeMouseWheelIfScrollbarIsNeeded&&e.consumeMouseWheelIfScrollbarIsNeeded,alwaysConsumeMouseWheel:void 0!==e.alwaysConsumeMouseWheel&&e.alwaysConsumeMouseWheel,scrollYToX:void 0!==e.scrollYToX&&e.scrollYToX,mouseWheelScrollSensitivity:void 0!==e.mouseWheelScrollSensitivity?e.mouseWheelScrollSensitivity:1,fastScrollSensitivity:void 0!==e.fastScrollSensitivity?e.fastScrollSensitivity:5,scrollPredominantAxis:void 0===e.scrollPredominantAxis||e.scrollPredominantAxis,mouseWheelSmoothScroll:void 0===e.mouseWheelSmoothScroll||e.mouseWheelSmoothScroll,listenOnDomNode:void 0!==e.listenOnDomNode?e.listenOnDomNode:null,horizontal:void 0!==e.horizontal?e.horizontal:1,horizontalScrollbarSize:void 0!==e.horizontalScrollbarSize?e.horizontalScrollbarSize:10,horizontalSliderSize:void 0!==e.horizontalSliderSize?e.horizontalSliderSize:0,horizontalHasArrows:void 0!==e.horizontalHasArrows&&e.horizontalHasArrows,vertical:void 0!==e.vertical?e.vertical:1,verticalScrollbarSize:void 0!==e.verticalScrollbarSize?e.verticalScrollbarSize:10,verticalHasArrows:void 0!==e.verticalHasArrows&&e.verticalHasArrows,verticalSliderSize:void 0!==e.verticalSliderSize?e.verticalSliderSize:0,scrollByPage:void 0!==e.scrollByPage&&e.scrollByPage};return t.horizontalSliderSize=void 0!==e.horizontalSliderSize?e.horizontalSliderSize:t.horizontalScrollbarSize,t.verticalSliderSize=void 0!==e.verticalSliderSize?e.verticalSliderSize:t.verticalScrollbarSize,v.isMac&&(t.className+=" xterm-mac"),t}(t),this._scrollable=s,this._register(this._scrollable.onScroll(e=>{this._handleScroll(e),this._onScroll.fire(e)})),r&&this._register(this._scrollable);const o={handleMouseWheel:e=>this._handleMouseWheel(e),handleDragStart:()=>this._handleDragStart(),handleDragEnd:()=>this._handleDragEnd()};this._verticalScrollbar=this._register(new d.VerticalScrollbar(this._scrollable,this._options,o)),this._horizontalScrollbar=this._register(new c.HorizontalScrollbar(this._scrollable,this._options,o)),this._domNode=document.createElement("div"),this._domNode.className="xterm-scrollable-element "+this._options.className,this._domNode.setAttribute("role","presentation"),this._domNode.style.position="relative",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._leftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topLeftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode??this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this._onmouseover(this._listenOnDomNode,e=>this._handleMouseOver(e)),this._onmouseleave(this._listenOnDomNode,e=>this._handleMouseLeave(e)),this._hideTimeout=this._register(new u.TimeoutTimer),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}dispose(){this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}updateClassName(e){this._options.className=e,v.isMac&&(this._options.className+=" xterm-mac"),this._domNode.className="xterm-scrollable-element "+this._options.className}updateOptions(e){void 0!==e.handleMouseWheel&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),void 0!==e.mouseWheelScrollSensitivity&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),void 0!==e.fastScrollSensitivity&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),void 0!==e.scrollPredominantAxis&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),void 0!==e.horizontal&&(this._options.horizontal=e.horizontal),void 0!==e.vertical&&(this._options.vertical=e.vertical),void 0!==e.horizontalHasArrows&&(this._options.horizontalHasArrows=e.horizontalHasArrows),void 0!==e.verticalHasArrows&&(this._options.verticalHasArrows=e.verticalHasArrows),void 0!==e.horizontalScrollbarSize&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),void 0!==e.verticalScrollbarSize&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),void 0!==e.scrollByPage&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}delegateScrollFromMouseWheelEvent(e){this._handleMouseWheel(new l.StandardWheelEvent(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),e)){const e=e=>{this._handleMouseWheel(new l.StandardWheelEvent(e))};this._mouseWheelToDispose.push(a.addDisposableListener(this._listenOnDomNode,a.eventType.MOUSE_WHEEL,e,{passive:!1}))}}_handleMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;const t=S.INSTANCE;t.acceptStandardWheelEvent(e);let i=!1;if(e.deltaY||e.deltaX){let s=e.deltaY*this._options.mouseWheelScrollSensitivity,r=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&r+s===0?r=s=0:Math.abs(s)>=Math.abs(r)?r=0:s=0),this._options.flipAxes&&([s,r]=[r,s]);const o=!v.isMac&&e.browserEvent&&e.browserEvent.shiftKey;!this._options.scrollYToX&&!o||r||(r=s,s=0),e.browserEvent&&e.browserEvent.altKey&&(r*=this._options.fastScrollSensitivity,s*=this._options.fastScrollSensitivity);const n=this._scrollable.getFutureScrollPosition();let a={};if(s){const e=50*s,t=n.scrollTop-(e<0?Math.floor(e):Math.ceil(e));this._verticalScrollbar.writeScrollPosition(a,t)}if(r){const e=50*r,t=n.scrollLeft-(e<0?Math.floor(e):Math.ceil(e));this._horizontalScrollbar.writeScrollPosition(a,t)}a=this._scrollable.validateScrollPosition(a),(n.scrollLeft!==a.scrollLeft||n.scrollTop!==a.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(a):this._scrollable.setScrollPositionNow(a),i=!0)}let s=i;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_handleScroll(e){this._shouldRender=this._horizontalScrollbar.handleScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.handleScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error("Please use `lazyRender` together with `renderNow`!");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){const e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,i=e.scrollLeft>0,s=i?" xterm-shadow-left":"",r=t?" xterm-shadow-top":"",o=i||t?" xterm-shadow-top-left-corner":"";this._leftShadowDomNode.setClassName(`xterm-shadow${s}`),this._topShadowDomNode.setClassName(`xterm-shadow${r}`),this._topLeftShadowDomNode.setClassName(`xterm-shadow${o}${r}${s}`)}}_handleDragStart(){this._isDragging=!0,this._reveal()}_handleDragEnd(){this._isDragging=!1,this._hide()}_handleMouseLeave(e){this._mouseIsOver=!1,this._hide()}_handleMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){this._mouseIsOver||this._isDragging||(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){this._mouseIsOver||this._isDragging||this._hideTimeout.cancelAndSet(()=>this._hide(),500)}}t.SmoothScrollableElement=b},9594(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._arrowPointerDown(e))),this._register(c.addStandardDisposableListener(this.domNode,c.eventType.POINTER_DOWN,e=>this._arrowPointerDown(e))),this._pointerdownRepeatTimer=this._register(new c.WindowIntervalTimer),this._pointerdownScheduleRepeatTimer=this._register(new l.TimeoutTimer)}_arrowPointerDown(e){e.target&&e.target instanceof Element&&(this._handleActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet(()=>{this._pointerdownRepeatTimer.cancelAndSet(()=>this._handleActivate(),1e3/24,c.getWindow(e))},200),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{},()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()}),e.preventDefault())}}t.ScrollbarArrow=d},1270(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ScrollbarState=void 0;class i{constructor(e,t,i,s,r,o){this._scrollbarSize=Math.round(t),this._oppositeScrollbarSize=Math.round(i),this._arrowSize=Math.round(e),this._visibleSize=s,this._scrollSize=r,this._scrollPosition=o,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new i(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(e){const t=Math.round(e);return this._visibleSize!==t&&(this._visibleSize=t,this._refreshComputedValues(),!0)}setScrollSize(e){const t=Math.round(e);return this._scrollSize!==t&&(this._scrollSize=t,this._refreshComputedValues(),!0)}setScrollPosition(e){const t=Math.round(e);return this._scrollPosition!==t&&(this._scrollPosition=t,this._refreshComputedValues(),!0)}setScrollbarSize(e){this._scrollbarSize=Math.round(e)}setArrowSize(e){const t=Math.round(e);this._arrowSize!==t&&(this._arrowSize=t,this._refreshComputedValues())}setOppositeScrollbarSize(e){this._oppositeScrollbarSize=Math.round(e)}static _computeValues(e,t,i,s,r){const o=Math.max(0,i-e),n=Math.max(0,o-2*t),a=s>0&&s>i;if(!a)return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(n),computedSliderRatio:0,computedSliderPosition:0};const h=Math.round(Math.max(20,Math.floor(i*n/s))),l=(n-h)/(s-i),c=r*l;return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(h),computedSliderRatio:l,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){const e=i._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=e.computedAvailableSize,this._computedIsNeeded=e.computedIsNeeded,this._computedSliderSize=e.computedSliderSize,this._computedSliderRatio=e.computedSliderRatio,this._computedSliderPosition=e.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize-this._computedSliderSize/2;return Math.round(t/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize;let i=this._scrollPosition;return t{this._domNode?.setClassName(this._visibleClassName)},0))}_hide(e){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(e?" xterm-fade":"")))}}t.ScrollbarVisibilityController=o},2650(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{s||(s=!0,this._remove(i))}}_remove(e){if(e.prev!==_.Undefined&&e.next!==_.Undefined){const t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===_.Undefined&&e.next===_.Undefined?(this._first=_.Undefined,this._last=_.Undefined):e.next===_.Undefined?(this._last=this._last.prev,this._last.next=_.Undefined):e.prev===_.Undefined&&(this._first=this._first.next,this._first.prev=_.Undefined)}*[Symbol.iterator](){let e=this._first;for(;e!==_.Undefined;)yield e.element,e=e.next}}var f;!function(e){e.TAP="-xterm-gesturetap",e.CHANGE="-xterm-gesturechange",e.START="-xterm-gesturestart",e.END="-xterm-gesturesend",e.CONTEXT_MENU="-xterm-gesturecontextmenu"}(f||(t.EventType=f={}));class p extends l.Disposable{constructor(){super(),this._dispatched=!1,this._targets=new u,this._ignoreTargets=new u,this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;const e=c;this._register(h.addDisposableListener(e.document,"touchstart",e=>this._handleTouchStart(e),{passive:!1})),this._register(h.addDisposableListener(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(h.addDisposableListener(e.document,"touchmove",e=>this._handleTouchMove(e),{passive:!1}))}static addTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._targets.push(e);return(0,l.toDisposable)(t)}static ignoreTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._ignoreTargets.push(e);return(0,l.toDisposable)(t)}static isTouchDevice(){return"ontouchstart"in c||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){const t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let i=0,s=e.targetTouches.length;i=p._holdDelay&&Math.abs(n.initialPageX-d(n.rollingPageX))<30&&Math.abs(n.initialPageY-d(n.rollingPageY))<30){const e=this._newGestureEvent(f.CONTEXT_MENU,n.initialTarget);e.pageX=d(n.rollingPageX),e.pageY=d(n.rollingPageY),this._dispatchEvent(e)}else if(1===s){const t=d(n.rollingPageX),s=d(n.rollingPageY),r=d(n.rollingTimestamps)-n.rollingTimestamps[0],o=t-n.rollingPageX[0],a=s-n.rollingPageY[0],h=[...this._targets].filter(e=>n.initialTarget instanceof Node&&e.contains(n.initialTarget));this._inertia(e,h,i,Math.abs(o)/r,o>0?1:-1,t,Math.abs(a)/r,a>0?1:-1,s)}this._dispatchEvent(this._newGestureEvent(f.END,n.initialTarget)),delete this._activeTouches[o.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){const i=document.createEvent("CustomEvent");return i.initEvent(e,!1,!0),i.initialTarget=t,i.tapCount=0,i}_dispatchEvent(e){if(e.type===f.TAP){const t=(new Date).getTime();let i;i=t-this._lastSetTapCountTime>p._clearTapCountTime?1:2,this._lastSetTapCountTime=t,e.tapCount=i}else e.type!==f.CHANGE&&e.type!==f.CONTEXT_MENU||(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(const t of this._ignoreTargets)if(t.contains(e.initialTarget))return;const t=[];for(const i of this._targets)if(i.contains(e.initialTarget)){let s=0,r=e.initialTarget;for(;r&&r!==i;)s++,r=r.parentElement;t.push([s,i])}t.sort((e,t)=>e[0]-t[0]);for(const[,i]of t)i.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,i,s,r,o,n,a,l){this._handle=h.scheduleAtNextAnimationFrame(e,()=>{const h=Date.now(),c=h-i;let d=0,_=0,u=!0;s+=p._scrollFriction*c,n+=p._scrollFriction*c,s>0&&(u=!1,d=r*s*c),n>0&&(u=!1,_=a*n*c);const v=this._newGestureEvent(f.CHANGE);v.translationX=d,v.translationY=_,t.forEach(e=>e.dispatchEvent(v)),u||this._inertia(e,t,h,s,r,o+d,n,a,l+_)})}_handleTouchMove(e){const t=Date.now();for(let i=0,s=e.changedTouches.length;i3&&(r.rollingPageX.shift(),r.rollingPageY.shift(),r.rollingTimestamps.shift()),r.rollingPageX.push(s.pageX),r.rollingPageY.push(s.pageY),r.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}}t.Gesture=p,p._scrollFriction=-.005,p._holdDelay=700,p._clearTapCountTime=400,n([function(e,t,i){let s=null,r=null;if("function"==typeof i.value?(s="value",r=i.value,0!==r.length&&console.warn("Memoize should only be used in functions with zero parameters")):"function"==typeof i.get&&(s="get",r=i.get),!r||!s)throw new Error("not supported");const o=`$memoize$${t}`;i[s]=function(...e){return this.hasOwnProperty(o)||Object.defineProperty(this,o,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,e)}),this[o]}}],p,"isTouchDevice",null)},8997(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.VerticalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition(),n=t.verticalHasArrows;super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(n?t.verticalScrollbarSize:0,2===t.vertical?0:t.verticalScrollbarSize,0,s.height,s.scrollHeight,o.scrollTop),visibility:t.vertical,extraScrollbarClassName:"xterm-vertical",scrollable:e,scrollByPage:t.scrollByPage}),this._arrowScrollDelta=0,this._setArrows(n,t.verticalScrollbarSize),this._createSlider(0,Math.floor((t.verticalScrollbarSize-t.verticalSliderSize)/2),t.verticalSliderSize,void 0)}_updateSlider(e,t){this.slider.setHeight(e),this.slider.setTop(t)}_renderDomNode(e,t){this.domNode.setWidth(t),this.domNode.setHeight(e),this.domNode.setRight(0),this.domNode.setTop(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollHeight)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollTop)||this._shouldRender,this._shouldRender=this._handleElementSize(e.height)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return t}_sliderPointerPosition(e){return e.pageY}_sliderOrthogonalPointerPosition(e){return e.pageX}_updateScrollbarSize(e){this.slider.setWidth(e)}writeScrollPosition(e,t){e.scrollTop=t}_arrowScroll(e){const t=this._scrollable.getCurrentScrollPosition();this._scrollable.setScrollPositionNow({scrollTop:t.scrollTop+e})}_setArrows(e,t){if(this._arrowScrollDelta=t,!this._arrowUp||!this._arrowDown){const e=0;this._arrowUp=this._createArrow({className:"xterm-scra xterm-arrow-up",top:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(-this._arrowScrollDelta)}),this._arrowDown=this._createArrow({className:"xterm-scra xterm-arrow-down",bottom:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(this._arrowScrollDelta)})}if(this._updateArrowSize(this._arrowUp,t),this._updateArrowSize(this._arrowDown,t),!this._arrowUp||!this._arrowDown)return;const i=e?"":"none";this._arrowUp.bgDomNode.style.display=i,this._arrowUp.domNode.style.display=i,this._arrowDown.bgDomNode.style.display=i,this._arrowDown.domNode.style.display=i}_updateArrowSize(e,t){e&&(e.bgDomNode.style.width=`${t}px`,e.bgDomNode.style.height=`${t}px`,e.domNode.style.width=`${t}px`,e.domNode.style.height=`${t}px`)}updateOptions(e){const t=e.verticalHasArrows?e.verticalScrollbarSize:0;this._scrollbarState.setArrowSize(t),this._setArrows(e.verticalHasArrows,e.verticalScrollbarSize),this.updateScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}}t.VerticalScrollbar=o},7741(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nt(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseover(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_OVER,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseleave(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_LEAVE,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}}t.Widget=c},5959(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SelectionModel=void 0,t.SelectionModel=class{constructor(e){this._bufferService=e,this.isSelectAllActive=!1,this.selectionStartLength=0}clearSelection(){this.selectionStart=void 0,this.selectionEnd=void 0,this.isSelectAllActive=!1,this.selectionStartLength=0}get finalSelectionStart(){return this.isSelectAllActive?[0,0]:this.selectionEnd&&this.selectionStart&&this.areSelectionValuesReversed()?this.selectionEnd:this.selectionStart}get finalSelectionEnd(){if(this.isSelectAllActive)return[this._bufferService.cols,this._bufferService.buffer.ybase+this._bufferService.rows-1];if(this.selectionStart){if(!this.selectionEnd||this.areSelectionValuesReversed()){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?e%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)-1]:[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[e,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[Math.max(e,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){const e=this.selectionStart,t=this.selectionEnd;return!(!e||!t)&&(e[1]>t[1]||e[1]===t[1]&&e[0]>t[0])}handleTrim(e){return this.selectionStart&&(this.selectionStart[1]-=e),this.selectionEnd&&(this.selectionEnd[1]-=e),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):!!(this.selectionStart&&this.selectionStart[1]<0)&&(this.selectionStart=[0,0],!0)}}},4792(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharSizeService=void 0;const o=i(6501),n=i(4812),a=i(8636);let h=class extends n.Disposable{get hasValidSize(){return this.width>0&&this.height>0}constructor(e,t,i){super(),this._optionsService=i,this.width=0,this.height=0,this._onCharSizeChange=this._register(new a.Emitter),this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new d(this._optionsService))}catch{this._measureStrategy=this._register(new c(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}measure(){const e=this._measureStrategy.measure();e.width===this.width&&e.height===this.height||(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};t.CharSizeService=h,t.CharSizeService=h=s([r(2,o.IOptionsService)],h);class l extends n.Disposable{constructor(){super(...arguments),this._result={width:0,height:0}}_validateAndSet(e,t){void 0!==e&&e>0&&void 0!==t&&t>0&&(this._result.width=e,this._result.height=t)}}class c extends l{constructor(e,t,i){super(),this._document=e,this._parentElement=t,this._optionsService=i,this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}}class d extends l{constructor(e){super(),this._optionsService=e,this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");const t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;const e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}}},945(e,t,i){var s,r=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},o=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharacterJoinerService=t.JoinedCellData=void 0;const n=i(5451),a=i(8938),h=i(3055),l=i(6501);class c extends n.AttributeData{constructor(e,t,i){super(),this.content=0,this.combinedData="",this.fg=e.fg,this.bg=e.bg,this.combinedData=t,this._width=i}isCombined(){return 2097152}getWidth(){return this._width}getChars(){return this.combinedData}getCode(){return 2097151}setFromCharData(e){throw new Error("not implemented")}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.JoinedCellData=c;let d=s=class{constructor(e){this._bufferService=e,this._characterJoiners=[],this._nextCharacterJoinerId=0,this._workCell=new h.CellData}register(e){const t={id:this._nextCharacterJoinerId++,handler:e};return this._characterJoiners.push(t),t.id}deregister(e){for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;tthis._screenDprMonitor.setWindow(e))),this._register(s.EventUtils.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register((0,r.addDisposableListener)(this._textarea,"focus",()=>this._isFocused=!0)),this._register((0,r.addDisposableListener)(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return void 0===this._cachedIsFocused&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}}t.CoreBrowserService=n;class a extends o.Disposable{constructor(e){super(),this._parentWindow=e,this._windowResizeListener=this._register(new o.MutableDisposable),this._onDprChange=this._register(new s.Emitter),this.onDprChange=this._onDprChange.event,this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register((0,o.toDisposable)(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=(0,r.addDisposableListener)(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){this._resolutionMediaMatchList&&this._outerListener&&(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}}},2136(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.KeyboardService=void 0;const o=i(706),n=i(7241),a=i(9249),h=i(701),l=i(6501);let c=class{constructor(e,t){this._coreService=e,this._optionsService=t}_getWin32InputMode(){return this._win32InputMode??=new a.Win32InputMode,this._win32InputMode}_getKittyKeyboard(){return this._kittyKeyboard??=new n.KittyKeyboard,this._kittyKeyboard}evaluateKeyDown(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!0);const t=this._coreService.kittyKeyboard.flags;return this.useKitty?this._getKittyKeyboard().evaluate(e,t,e.repeat?2:1,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):(0,o.evaluateKeyboardEvent)(e,this._coreService.decPrivateModes.applicationCursorKeys,h.isMac,this._optionsService.rawOptions.macOptionIsMeta)}evaluateKeyUp(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!1);const t=this._coreService.kittyKeyboard.flags;return this.useKitty&&2&t?this._getKittyKeyboard().evaluate(e,t,3,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):void 0}get useKitty(){const e=this._coreService.kittyKeyboard.flags;return!(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard||!n.KittyKeyboard.shouldUseProtocol(e))}get useWin32InputMode(){return!(!this._optionsService.rawOptions.vtExtensions?.win32InputMode||!this._coreService.decPrivateModes.win32InputMode)}};t.KeyboardService=c,t.KeyboardService=c=s([r(0,l.ICoreService),r(1,l.IOptionsService)],c)},9820(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.LinkProviderService=void 0;const s=i(4812);class r extends s.Disposable{constructor(){super(),this.linkProviders=[],this._register((0,s.toDisposable)(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{const t=this.linkProviders.indexOf(e);-1!==t&&this.linkProviders.splice(t,1)}}}}t.LinkProviderService=r},8294(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.MouseCoordsService=void 0;const o=i(4159),n=i(5251),a=i(7098);let h=class{constructor(e,t){this._charSizeService=e,this._renderService=t}getCoords(e,t,i,s,r){return(0,n.getCoords)((0,o.getWindow)(t),e,t,i,s,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,r)}getMouseReportCoords(e,t){const i=(0,n.getCoordsRelativeToElement)((0,o.getWindow)(t),e,t);if(this._charSizeService.hasValidSize)return i[0]=Math.min(Math.max(i[0],0),this._renderService.dimensions.css.canvas.width-1),i[1]=Math.min(Math.max(i[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(i[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(i[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(i[0]),y:Math.floor(i[1])}}};t.MouseCoordsService=h,t.MouseCoordsService=h=s([r(0,a.ICharSizeService),r(1,a.IRenderService)],h)},9784(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.AltMouseCursorController=t.MouseService=void 0;const o=i(4159),n=i(6501),a=i(4812),h=i(7098),l=i(2650);let c=class{constructor(e,t,i,s,r,o,n,a,h){this._renderService=e,this._mouseCoordsService=t,this._mouseStateService=i,this._coreService=s,this._bufferService=r,this._optionsService=o,this._selectionService=n,this._logService=a,this._coreBrowserService=h,this._lastEvent=null,this._wheelPartialScroll=0,this._touchScrollAccumulator=0}bindMouse(e,t,i){const{element:s,document:r}=e,n={mouseup:null,wheel:null,mousedrag:null,mousemove:null},h={target:e,focus:i,requestedEvents:n},c={mouseup:e=>this._handleMouseUp(h,e),wheel:e=>this._handleWheel(h,e),mousedrag:e=>this._handleMouseDrag(h,e),mousemove:e=>this._handleMouseMove(h,e)};this._altMouseCursor=new d(s,r,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),t(this._altMouseCursor),t(this._mouseStateService.onProtocolChange(e=>{this._handleProtocolChange(h,c,e)})),t(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(s),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,t((0,a.toDisposable)(()=>{n.mouseup&&r.removeEventListener("mouseup",n.mouseup),n.mousedrag&&r.removeEventListener("mousemove",n.mousedrag)})),t((0,o.addDisposableListener)(s,"mousedown",e=>this._handleMouseDown(h,e))),t((0,o.addDisposableListener)(s,"wheel",e=>this._handlePassiveWheel(h,e),{passive:!1})),t(l.Gesture.addTarget(e.screenElement)),t((0,o.addDisposableListener)(e.screenElement,l.EventType.START,()=>this._handleTouchStart())),t((0,o.addDisposableListener)(e.screenElement,l.EventType.CHANGE,e=>this._handleTouchChange(h,e)))}_sendEvent(e,t){const i=this._mouseCoordsService.getMouseReportCoords(t,e.target.screenElement);if(!i)return!1;let s,r;switch(t.overrideType||t.type){case"mousemove":r=32,void 0===t.buttons?(s=3,void 0!==t.button&&(s=t.button<3?t.button:3)):s=1&t.buttons?0:4&t.buttons?1:2&t.buttons?2:3;break;case"mouseup":r=0,s=t.button<3?t.button:3;break;case"mousedown":r=1,s=t.button<3?t.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;const e=t.deltaY;if(0===e)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return!1;r=e<0?0:1,s=4;break;default:return!1}if(void 0===r||void 0===s||s>4)return!1;if(4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!t.altKey)return!1;const o=4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:i.col,row:i.row,x:i.x,y:i.y,button:s,action:r,ctrl:t.ctrlKey,alt:!o&&t.altKey,shift:t.shiftKey})}_handleMouseUp(e,t){this._sendEvent(e,t),t.buttons||(e.requestedEvents.mouseup&&e.target.document.removeEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.removeEventListener("mousemove",e.requestedEvents.mousedrag))}_handleWheel(e,t){return this._sendEvent(e,t),t.preventDefault(),t.stopPropagation(),!1}_handleMouseDrag(e,t){t.buttons&&this._sendEvent(e,t)}_handleMouseMove(e,t){t.buttons||this._sendEvent(e,t)}_handleMouseDown(e,t){t.preventDefault(),e.focus(),this._mouseStateService.areMouseEventsActive&&!this._selectionService.shouldForceSelection(t)&&(this._sendEvent(e,t),e.requestedEvents.mouseup&&e.target.document.addEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.addEventListener("mousemove",e.requestedEvents.mousedrag))}_handlePassiveWheel(e,t){if(!e.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;if(!this._bufferService.buffer.hasScrollback){if(0===t.deltaY)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return t.preventDefault(),t.stopPropagation(),!1;const e=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(e,!0),t.preventDefault(),t.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(e,t){t.preventDefault(),t.stopPropagation(),e.requestedEvents.wheel?this._handleTouchScrollAsWheel(e,t):this._bufferService.buffer.hasScrollback?e.target.handleTouchScroll?.(t.translationY):this._handleTouchScrollAsKeys(t)}_handleTouchScrollAsKeys(e){const t=this._renderService?.dimensions.css.cell.height;if(!t)return;this._touchScrollAccumulator-=e.translationY;const i=Math.trunc(this._touchScrollAccumulator/t);if(0===i)return;this._touchScrollAccumulator-=i*t;const s=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(i<0?"A":"B");for(let e=0;e0?1:-1),this._wheelPartialScroll%=1):e.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(r*=this._bufferService.rows),r}_triggerMouseEvent(e){if(e.col<0||e.col>=this._bufferService.cols||e.row<0||e.row>=this._bufferService.rows)return!1;if(4===e.button&&32===e.action)return!1;if(3===e.button&&32!==e.action)return!1;if(4!==e.button&&(2===e.action||3===e.action))return!1;if(e.col++,e.row++,32===e.action&&this._lastEvent&&this._equalEvents(this._lastEvent,e,this._mouseStateService.isPixelEncoding))return!1;if(!this._mouseStateService.restrictMouseEvent(e))return!1;const t=this._mouseStateService.encodeMouseEvent(e);return t&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(t):this._coreService.triggerDataEvent(t,!0)),this._lastEvent=e,!0}_explainEvents(e){return{down:!!(1&e),up:!!(2&e),drag:!!(4&e),move:!!(8&e),wheel:!!(16&e)}}_equalEvents(e,t,i){if(i){if(e.x!==t.x)return!1;if(e.y!==t.y)return!1}else{if(e.col!==t.col)return!1;if(e.row!==t.row)return!1}return e.button===t.button&&e.action===t.action&&e.ctrl===t.ctrl&&e.alt===t.alt&&e.shift===t.shift}};t.MouseService=c,t.MouseService=c=s([r(0,h.IRenderService),r(1,h.IMouseCoordsService),r(2,n.IMouseStateService),r(3,n.ICoreService),r(4,n.IBufferService),r(5,n.IOptionsService),r(6,h.ISelectionService),r(7,n.ILogService),r(8,h.ICoreBrowserService)],c);class d{constructor(e,t,i){this._element=e,this._document=t,this._isActive=i,this._listeners=new a.MutableDisposable}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;const e=new a.DisposableStore,t=e=>this.syncFromModifier(e);e.add((0,o.addDisposableListener)(this._document,"keydown",t)),e.add((0,o.addDisposableListener)(this._document,"keyup",t)),e.add((0,o.addDisposableListener)(this._element,"mousemove",t));const i=this._element.ownerDocument?.defaultView;i&&e.add((0,o.addDisposableListener)(i,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=e}resetClass(){this._updateClass(!1)}syncFromModifier(e){this._isActive()&&this._updateClass(e.getModifierState("Alt"))}_updateClass(e){e?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}}t.AltMouseCursorController=d},5783(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.RenderService=void 0;const o=i(4852),n=i(7098),a=i(4812),h=i(6168),l=i(6501),c=i(8636);let d=class extends a.Disposable{get dimensions(){return this._renderer.value.dimensions}constructor(e,t,i,s,r,n,l,d,u,f){super(),this._rowCount=e,this._optionsService=i,this._logService=s,this._charSizeService=r,this._coreService=n,this._coreBrowserService=u,this._renderer=this._register(new a.MutableDisposable),this._observerDisposable=this._register(new a.MutableDisposable),this._isPaused=!1,this._needsFullRefresh=!1,this._isNextRenderRedrawOnly=!0,this._needsSelectionRefresh=!1,this._canvasWidth=0,this._canvasHeight=0,this._selectionState={start:void 0,end:void 0,columnSelectMode:!1},this._onDimensionsChange=this._register(new c.Emitter),this.onDimensionsChange=this._onDimensionsChange.event,this._onRenderedViewportChange=this._register(new c.Emitter),this.onRenderedViewportChange=this._onRenderedViewportChange.event,this._onRender=this._register(new c.Emitter),this.onRender=this._onRender.event,this._onRefreshRequest=this._register(new c.Emitter),this.onRefreshRequest=this._onRefreshRequest.event,this._pausedResizeTask=this._register(new h.DebouncedIdleTask(this._logService)),this._renderDebouncer=new o.RenderDebouncer((e,t)=>this._renderRows(e,t),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new _(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register((0,a.toDisposable)(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(d.onResize(()=>this._fullRefresh())),this._register(d.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(d.cols,d.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(d.buffer.y,d.buffer.y,void 0,!0))),this._register(f.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(e=>this._registerIntersectionObserver(e,t)))}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){const i=new e.IntersectionObserver(e=>this._handleIntersectionChange(e[e.length-1]),{threshold:0});this._observerDisposable.value=(0,a.toDisposable)(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=i,i.observe(t)}}_handleIntersectionChange(e){this._isPaused=void 0===e.isIntersecting?0===e.intersectionRatio:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),this._isPaused||this._charSizeService.hasValidSize||this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,i=!1,s=!1){if(this._isPaused)return void(this._needsFullRefresh=!0);if(this._coreService.decPrivateModes.synchronizedOutput)return void this._syncOutputHandler.bufferRows(e,t);const r=this._syncOutputHandler.flush();r&&(e=Math.min(e,r.start),t=Math.max(t,r.end)),s||(this._isNextRenderRedrawOnly=!1),i?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){this._renderer.value&&(this._coreService.decPrivateModes.synchronizedOutput?this._syncOutputHandler.bufferRows(e,t):(e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0))}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(e=>this.refreshRows(e.start,e.end,e.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,i){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=i,this._renderer.value?.handleSelectionChanged(e,t,i)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};t.RenderService=d,t.RenderService=d=s([r(2,l.IOptionsService),r(3,l.ILogService),r(4,n.ICharSizeService),r(5,l.ICoreService),r(6,l.IDecorationService),r(7,l.IBufferService),r(8,n.ICoreBrowserService),r(9,n.IThemeService)],d);class _{constructor(e,t,i){this._coreBrowserService=e,this._coreService=t,this._onTimeout=i,this._start=0,this._end=0,this._isBuffering=!1}bufferRows(e,t){this._isBuffering?(this._start=Math.min(this._start,e),this._end=Math.max(this._end,t)):(this._start=e,this._end=t,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;const e={start:this._start,end:this._end};return this._isBuffering=!1,e}dispose(){void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}}},2079(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleMouseMove(e),this._mouseUpListener=e=>this._handleMouseUp(e),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(e=>this._handleTrim(e)),this._register(this._bufferService.buffers.onBufferActivate(e=>this._handleBufferActivate(e))),this.enable(),this._model=new d.SelectionModel(this._bufferService),this._activeSelectionMode=0,this._register((0,u.toDisposable)(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(e=>{e.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!(!e||!t||e[0]===t[0]&&e[1]===t[1])}get selectionText(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";const i=this._bufferService.buffer,s=[];if(3===this._activeSelectionMode){if(e[0]===t[0])return"";const r=e[0]e.replace(b," ")).join(f.isWindows?"\r\n":"\n")}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._refresh())),f.isLinux&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:3===this._activeSelectionMode})}_isClickInSelection(e){const t=this._getMouseBufferCoords(e),i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!!(i&&s&&t)&&this._areCoordsInSelection(t,i,s)}isCellInSelection(e,t){const i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!(!i||!s)&&this._areCoordsInSelection([e,t],i,s)}_areCoordsInSelection(e,t,i){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){const i=this._linkifier.currentLink?.link?.range;if(i)return this._model.selectionStart=[i.start.x-1,i.start.y-1],this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols),this._model.selectionEnd=void 0,!0;const s=this._getMouseBufferCoords(e);return!!s&&(this._selectWordAt(s,t),this._model.selectionEnd=void 0,!0)}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){const t=this._mouseCoordsService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=(0,l.getCoordsRelativeToElement)(this._coreBrowserService.window,e,this._screenElement)[1];const i=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=i?0:(t>i&&(t-=i),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(14*t))}shouldForceSelection(e){return this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive?!e.altKey:f.isMac?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,!(2===e.button&&this.hasSelection||0!==e.button||this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&e.altKey)){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):1===e.detail?this._handleSingleClick(e):2===e.detail?this._handleDoubleClick(e):3===e.detail&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener("mouseup",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval(()=>this._dragScroll(),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener("mouseup",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){const t=this.hasSelection;if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0,t&&this._fireOnSelectionChange(this._model.finalSelectionStart,this._model.finalSelectionEnd,!1);const i=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);i&&i.length!==this._model.selectionStart[0]&&0===i.hasWidth(this._model.selectionStart[0])&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){const t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return(!this._optionsService.rawOptions.mouseEventsRequireAlt||!this._mouseStateService.areMouseEventsActive)&&e.altKey&&!(f.isMac&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;const t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd)return void this.refresh(!0);2===this._activeSelectionMode?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));const i=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows-1,e.lines.length-1)):(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){const t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){const t=this._mouseCoordsService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(t&&void 0!==t[0]&&void 0!==t[1]){const e=(0,c.moveToCellSequence)(t[0]-1,t[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(e,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,i=!(!e||!t||e[0]===t[0]&&e[1]===t[1]);i?e&&t&&(this._oldSelectionStart&&this._oldSelectionEnd&&e[0]===this._oldSelectionStart[0]&&e[1]===this._oldSelectionStart[1]&&t[0]===this._oldSelectionEnd[0]&&t[1]===this._oldSelectionEnd[1]||this._fireOnSelectionChange(e,t,i)):this._oldHasSelection&&this._fireOnSelectionChange(e,t,i)}_fireOnSelectionChange(e,t,i){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=i,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.value=e.activeBuffer.lines.onTrim(e=>this._handleTrim(e))}_convertViewportColToCharacterIndex(e,t){let i=t;for(let s=0;t>=s;s++){const r=e.loadCell(s,this._workCell).getChars().length;0===this._workCell.getWidth()?i--:r>1&&t!==s&&(i+=r-1)}return i}setSelection(e,t,i){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=i,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,i=!0,s=!0){if(e[0]>=this._bufferService.cols)return;const r=this._bufferService.buffer,o=r.lines.get(e[1]);if(!o)return;const n=r.translateBufferLineToString(e[1],!1);let a=this._convertViewportColToCharacterIndex(o,e[0]),h=a;const l=e[0]-a;let c=0,d=0,_=0,u=0;if(" "===n.charAt(a)){for(;a>0&&" "===n.charAt(a-1);)a--;for(;h1&&(u+=s-1,h+=s-1);t>0&&a>0&&!this._isCharWordSeparator(o.loadCell(t-1,this._workCell));){o.loadCell(t-1,this._workCell);const e=this._workCell.getChars().length;0===this._workCell.getWidth()?(c++,t--):e>1&&(_+=e-1,a-=e-1),a--,t--}for(;i1&&(u+=e-1,h+=e-1),h++,i++}}h++;let f=a+l-c+_,p=Math.min(this._bufferService.cols,h-a+c+d-_-u);if(t||""!==n.slice(a,h).trim()){if(i&&0===f&&32!==o.getCodePoint(0)){const t=r.lines.get(e[1]-1);if(t&&o.isWrapped&&32!==t.getCodePoint(this._bufferService.cols-1)){const t=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(t){const e=this._bufferService.cols-t.start;f-=e,p+=e}}}if(s&&f+p===this._bufferService.cols&&32!==o.getCodePoint(this._bufferService.cols-1)){const t=r.lines.get(e[1]+1);if(t?.isWrapped&&32!==t.getCodePoint(0)){const t=this._getWordAt([0,e[1]+1],!1,!1,!0);t&&(p+=t.length)}}return{start:f,length:p}}}_selectWordAt(e,t){const i=this._getWordAt(e,t);if(i){for(;i.start<0;)i.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[i.start,e[1]],this._model.selectionStartLength=i.length}}_selectToWordAt(e){const t=this._getWordAt(e,!0);if(t){let i=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,i--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,i++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,i]}}_isCharWordSeparator(e){return 0!==e.getWidth()&&this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){const t=this._bufferService.buffer.getWrappedRangeForLine(e),i={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols)}};t.SelectionService=w,t.SelectionService=w=n([h(3,g.IBufferService),h(4,g.ICoreService),h(5,_.IMouseCoordsService),h(6,g.IOptionsService),h(7,g.IMouseStateService),h(8,_.IRenderService),h(9,_.ICoreBrowserService)],w)},7098(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IKeyboardService=t.ILinkProviderService=t.IThemeService=t.ICharacterJoinerService=t.ISelectionService=t.IRenderService=t.IMouseService=t.IMouseCoordsService=t.ICoreBrowserService=t.ICharSizeService=void 0;const s=i(6201);t.ICharSizeService=(0,s.createDecorator)("CharSizeService"),t.ICoreBrowserService=(0,s.createDecorator)("CoreBrowserService"),t.IMouseCoordsService=(0,s.createDecorator)("MouseCoordsService"),t.IMouseService=(0,s.createDecorator)("MouseService"),t.IRenderService=(0,s.createDecorator)("RenderService"),t.ISelectionService=(0,s.createDecorator)("SelectionService"),t.ICharacterJoinerService=(0,s.createDecorator)("CharacterJoinerService"),t.IThemeService=(0,s.createDecorator)("ThemeService"),t.ILinkProviderService=(0,s.createDecorator)("LinkProviderService"),t.IKeyboardService=(0,s.createDecorator)("KeyboardService")},9078(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeService=void 0;const o=i(7174),n=i(9302),a=i(4103),h=i(4812),l=i(6501),c=i(8636),d=a.css.toColor("#ffffff"),_=a.css.toColor("#000000"),u=a.css.toColor("#ffffff"),f=_,p={css:"rgba(255, 255, 255, 0.3)",rgba:4294967117},v=d;let g=class extends h.Disposable{get colors(){return this._colors}constructor(e){super(),this._optionsService=e,this._contrastCache=new o.ColorContrastCache,this._halfContrastCache=new o.ColorContrastCache,this._onChangeColors=this._register(new c.Emitter),this.onChangeColors=this._onChangeColors.event,this._colors={foreground:d,background:_,cursor:u,cursorAccent:f,selectionForeground:void 0,selectionBackgroundTransparent:p,selectionBackgroundOpaque:a.color.blend(_,p),selectionInactiveBackgroundTransparent:p,selectionInactiveBackgroundOpaque:a.color.blend(_,p),scrollbarSliderBackground:a.color.opacity(d,.2),scrollbarSliderHoverBackground:a.color.opacity(d,.4),scrollbarSliderActiveBackground:a.color.opacity(d,.5),overviewRulerBorder:d,ansi:n.DEFAULT_ANSI_COLORS.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this._register(this._optionsService.onSpecificOptionChange("minimumContrastRatio",()=>this._contrastCache.clear())),this._register(this._optionsService.onSpecificOptionChange("theme",()=>this._setTheme(this._optionsService.rawOptions.theme)))}_setTheme(e={}){const t=this._colors;if(t.foreground=m(e.foreground,d),t.background=m(e.background,_),t.cursor=a.color.blend(t.background,m(e.cursor,u)),t.cursorAccent=a.color.blend(t.background,m(e.cursorAccent,f)),t.selectionBackgroundTransparent=m(e.selectionBackground,p),t.selectionBackgroundOpaque=a.color.blend(t.background,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundTransparent=m(e.selectionInactiveBackground,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundOpaque=a.color.blend(t.background,t.selectionInactiveBackgroundTransparent),t.selectionForeground=e.selectionForeground?m(e.selectionForeground,a.NULL_COLOR):void 0,t.selectionForeground===a.NULL_COLOR&&(t.selectionForeground=void 0),a.color.isOpaque(t.selectionBackgroundTransparent)){const e=.3;t.selectionBackgroundTransparent=a.color.opacity(t.selectionBackgroundTransparent,e)}if(a.color.isOpaque(t.selectionInactiveBackgroundTransparent)){const e=.3;t.selectionInactiveBackgroundTransparent=a.color.opacity(t.selectionInactiveBackgroundTransparent,e)}if(t.scrollbarSliderBackground=m(e.scrollbarSliderBackground,a.color.opacity(t.foreground,.2)),t.scrollbarSliderHoverBackground=m(e.scrollbarSliderHoverBackground,a.color.opacity(t.foreground,.4)),t.scrollbarSliderActiveBackground=m(e.scrollbarSliderActiveBackground,a.color.opacity(t.foreground,.5)),t.overviewRulerBorder=m(e.overviewRulerBorder,v),t.ansi=n.DEFAULT_ANSI_COLORS.slice(),t.ansi[0]=m(e.black,n.DEFAULT_ANSI_COLORS[0]),t.ansi[1]=m(e.red,n.DEFAULT_ANSI_COLORS[1]),t.ansi[2]=m(e.green,n.DEFAULT_ANSI_COLORS[2]),t.ansi[3]=m(e.yellow,n.DEFAULT_ANSI_COLORS[3]),t.ansi[4]=m(e.blue,n.DEFAULT_ANSI_COLORS[4]),t.ansi[5]=m(e.magenta,n.DEFAULT_ANSI_COLORS[5]),t.ansi[6]=m(e.cyan,n.DEFAULT_ANSI_COLORS[6]),t.ansi[7]=m(e.white,n.DEFAULT_ANSI_COLORS[7]),t.ansi[8]=m(e.brightBlack,n.DEFAULT_ANSI_COLORS[8]),t.ansi[9]=m(e.brightRed,n.DEFAULT_ANSI_COLORS[9]),t.ansi[10]=m(e.brightGreen,n.DEFAULT_ANSI_COLORS[10]),t.ansi[11]=m(e.brightYellow,n.DEFAULT_ANSI_COLORS[11]),t.ansi[12]=m(e.brightBlue,n.DEFAULT_ANSI_COLORS[12]),t.ansi[13]=m(e.brightMagenta,n.DEFAULT_ANSI_COLORS[13]),t.ansi[14]=m(e.brightCyan,n.DEFAULT_ANSI_COLORS[14]),t.ansi[15]=m(e.brightWhite,n.DEFAULT_ANSI_COLORS[15]),e.extendedAnsi){const i=Math.min(t.ansi.length-16,e.extendedAnsi.length);for(let s=0;ssetTimeout(t,e))},t.disposableTimeout=function(e,t=0,i){const r=setTimeout(()=>{e(),i&&o.dispose()},t),o=(0,s.toDisposable)(()=>{clearTimeout(r)});return i?.add(o),o};const s=i(4812);t.TimeoutTimer=class{constructor(){this._token=-1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,e()},t)}setIfNotSet(e,t){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout(()=>{this._token=-1,e()},t))}},t.MicrotaskTimer=class{constructor(){this._isScheduled=!1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(e){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,e())}))}},t.IntervalTimer=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(e,t,i=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();const s=i.setInterval(()=>{e()},t);this._disposable={dispose:()=>{i.clearInterval(s),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}}},5639(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CircularList=void 0;const s=i(4812),r=i(8636);class o extends s.Disposable{constructor(e){super(),this._maxLength=e,this.onDeleteEmitter=this._register(new r.Emitter),this.onDelete=this.onDeleteEmitter.event,this.onInsertEmitter=this._register(new r.Emitter),this.onInsert=this.onInsertEmitter.event,this.onTrimEmitter=this._register(new r.Emitter),this.onTrim=this.onTrimEmitter.event,this._array=new Array(this._maxLength),this._startIndex=0,this._length=0}get maxLength(){return this._maxLength}set maxLength(e){if(this._maxLength===e)return;const t=new Array(e);for(let i=0;ithis._length)for(let t=this._length;t=e;t--)this._array[this._getCyclicIndex(t+i.length)]=this._array[this._getCyclicIndex(t)];for(let t=0;tthis._maxLength){const e=this._length+i.length-this._maxLength;this._startIndex+=e,this._length=this._maxLength,this.onTrimEmitter.fire(e)}else this._length+=i.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,i){if(!(t<=0)){if(e<0||e>=this._length)throw new Error("start argument out of range");if(e+i<0)throw new Error("Cannot shift elements in list beyond index 0");if(i>0){for(let s=t-1;s>=0;s--)this.set(e+s+i,this.get(e+s));const s=e+t+i-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;s>>0},e.toColor=function(t,i,s,r){return{css:e.toCss(t,i,s,r),rgba:e.toRgba(t,i,s,r)}}}(n||(t.channels=n={})),function(e){function t(e,t){return o=Math.round(255*t),[i,s,r]=c.toChannels(e.rgba),{css:n.toCss(i,s,r,o),rgba:n.toRgba(i,s,r,o)}}e.blend=function(e,t){if(o=(255&t.rgba)/255,1===o)return{css:t.css,rgba:t.rgba};const a=t.rgba>>24&255,h=t.rgba>>16&255,l=t.rgba>>8&255,c=e.rgba>>24&255,d=e.rgba>>16&255,_=e.rgba>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),{css:n.toCss(i,s,r),rgba:n.toRgba(i,s,r)}},e.isOpaque=function(e){return!(255&~e.rgba)},e.ensureContrastRatio=function(e,t,i){const s=c.ensureContrastRatio(e.rgba,t.rgba,i);if(s)return n.toColor(s>>24&255,s>>16&255,s>>8&255)},e.opaque=function(e){const t=(255|e.rgba)>>>0;return[i,s,r]=c.toChannels(t),{css:n.toCss(i,s,r),rgba:t}},e.opacity=t,e.multiplyOpacity=function(e,i){return o=255&e.rgba,t(e,o*i/255)},e.toColorRGB=function(e){return[e.rgba>>24&255,e.rgba>>16&255,e.rgba>>8&255]}}(a||(t.color=a={})),function(e){let t,a;try{const e=document.createElement("canvas");e.width=1,e.height=1;const i=e.getContext("2d",{willReadFrequently:!0});i&&(t=i,t.globalCompositeOperation="copy",a=t.createLinearGradient(0,0,1,1))}catch{}e.toColor=function(e){if(e.match(/#[\da-f]{3,8}/i))switch(e.length){case 4:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),n.toColor(i,s,r);case 5:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),o=parseInt(e.slice(4,5).repeat(2),16),n.toColor(i,s,r,o);case 7:return{css:e,rgba:(parseInt(e.slice(1),16)<<8|255)>>>0};case 9:return{css:e,rgba:parseInt(e.slice(1),16)>>>0}}const h=e.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(h)return i=parseInt(h[1],10),s=parseInt(h[2],10),r=parseInt(h[3],10),o=Math.round(255*(void 0===h[5]?1:parseFloat(h[5]))),n.toColor(i,s,r,o);if("transparent"===e)return{css:"transparent",rgba:0};if(!t||!a)throw new Error("css.toColor: Unsupported css format");if(t.fillStyle=a,t.fillStyle=e,"string"!=typeof t.fillStyle)throw new Error("css.toColor: Unsupported css format");if(t.fillRect(0,0,1,1),[i,s,r,o]=t.getImageData(0,0,1,1).data,255!==o)throw new Error("css.toColor: Unsupported css format");return{rgba:n.toRgba(i,s,r,o),css:e}}}(h||(t.css=h={})),function(e){function t(e,t,i){const s=e/255,r=t/255,o=i/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:Math.pow((r+.055)/1.055,2.4))+.0722*(o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4))}e.relativeLuminance=function(e){return t(e>>16&255,e>>8&255,255&e)},e.relativeLuminance2=t}(l||(t.rgb=l={})),function(e){function t(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c0||a>0||h>0);)n-=Math.max(0,Math.ceil(.1*n)),a-=Math.max(0,Math.ceil(.1*a)),h-=Math.max(0,Math.ceil(.1*h)),c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));return(n<<24|a<<16|h<<8|255)>>>0}function a(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c>>0}e.blend=function(e,t){if(o=(255&t)/255,1===o)return t;const a=t>>24&255,h=t>>16&255,l=t>>8&255,c=e>>24&255,d=e>>16&255,_=e>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),n.toRgba(i,s,r)},e.ensureContrastRatio=function(e,i,s){const r=l.relativeLuminance(e>>8),o=l.relativeLuminance(i>>8);if(_(r,o)>8));if(n_(r,l.relativeLuminance(t>>8))?o:t}return o}const n=a(e,i,s),h=_(r,l.relativeLuminance(n>>8));if(h_(r,l.relativeLuminance(o>>8))?n:o}return n}},e.reduceLuminance=t,e.increaseLuminance=a,e.toChannels=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}}(c||(t.rgba=c={}))},5777(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CoreTerminal=void 0;const s=i(6501),r=i(6025),o=i(7276),n=i(9640),a=i(56),h=i(4071),l=i(6478),c=i(7428),d=i(6415),_=i(5746),u=i(5882),f=i(2486),p=i(3562),v=i(8811),g=i(8636),m=i(4812);let S=!1;class b extends m.Disposable{get onScroll(){return this._onScrollApi||(this._onScrollApi=this._register(new g.Emitter),this._onScroll.event(e=>{this._onScrollApi?.fire(e.position)})),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(const t in e)this.optionsService.options[t]=e[t]}constructor(e){super(),this._windowsWrappingHeuristics=this._register(new m.MutableDisposable),this._onBinary=this._register(new g.Emitter),this.onBinary=this._onBinary.event,this._onData=this._register(new g.Emitter),this.onData=this._onData.event,this._onLineFeed=this._register(new g.Emitter),this.onLineFeed=this._onLineFeed.event,this._onRender=this._register(new g.Emitter),this.onRender=this._onRender.event,this._onResize=this._register(new g.Emitter),this.onResize=this._onResize.event,this._onWriteParsed=this._register(new g.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._onScroll=this._register(new g.Emitter),this._instantiationService=new r.InstantiationService,this.optionsService=this._register(new a.OptionsService(e)),this._instantiationService.setService(s.IOptionsService,this.optionsService),this._logService=this._register(this._instantiationService.createInstance(o.LogService)),this._instantiationService.setService(s.ILogService,this._logService),this._bufferService=this._register(this._instantiationService.createInstance(n.BufferService)),this._instantiationService.setService(s.IBufferService,this._bufferService),this.coreService=this._register(this._instantiationService.createInstance(h.CoreService)),this._instantiationService.setService(s.ICoreService,this.coreService),this.mouseStateService=this._register(this._instantiationService.createInstance(l.MouseStateService)),this._instantiationService.setService(s.IMouseStateService,this.mouseStateService),this.unicodeService=this._register(this._instantiationService.createInstance(d.UnicodeService)),this.unicodeService.register(new c.UnicodeV6),this._instantiationService.setService(s.IUnicodeService,this.unicodeService),this._charsetService=this._instantiationService.createInstance(_.CharsetService),this._instantiationService.setService(s.ICharsetService,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(v.OscLinkService),this._instantiationService.setService(s.IOscLinkService,this._oscLinkService),this._inputHandler=this._register(new f.InputHandler(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.mouseStateService,this.unicodeService)),this._register(g.EventUtils.forward(this._inputHandler.onLineFeed,this._onLineFeed)),this._register(g.EventUtils.forward(this._bufferService.onResize,this._onResize)),this._register(g.EventUtils.forward(this.coreService.onData,this._onData)),this._register(g.EventUtils.forward(this.coreService.onBinary,this._onBinary)),this._register(this.coreService.onRequestScrollToBottom(()=>this.scrollToBottom(!0))),this._register(this.coreService.onUserInput(()=>this._writeBuffer.handleUserInput())),this._register(this.optionsService.onMultipleOptionChange(["windowsPty"],()=>this._handleWindowsPtyOptionChange())),this._register(this._bufferService.onScroll(()=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)})),this._writeBuffer=this._register(new p.WriteBuffer((e,t)=>this._inputHandler.parse(e,t))),this._register(g.EventUtils.forward(this._writeBuffer.onWriteParsed,this._onWriteParsed))}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=s.LogLevelEnum.WARN&&!S&&(this._logService.warn("writeSync is unreliable and will be removed soon."),S=!0),this._writeBuffer.writeSync(e,t)}input(e,t=!0){this.coreService.triggerDataEvent(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,2),t=Math.max(t,1),this._writeBuffer.flushSync(),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t){this._bufferService.scrollLines(e,t)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}registerApcHandler(e,t){return this._inputHandler.registerApcHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.mouseStateService.reset()}_handleWindowsPtyOptionChange(){let e=!1;const t=this.optionsService.rawOptions.windowsPty;t&&void 0!==t.backend&&void 0!==t.buildNumber&&(e=!!("conpty"===t.backend&&t.buildNumber<21376)),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){const e=[];e.push(this.onLineFeed(u.updateWindowsModeWrappedState.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:"H"},()=>((0,u.updateWindowsModeWrappedState)(this._bufferService),!1))),this._windowsWrappingHeuristics.value=(0,m.toDisposable)(()=>{for(const t of e)t.dispose()})}}}t.CoreTerminal=b},8636(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EventUtils=t.Emitter=void 0;const s=i(4812);var r;t.Emitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=(e,t,i)=>{if(this._disposed)return(0,s.toDisposable)(()=>{});const r={fn:e,thisArgs:t};this._listeners.push(r);const o=(0,s.toDisposable)(()=>{const e=this._listeners.indexOf(r);-1!==e&&this._listeners.splice(e,1)});return i&&(Array.isArray(i)?i.push(o):i.add(o)),o}),this._event}fire(e){if(!this._disposed)switch(this._listeners.length){case 0:return;case 1:{const{fn:t,thisArgs:i}=this._listeners[0];return void t.call(i,e)}default:{const t=this._listeners.slice();for(const{fn:i,thisArgs:s}of t)i.call(s,e)}}}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},function(e){e.forward=function(e,t){return e(e=>t.fire(e))},e.map=function(e,t){return(i,s,r)=>e(e=>i.call(s,t(e)),void 0,r)},e.any=function(...e){return(t,i,r)=>{const o=new s.DisposableStore;for(const s of e)o.add(s(e=>t.call(i,e)));return r&&(Array.isArray(r)?r.push(o):r.add(o)),o}},e.runAndSubscribe=function(e,t,i){return t(i),e(e=>t(e))}}(r||(t.EventUtils=r={}))},2486(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.InputHandler=t.WindowsOptionsReportType=void 0,t.isValidColorIndex=L;const o=i(6760),n=i(6717),a=i(4812),h=i(726),l=i(6107),c=i(8938),d=i(3055),_=i(5451),u=i(6501),f=i(6415),p=i(1346),v=i(9823),g=i(2607),m=i(8693),S=i(8636),b=i(7804),w={"(":0,")":1,"*":2,"+":3,"-":1,".":2};function y(e,t){if(e>24)return t.setWinLines||!1;switch(e){case 1:return!!t.restoreWin;case 2:return!!t.minimizeWin;case 3:return!!t.setWinPosition;case 4:return!!t.setWinSizePixels;case 5:return!!t.raiseWin;case 6:return!!t.lowerWin;case 7:return!!t.refreshWin;case 8:return!!t.setWinSizeChars;case 9:return!!t.maximizeWin;case 10:return!!t.fullscreenWin;case 11:return!!t.getWinState;case 13:return!!t.getWinPosition;case 14:return!!t.getWinSizePixels;case 15:return!!t.getScreenSizePixels;case 16:return!!t.getCellSizePixels;case 18:return!!t.getWinSizeChars;case 19:return!!t.getScreenSizeChars;case 20:return!!t.getIconTitle;case 21:return!!t.getWinTitle;case 22:return!!t.pushTitle;case 23:return!!t.popTitle;case 24:return!!t.setWinLines}return!1}var C;!function(e){e[e.GET_WIN_SIZE_PIXELS=0]="GET_WIN_SIZE_PIXELS",e[e.GET_CELL_SIZE_PIXELS=1]="GET_CELL_SIZE_PIXELS"}(C||(t.WindowsOptionsReportType=C={}));let k=0;class D extends a.Disposable{getAttrData(){return this._curAttrData}constructor(e,t,i,s,r,a,c,d,_=new n.EscapeSequenceParser){super(),this._bufferService=e,this._charsetService=t,this._coreService=i,this._logService=s,this._optionsService=r,this._oscLinkService=a,this._mouseStateService=c,this._unicodeService=d,this._parser=_,this._parseBuffer=new Uint32Array(4096),this._stringDecoder=new h.StringToUtf32,this._utf8Decoder=new h.Utf8ToUtf32,this._windowTitle="",this._iconName="",this._windowTitleStack=[],this._iconNameStack=[],this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone(),this._onRequestBell=this._register(new S.Emitter),this.onRequestBell=this._onRequestBell.event,this._onRequestRefreshRows=this._register(new S.Emitter),this.onRequestRefreshRows=this._onRequestRefreshRows.event,this._onRequestReset=this._register(new S.Emitter),this.onRequestReset=this._onRequestReset.event,this._onRequestSendFocus=this._register(new S.Emitter),this.onRequestSendFocus=this._onRequestSendFocus.event,this._onRequestSyncScrollBar=this._register(new S.Emitter),this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event,this._onRequestWindowsOptionsReport=this._register(new S.Emitter),this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event,this._onA11yChar=this._register(new S.Emitter),this.onA11yChar=this._onA11yChar.event,this._onA11yTab=this._register(new S.Emitter),this.onA11yTab=this._onA11yTab.event,this._onCursorMove=this._register(new S.Emitter),this.onCursorMove=this._onCursorMove.event,this._onLineFeed=this._register(new S.Emitter),this.onLineFeed=this._onLineFeed.event,this._onScroll=this._register(new S.Emitter),this.onScroll=this._onScroll.event,this._onTitleChange=this._register(new S.Emitter),this.onTitleChange=this._onTitleChange.event,this._onColor=this._register(new S.Emitter),this.onColor=this._onColor.event,this._onRequestColorSchemeQuery=this._register(new S.Emitter),this.onRequestColorSchemeQuery=this._onRequestColorSchemeQuery.event,this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0},this._specialColors=[256,257,258],this._register(this._parser),this._dirtyRowTracker=new E(this._bufferService),this._activeBuffer=this._bufferService.buffer,this._register(this._bufferService.buffers.onBufferActivate(e=>this._activeBuffer=e.activeBuffer)),this._parser.setCsiHandlerFallback((e,t)=>{this._logService.debug("Unknown CSI code: ",{identifier:this._parser.identToString(e),params:t.toArray()})}),this._parser.setEscHandlerFallback(e=>{this._logService.debug("Unknown ESC code: ",{identifier:this._parser.identToString(e)})}),this._parser.setExecuteHandlerFallback(e=>{this._logService.debug("Unknown EXECUTE code: ",{code:e})}),this._parser.setOscHandlerFallback((e,t,i)=>{this._logService.debug("Unknown OSC code: ",{identifier:e,action:t,data:i})}),this._parser.setDcsHandlerFallback((e,t,i)=>{"HOOK"===t&&(i=i.toArray()),this._logService.debug("Unknown DCS code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setApcHandlerFallback((e,t,i)=>{this._logService.debug("Unknown APC code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setPrintHandler((e,t,i)=>this.print(e,t,i)),this._parser.registerCsiHandler({final:"@"},e=>this.insertChars(e)),this._parser.registerCsiHandler({intermediates:" ",final:"@"},e=>this.scrollLeft(e)),this._parser.registerCsiHandler({final:"A"},e=>this.cursorUp(e)),this._parser.registerCsiHandler({intermediates:" ",final:"A"},e=>this.scrollRight(e)),this._parser.registerCsiHandler({final:"B"},e=>this.cursorDown(e)),this._parser.registerCsiHandler({final:"C"},e=>this.cursorForward(e)),this._parser.registerCsiHandler({final:"D"},e=>this.cursorBackward(e)),this._parser.registerCsiHandler({final:"E"},e=>this.cursorNextLine(e)),this._parser.registerCsiHandler({final:"F"},e=>this.cursorPrecedingLine(e)),this._parser.registerCsiHandler({final:"G"},e=>this.cursorCharAbsolute(e)),this._parser.registerCsiHandler({final:"H"},e=>this.cursorPosition(e)),this._parser.registerCsiHandler({final:"I"},e=>this.cursorForwardTab(e)),this._parser.registerCsiHandler({final:"J"},e=>this.eraseInDisplay(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"J"},e=>this.eraseInDisplay(e,!0)),this._parser.registerCsiHandler({final:"K"},e=>this.eraseInLine(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"K"},e=>this.eraseInLine(e,!0)),this._parser.registerCsiHandler({final:"L"},e=>this.insertLines(e)),this._parser.registerCsiHandler({final:"M"},e=>this.deleteLines(e)),this._parser.registerCsiHandler({final:"P"},e=>this.deleteChars(e)),this._parser.registerCsiHandler({final:"S"},e=>this.scrollUp(e)),this._parser.registerCsiHandler({final:"T"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"X"},e=>this.eraseChars(e)),this._parser.registerCsiHandler({final:"Z"},e=>this.cursorBackwardTab(e)),this._parser.registerCsiHandler({final:"^"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"`"},e=>this.charPosAbsolute(e)),this._parser.registerCsiHandler({final:"a"},e=>this.hPositionRelative(e)),this._parser.registerCsiHandler({final:"b"},e=>this.repeatPrecedingCharacter(e)),this._parser.registerCsiHandler({final:"c"},e=>this.sendDeviceAttributesPrimary(e)),this._parser.registerCsiHandler({prefix:">",final:"c"},e=>this.sendDeviceAttributesSecondary(e)),this._parser.registerCsiHandler({final:"d"},e=>this.linePosAbsolute(e)),this._parser.registerCsiHandler({final:"e"},e=>this.vPositionRelative(e)),this._parser.registerCsiHandler({final:"f"},e=>this.hVPosition(e)),this._parser.registerCsiHandler({final:"g"},e=>this.tabClear(e)),this._parser.registerCsiHandler({final:"h"},e=>this.setMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"h"},e=>this.setModePrivate(e)),this._parser.registerCsiHandler({final:"l"},e=>this.resetMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"l"},e=>this.resetModePrivate(e)),this._parser.registerCsiHandler({final:"m"},e=>this.charAttributes(e)),this._parser.registerCsiHandler({final:"n"},e=>this.deviceStatus(e)),this._parser.registerCsiHandler({prefix:"?",final:"n"},e=>this.deviceStatusPrivate(e)),this._parser.registerCsiHandler({intermediates:"!",final:"p"},e=>this.softReset(e)),this._parser.registerCsiHandler({prefix:">",final:"q"},e=>this.sendXtVersion(e)),this._parser.registerCsiHandler({intermediates:" ",final:"q"},e=>this.setCursorStyle(e)),this._parser.registerCsiHandler({final:"r"},e=>this.setScrollRegion(e)),this._parser.registerCsiHandler({final:"s"},e=>this.saveCursor(e)),this._parser.registerCsiHandler({final:"t"},e=>this.windowOptions(e)),this._parser.registerCsiHandler({final:"u"},e=>this.restoreCursor(e)),this._parser.registerCsiHandler({intermediates:"'",final:"}"},e=>this.insertColumns(e)),this._parser.registerCsiHandler({intermediates:"'",final:"~"},e=>this.deleteColumns(e)),this._parser.registerCsiHandler({intermediates:'"',final:"q"},e=>this.selectProtected(e)),this._parser.registerCsiHandler({intermediates:"$",final:"p"},e=>this.requestMode(e,!0)),this._parser.registerCsiHandler({prefix:"?",intermediates:"$",final:"p"},e=>this.requestMode(e,!1)),this._parser.registerCsiHandler({prefix:"=",final:"u"},e=>this.kittyKeyboardSet(e)),this._parser.registerCsiHandler({prefix:"?",final:"u"},e=>this.kittyKeyboardQuery(e)),this._parser.registerCsiHandler({prefix:">",final:"u"},e=>this.kittyKeyboardPush(e)),this._parser.registerCsiHandler({prefix:"<",final:"u"},e=>this.kittyKeyboardPop(e)),this._parser.setExecuteHandler("",()=>this.bell()),this._parser.setExecuteHandler("\n",()=>this.lineFeed()),this._parser.setExecuteHandler("\v",()=>this.lineFeed()),this._parser.setExecuteHandler("\f",()=>this.lineFeed()),this._parser.setExecuteHandler("\r",()=>this.carriageReturn()),this._parser.setExecuteHandler("\b",()=>this.backspace()),this._parser.setExecuteHandler("\t",()=>this.tab()),this._parser.setExecuteHandler("",()=>this.shiftOut()),this._parser.setExecuteHandler("",()=>this.shiftIn()),this._parser.setExecuteHandler("„",()=>this.index()),this._parser.setExecuteHandler("…",()=>this.nextLine()),this._parser.setExecuteHandler("ˆ",()=>this.tabSet()),this._parser.registerOscHandler(0,new p.OscHandler(e=>(this.setTitle(e),this.setIconName(e),!0))),this._parser.registerOscHandler(1,new p.OscHandler(e=>this.setIconName(e))),this._parser.registerOscHandler(2,new p.OscHandler(e=>this.setTitle(e))),this._parser.registerOscHandler(4,new p.OscHandler(e=>this.setOrReportIndexedColor(e))),this._parser.registerOscHandler(8,new p.OscHandler(e=>this.setHyperlink(e))),this._parser.registerOscHandler(10,new p.OscHandler(e=>this.setOrReportFgColor(e))),this._parser.registerOscHandler(11,new p.OscHandler(e=>this.setOrReportBgColor(e))),this._parser.registerOscHandler(12,new p.OscHandler(e=>this.setOrReportCursorColor(e))),this._parser.registerOscHandler(104,new p.OscHandler(e=>this.restoreIndexedColor(e))),this._parser.registerOscHandler(110,new p.OscHandler(e=>this.restoreFgColor(e))),this._parser.registerOscHandler(111,new p.OscHandler(e=>this.restoreBgColor(e))),this._parser.registerOscHandler(112,new p.OscHandler(e=>this.restoreCursorColor(e))),this._parser.registerEscHandler({final:"7"},()=>this.saveCursor()),this._parser.registerEscHandler({final:"8"},()=>this.restoreCursor()),this._parser.registerEscHandler({final:"D"},()=>this.index()),this._parser.registerEscHandler({final:"E"},()=>this.nextLine()),this._parser.registerEscHandler({final:"H"},()=>this.tabSet()),this._parser.registerEscHandler({final:"M"},()=>this.reverseIndex()),this._parser.registerEscHandler({final:"="},()=>this.keypadApplicationMode()),this._parser.registerEscHandler({final:">"},()=>this.keypadNumericMode()),this._parser.registerEscHandler({final:"c"},()=>this.fullReset()),this._parser.registerEscHandler({final:"n"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"o"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"|"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"}"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"~"},()=>this.setgLevel(1)),this._parser.registerEscHandler({intermediates:"%",final:"@"},()=>this.selectDefaultCharset()),this._parser.registerEscHandler({intermediates:"%",final:"G"},()=>this.selectDefaultCharset());for(const e in o.CHARSETS)this._parser.registerEscHandler({intermediates:"(",final:e},()=>this.selectCharset("("+e)),this._parser.registerEscHandler({intermediates:")",final:e},()=>this.selectCharset(")"+e)),this._parser.registerEscHandler({intermediates:"*",final:e},()=>this.selectCharset("*"+e)),this._parser.registerEscHandler({intermediates:"+",final:e},()=>this.selectCharset("+"+e)),this._parser.registerEscHandler({intermediates:"-",final:e},()=>this.selectCharset("-"+e)),this._parser.registerEscHandler({intermediates:".",final:e},()=>this.selectCharset("."+e)),this._parser.registerEscHandler({intermediates:"/",final:e},()=>this.selectCharset("/"+e));this._parser.registerEscHandler({intermediates:"#",final:"8"},()=>this.screenAlignmentPattern()),this._parser.setErrorHandler(e=>(this._logService.error("Parsing error: ",e),e)),this._parser.registerDcsHandler({intermediates:"$",final:"q"},new v.DcsHandler((e,t)=>this.requestStatusString(e,t)))}_preserveStack(e,t,i,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=i,this._parseStack.position=s}_logSlowResolvingAsync(e){if(this._logService.logLevel<=u.LogLevelEnum.WARN){let t;const i=new Promise((e,i)=>{t=setTimeout(()=>i("#SLOW_TIMEOUT"),5e3)});Promise.race([e,i]).then(()=>{void 0!==t&&clearTimeout(t)},e=>{if(void 0!==t&&clearTimeout(t),"#SLOW_TIMEOUT"!==e)throw e;console.warn("async parser handler taking longer than 5000 ms")})}}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let i,s=this._activeBuffer.x,r=this._activeBuffer.y,o=0;const n=this._parseStack.paused;if(n){if(i=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(i),i;s=this._parseStack.cursorStartX,r=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>131072&&(o=this._parseStack.position+131072)}if(this._logService.logLevel<=u.LogLevelEnum.DEBUG&&this._logService.debug("parsing data "+("string"==typeof e?` "${e}"`:` "${Array.prototype.map.call(e,e=>String.fromCharCode(e)).join("")}"`)),this._logService.logLevel===u.LogLevelEnum.TRACE&&this._logService.trace("parsing data (codes)","string"==typeof e?e.split("").map(e=>e.charCodeAt(0)):e),this._parseBuffer.length131072)for(let t=o;t0&&2===p.getWidth(this._activeBuffer.x-1)&&p.setCellFromCodepoint(this._activeBuffer.x-1,0,1,u);let v=this._parser.precedingJoinState;for(let g=t;ga)if(d){const e=p;let t=this._activeBuffer.x-m;if(this._activeBuffer.x=m,this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData(),!0)):(this._activeBuffer.y>=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),p=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y),!p)return;for(m>0&&p instanceof l.BufferLine&&p.copyCellsFrom(e,t,0,m,!1);t=0;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u);continue}if(_&&(p.insertCells(this._activeBuffer.x,r-m,this._activeBuffer.getNullCell(u)),2===p.getWidth(a-1)&&p.setCellFromCodepoint(a-1,c.NULL_CELL_CODE,c.NULL_CELL_WIDTH,u)),p.setCellFromCodepoint(this._activeBuffer.x++,s,r,u),r>0)for(;--r;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u)}this._parser.precedingJoinState=v,this._activeBuffer.x0&&0===p.getWidth(this._activeBuffer.x)&&!p.hasContent(this._activeBuffer.x)&&p.setCellFromCodepoint(this._activeBuffer.x,0,1,u),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return"t"!==e.final||e.prefix||e.intermediates?this._parser.registerCsiHandler(e,t):this._parser.registerCsiHandler(e,e=>!y(e.params[0],this._optionsService.rawOptions.windowOptions)||t(e))}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new v.DcsHandler(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new p.OscHandler(t))}registerApcHandler(e,t){return this._parser.registerApcHandler(e,new g.ApcHandler(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(0===this._activeBuffer.x&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)?.isWrapped){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;const e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){const t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){const t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){const t=e.params[0];return 0===t?delete this._activeBuffer.tabs[this._activeBuffer.x]:3===t&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){const t=e.params[0];return 1===t&&(this._curAttrData.bg|=536870912),2!==t&&0!==t||(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,i,s=!1,r=!1){const o=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);o&&(o.replaceCells(t,i,this._activeBuffer.getNullCell(this._eraseAttrData()),r),s&&(o.isWrapped=!1))}_resetBufferLine(e,t=!1){const i=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);i&&(i.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),i.isWrapped=!1)}eraseInDisplay(e,t=!1){let i;switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:for(i=this._activeBuffer.y,this._dirtyRowTracker.markDirty(i),this._eraseInBufferLine(i++,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);i=this._bufferService.cols){const e=this._activeBuffer.lines.get(i+1);e&&(e.isWrapped=!1)}for(;i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 2:if(this._optionsService.rawOptions.scrollOnEraseInDisplay){for(i=this._bufferService.rows,this._dirtyRowTracker.markRangeDirty(0,i-1);i--;){const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+i);if(e?.getTrimmedLength())break}for(;i>=0;i--)this._bufferService.scroll(this._eraseAttrData())}else{for(i=this._bufferService.rows,this._dirtyRowTracker.markDirty(i-1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0)}break;case 3:const e=this._activeBuffer.lines.length-this._bufferService.rows;e>0&&(this._activeBuffer.lines.trimStart(e),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-e,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-e,0),this._onScroll.fire(0))}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t)}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y65535?2:1}let h=a;for(let e=1;e0||(this._is("xterm")||this._is("rxvt-unicode")||this._is("screen")?this._coreService.triggerDataEvent("[?1;2c"):this._is("linux")&&this._coreService.triggerDataEvent("[?6c")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is("xterm")?this._coreService.triggerDataEvent("[>0;276;0c"):this._is("rxvt-unicode")?this._coreService.triggerDataEvent("[>85;95;0c"):this._is("linux")?this._coreService.triggerDataEvent(e.params[0]+"c"):this._is("screen")&&this._coreService.triggerDataEvent("[>83;40003;0c")),!0}sendXtVersion(e){return e.params[0]>0||this._coreService.triggerDataEvent(`P>|xterm.js(${b.XTERM_VERSION})\\`),!0}_is(e){return(this._optionsService.rawOptions.termName+"").startsWith(e)}setMode(e){for(let t=0;t(o.triggerDataEvent(`[${t?"":"?"}${e};${i}$y`),!0),_=e=>e?1:2,u=e.params[0];return t?d(u,2===u?4:4===u?_(o.modes.insertMode):12===u?3:20===u?_(c.convertEol):0):1===u?d(u,_(i.applicationCursorKeys)):3===u?d(u,c.windowOptions.setWinLines?80===a?2:132===a?1:0:0):6===u?d(u,_(i.origin)):7===u?d(u,_(i.wraparound)):8===u?d(u,3):9===u?d(u,_("X10"===s)):12===u?d(u,_(c.cursorBlink)):25===u?d(u,_(!o.isCursorHidden)):45===u?d(u,_(i.reverseWraparound)):66===u?d(u,_(i.applicationKeypad)):67===u?d(u,4):1e3===u?d(u,_("VT200"===s)):1002===u?d(u,_("DRAG"===s)):1003===u?d(u,_("ANY"===s)):1004===u?d(u,_(i.sendFocus)):1005===u?d(u,4):1006===u?d(u,_("SGR"===r)):1015===u?d(u,4):1016===u?d(u,_("SGR_PIXELS"===r)):1048===u?d(u,1):47===u||1047===u||1049===u?d(u,_(h===l)):2004===u?d(u,_(i.bracketedPasteMode)):2026===u?d(u,_(i.synchronizedOutput)):9001===u&&this._optionsService.rawOptions.vtExtensions?.win32InputMode?d(u,_(i.win32InputMode)):d(u,0)}_updateAttrColor(e,t,i,s,r){return 2===t?(e|=50331648,e&=-16777216,e|=_.AttributeData.fromColorRGB([i,s,r])):5===t&&(e&=-67108864,e|=33554432|255&i),e}_extractColor(e,t,i){const s=[0,0,-1,0,0,0];let r=0,o=0;do{if(s[o+r]=e.params[t+o],e.hasSubParams(t+o)){const i=e.getSubParams(t+o);let n=0;do{5===s[1]&&(r=1),s[o+n+1+r]=i[n]}while(++n=2||2===s[1]&&o+r>=5)break;s[1]&&(r=1)}while(++o+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,0===e&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=l.DEFAULT_ATTR_DATA.fg,e.bg=l.DEFAULT_ATTR_DATA.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(1===e.length&&0===e.params[0])return this._processSGR0(this._curAttrData),!0;const t=e.length;let i;const s=this._curAttrData;for(let r=0;r=30&&i<=37?(s.fg&=-67108864,s.fg|=16777216|i-30):i>=40&&i<=47?(s.bg&=-67108864,s.bg|=16777216|i-40):i>=90&&i<=97?(s.fg&=-67108864,s.fg|=16777224|i-90):i>=100&&i<=107?(s.bg&=-67108864,s.bg|=16777224|i-100):0===i?this._processSGR0(s):1===i?s.fg|=134217728:3===i?s.bg|=67108864:4===i?(s.fg|=268435456,this._processUnderline(e.hasSubParams(r)?e.getSubParams(r)[0]:1,s)):5===i?s.fg|=536870912:7===i?s.fg|=67108864:8===i?s.fg|=1073741824:9===i?s.fg|=2147483648:2===i?s.bg|=134217728:21===i?this._processUnderline(2,s):22===i?(s.fg&=-134217729,s.bg&=-134217729):23===i?s.bg&=-67108865:24===i?(s.fg&=-268435457,this._processUnderline(0,s)):25===i?s.fg&=-536870913:27===i?s.fg&=-67108865:28===i?s.fg&=-1073741825:29===i?s.fg&=2147483647:39===i?(s.fg&=-67108864,s.fg|=16777215&l.DEFAULT_ATTR_DATA.fg):49===i?(s.bg&=-67108864,s.bg|=16777215&l.DEFAULT_ATTR_DATA.bg):38===i||48===i||58===i?r+=this._extractColor(e,r,s):53===i?s.bg|=1073741824:55===i?s.bg&=-1073741825:221===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.fg&=-134217729:222===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.bg&=-134217729:59===i?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):this._logService.debug("Unknown SGR attribute: %d.",i);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent("");break;case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[${e};${t}R`)}return!0}deviceStatusPrivate(e){switch(e.params[0]){case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[?${e};${t}R`);break;case 15:case 25:case 26:case 53:break;case 996:(this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery??1)&&this._onRequestColorSchemeQuery.fire()}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){const t=0===e.length?1:e.params[0];if(0===t)this._coreService.decPrivateModes.cursorStyle=void 0,this._coreService.decPrivateModes.cursorBlink=void 0;else{switch(t){case 1:case 2:this._coreService.decPrivateModes.cursorStyle="block";break;case 3:case 4:this._coreService.decPrivateModes.cursorStyle="underline";break;case 5:case 6:this._coreService.decPrivateModes.cursorStyle="bar"}const e=t%2==1;this._coreService.decPrivateModes.cursorBlink=e}return!0}setScrollRegion(e){const t=e.params[0]||1;let i;return(e.length<2||(i=e.params[1])>this._bufferService.rows||0===i)&&(i=this._bufferService.rows),i>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=i-1,this._setCursor(0,0)),!0}windowOptions(e){if(!y(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;const t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:2!==t&&this._onRequestWindowsOptionsReport.fire(C.GET_WIN_SIZE_PIXELS);break;case 16:this._onRequestWindowsOptionsReport.fire(C.GET_CELL_SIZE_PIXELS);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:0!==t&&2!==t||(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),0!==t&&1!==t||(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:0!==t&&2!==t||this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),0!==t&&1!==t||this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop())}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._activeBuffer.savedCharsets=this._charsetService.charsets.slice(),this._activeBuffer.savedGlevel=this._charsetService.glevel,this._activeBuffer.savedOriginMode=this._coreService.decPrivateModes.origin,this._activeBuffer.savedWraparoundMode=this._coreService.decPrivateModes.wraparound,!0}restoreCursor(e){this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg;for(let e=0;e1;){const e=i.shift(),s=i.shift();if(/^\d+$/.exec(e)){const i=parseInt(e,10);if(L(i))if("?"===s)t.push({type:0,index:i});else{const e=(0,m.parseColor)(s);e&&t.push({type:1,index:i,color:e})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){const t=e.indexOf(";");if(-1===t)return!0;const i=e.slice(0,t).trim(),s=e.slice(t+1);return s?this._createHyperlink(i,s):!i.trim()&&this._finishHyperlink()}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();const i=e.split(":");let s;const r=i.findIndex(e=>e.startsWith("id="));return-1!==r&&(s=i[r].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){const i=e.split(";");for(let e=0;e=this._specialColors.length);++e,++t)if("?"===i[e])this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{const s=(0,m.parseColor)(i[e]);s&&this._onColor.fire([{type:1,index:this._specialColors[t],color:s}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;const t=[],i=e.split(";");for(let e=0;e=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){const e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=67108863&this._curAttrData.bg,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){const e=new d.CellData;e.content=1<<22|"E".charCodeAt(0),e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`${e}\\`),!0))('"q'===e?`P1$r${this._curAttrData.isProtected()?1:0}"q`:'"p'===e?'P1$r61;1"p':"r"===e?`P1$r${i.scrollTop+1};${i.scrollBottom+1}r`:"m"===e?"P1$r0m":" q"===e?`P1$r${{block:2,underline:4,bar:6}[s.cursorStyle]-(s.cursorBlink?1:0)} q`:"P0$r")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}kittyKeyboardSet(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=e.length>1&&e.params[1]||1,s=this._coreService.kittyKeyboard;switch(i){case 1:s.flags=t;break;case 2:s.flags|=t;break;case 3:s.flags&=~t}return!0}kittyKeyboardQuery(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=this._coreService.kittyKeyboard.flags;return this._coreService.triggerDataEvent(`[?${t}u`),!0}kittyKeyboardPush(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;return s.length>=16&&s.shift(),s.push(i.flags),i.flags=t,!0}kittyKeyboardPop(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=Math.max(1,e.params[0]||1),i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;for(let e=0;e0;e++)i.flags=s.pop();return 0===s.length&&t>0&&(i.flags=0),!0}}t.InputHandler=D;let E=class{constructor(e){this._bufferService=e,this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(e){ethis.end&&(this.end=e)}markRangeDirty(e,t){e>t&&(k=e,e=t,t=k),ethis.end&&(this.end=t)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};function L(e){return 0<=e&&e<256}E=s([r(0,u.IBufferService)],E)},4812(e,t){function i(e){return{dispose:e}}function s(e){if(!e)return e;if(Array.isArray(e)){for(const t of e)t.dispose();return[]}return e.dispose(),e}Object.defineProperty(t,"__esModule",{value:!0}),t.MutableDisposable=t.Disposable=t.DisposableStore=void 0,t.toDisposable=i,t.dispose=s,t.combinedDisposable=function(...e){return i(()=>s(e))};class r{constructor(){this._disposables=new Set,this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(e){return this._isDisposed?e.dispose():this._disposables.add(e),e}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.clear()}}clear(){for(const e of this._disposables)e.dispose();this._disposables.clear()}}t.DisposableStore=r;class o{constructor(){this._store=new r}dispose(){this._store.dispose()}_register(e){return this._store.add(e)}}t.Disposable=o,o.None=Object.freeze({dispose(){}}),t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}}},7710(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.FourKeyMap=t.TwoKeyMap=void 0;class i{constructor(){this._data={}}set(e,t,i){this._data[e]||(this._data[e]={}),this._data[e][t]=i}get(e,t){return this._data[e]?this._data[e][t]:void 0}clear(){this._data={}}}t.TwoKeyMap=i,t.FourKeyMap=class{constructor(){this._data=new i}set(e,t,s,r,o){this._data.get(e,t)||this._data.set(e,t,new i),this._data.get(e,t).set(s,r,o)}get(e,t,i,s){return this._data.get(e,t)?.get(i,s)}clear(){this._data.clear()}}},701(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.isChromeOS=t.isLinux=t.isWindows=t.isMac=t.isSafari=t.isLegacyEdge=t.isChrome=t.isFirefox=t.isNode=void 0,t.getZoomFactor=function(e){return 1},t.getSafariVersion=function(){if(!t.isSafari)return 0;const e=i.match(/Version\/(\d+)/);return null===e||e.length<2?0:parseInt(e[1],10)},t.isNode=!("undefined"==typeof process||!("title"in process)||"undefined"!=typeof navigator&&!navigator.userAgent.startsWith("Node.js/"));const i=t.isNode?"node":navigator.userAgent,s=t.isNode?"node":navigator.platform;t.isFirefox=i.includes("Firefox"),t.isChrome=i.includes("Chrome"),t.isLegacyEdge=i.includes("Edge"),t.isSafari=/^((?!chrome|android).)*safari/i.test(i),t.isMac=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(s),t.isWindows=["Windows","Win16","Win32","WinCE"].includes(s),t.isLinux=s.indexOf("Linux")>=0,t.isChromeOS=/\bCrOS\b/.test(i)},3087(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.SortedList=void 0;const s=i(6168);let r=0;t.SortedList=class{constructor(e,t){this._getKey=e,this._array=[],this._insertedValues=[],this._isFlushingInserted=!1,this._deletedIndices=[],this._isFlushingDeleted=!1,this._flushInsertedTask=new s.IdleTaskQueue(t),this._flushDeletedTask=new s.IdleTaskQueue(t)}clear(){this._array.length=0,this._insertedValues.length=0,this._flushInsertedTask.clear(),this._isFlushingInserted=!1,this._deletedIndices.length=0,this._flushDeletedTask.clear(),this._isFlushingDeleted=!1}insert(e){this._flushCleanupDeleted(),0===this._insertedValues.length&&this._flushInsertedTask.enqueue(()=>this._flushInserted()),this._insertedValues.push(e)}_flushInserted(){const e=this._insertedValues.sort((e,t)=>this._getKey(e)-this._getKey(t));let t=0,i=0;const s=new Array(this._array.length+this._insertedValues.length);for(let r=0;r=this._array.length||this._getKey(e[t])<=this._getKey(this._array[i])?(s[r]=e[t],t++):s[r]=this._array[i++];this._array=s,this._insertedValues.length=0}_flushCleanupInserted(){!this._isFlushingInserted&&this._insertedValues.length>0&&this._flushInsertedTask.flush()}delete(e){if(this._flushCleanupInserted(),0===this._array.length)return!1;const t=this._getKey(e);if(void 0===t)return!1;if(r=this._search(t),-1===r)return!1;if(this._getKey(this._array[r])!==t)return!1;do{if(this._array[r]===e)return 0===this._deletedIndices.length&&this._flushDeletedTask.enqueue(()=>this._flushDeleted()),this._deletedIndices.push(r),!0}while(++re-t);let t=0;const i=new Array(this._array.length-e.length);let s=0;for(let r=0;r0&&this._flushDeletedTask.flush()}*getKeyIterator(e){if(this._flushCleanupInserted(),this._flushCleanupDeleted(),0!==this._array.length&&(r=this._search(e),!(r<0||r>=this._array.length)&&this._getKey(this._array[r])===e))do{yield this._array[r]}while(++r=this._array.length)&&this._getKey(this._array[r])===e))do{t(this._array[r])}while(++r=t;){let s=t+i>>1;const r=this._getKey(this._array[s]);if(r>e)i=s-1;else{if(!(r0&&this._getKey(this._array[s-1])===e;)s--;return s}t=s+1}}return t}}},4220(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.LimitedStringBuilder=t.StringBuilder=void 0;class i{constructor(){this._chunks=[],this._length=0}get length(){return this._length}reset(){this._chunks.length=0,this._length=0}append(e){this._chunks.push(e),this._length+=e.length}toString(){return this._chunks.join("")}}t.StringBuilder=i,t.LimitedStringBuilder=class{constructor(e){this._limit=e,this._builder=new i}get length(){return this._builder.length}get limit(){return this._limit}reset(){this._builder.reset()}append(e){return this._builder.append(e),this._builder.length>this._limit&&(this._builder.reset(),!0)}toString(){return this._builder.toString()}}},6168(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DebouncedIdleTask=t.IdleTaskQueue=t.PriorityTaskQueue=void 0;class i{constructor(e){this._tasks=[],this._i=0,this._logService=e}enqueue(e){this._tasks.push(e),this._start()}flush(){for(;this._ii)return r-t<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-t))}ms`),void this._start();r=i}this.clear()}}class s extends i{_requestCallback(e){return setTimeout(()=>e(this._createDeadline(16)))}_cancelCallback(e){clearTimeout(e)}_createDeadline(e){const t=performance.now()+e;return{timeRemaining:()=>Math.max(0,t-performance.now())}}}t.PriorityTaskQueue=s,t.IdleTaskQueue="requestIdleCallback"in globalThis?class extends i{_requestCallback(e){return requestIdleCallback(e)}_cancelCallback(e){cancelIdleCallback(e)}}:s,t.DebouncedIdleTask=class{constructor(e){this._queue=new t.IdleTaskQueue(e)}set(e){this._queue.clear(),this._queue.enqueue(e)}flush(){this._queue.flush()}dispose(){this._queue.clear()}}},7804(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.XTERM_VERSION=void 0,t.XTERM_VERSION="6.1.0-beta.287"},5882(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.updateWindowsModeWrappedState=function(e){const t=e.buffer.lines.get(e.buffer.ybase+e.buffer.y-1),i=t?.get(e.cols-1),r=e.buffer.lines.get(e.buffer.ybase+e.buffer.y);r&&i&&(r.isWrapped=i[s.CHAR_DATA_CODE_INDEX]!==s.NULL_CELL_CODE&&i[s.CHAR_DATA_CODE_INDEX]!==s.WHITESPACE_CELL_CODE)};const s=i(8938)},5451(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ExtendedAttrs=t.AttributeData=void 0;class i{constructor(){this.fg=0,this.bg=0,this.extended=new s}static toColorRGB(e){return[e>>>16&255,e>>>8&255,255&e]}static fromColorRGB(e){return(255&e[0])<<16|(255&e[1])<<8|255&e[2]}clone(){const e=new i;return e.fg=this.fg,e.bg=this.bg,e.extended=this.extended.clone(),e}isInverse(){return 67108864&this.fg}isBold(){return 134217728&this.fg}isUnderline(){return this.hasExtendedAttrs()&&0!==this.extended.underlineStyle?1:268435456&this.fg}isBlink(){return 536870912&this.fg}isInvisible(){return 1073741824&this.fg}isItalic(){return 67108864&this.bg}isDim(){return 134217728&this.bg}isStrikethrough(){return 2147483648&this.fg}isProtected(){return 536870912&this.bg}isOverline(){return 1073741824&this.bg}getFgColorMode(){return 50331648&this.fg}getBgColorMode(){return 50331648&this.bg}isFgRGB(){return!(50331648&~this.fg)}isBgRGB(){return!(50331648&~this.bg)}isFgPalette(){return 16777216==(50331648&this.fg)||33554432==(50331648&this.fg)}isBgPalette(){return 16777216==(50331648&this.bg)||33554432==(50331648&this.bg)}isFgDefault(){return!(50331648&this.fg)}isBgDefault(){return!(50331648&this.bg)}isAttributeDefault(){return 0===this.fg&&0===this.bg}getFgColor(){switch(50331648&this.fg){case 16777216:case 33554432:return 255&this.fg;case 50331648:return 16777215&this.fg;default:return-1}}getBgColor(){switch(50331648&this.bg){case 16777216:case 33554432:return 255&this.bg;case 50331648:return 16777215&this.bg;default:return-1}}hasExtendedAttrs(){return 268435456&this.bg}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(268435456&this.bg&&~this.extended.underlineColor)switch(50331648&this.extended.underlineColor){case 16777216:case 33554432:return 255&this.extended.underlineColor;case 50331648:return 16777215&this.extended.underlineColor;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return 268435456&this.bg&&~this.extended.underlineColor?50331648&this.extended.underlineColor:this.getFgColorMode()}isUnderlineColorRGB(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&~this.extended.underlineColor):this.isFgRGB()}isUnderlineColorPalette(){return 268435456&this.bg&&~this.extended.underlineColor?16777216==(50331648&this.extended.underlineColor)||33554432==(50331648&this.extended.underlineColor):this.isFgPalette()}isUnderlineColorDefault(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&this.extended.underlineColor):this.isFgDefault()}getUnderlineStyle(){return 268435456&this.fg?268435456&this.bg?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}}t.AttributeData=i;class s{get ext(){return this._urlId?-469762049&this._ext|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(469762048&this._ext)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return 67108863&this._ext}set underlineColor(e){this._ext&=-67108864,this._ext|=67108863&e}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){const e=(3758096384&this._ext)>>29;return e<0?4294967288^e:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}clone(){return new s(this._ext,this._urlId)}isEmpty(){return 0===this.underlineStyle&&0===this._urlId}}t.ExtendedAttrs=s},1073(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Buffer=t.MAX_BUFFER_SIZE=void 0;const s=i(5639),r=i(4812),o=i(6168),n=i(5451),a=i(6107),h=i(3326),l=i(732),c=i(3055),d=i(8938),_=i(8158),u=i(6760);t.MAX_BUFFER_SIZE=4294967295;class f extends r.Disposable{constructor(e,t,i,n){super(),this._hasScrollback=e,this._optionsService=t,this._bufferService=i,this._logService=n,this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.tabs={},this.savedY=0,this.savedX=0,this.savedCurAttrData=a.DEFAULT_ATTR_DATA.clone(),this.savedCharset=u.DEFAULT_CHARSET,this.savedCharsets=[],this.savedGlevel=0,this.savedOriginMode=!1,this.savedWraparoundMode=!0,this.markers=[],this._nullCell=c.CellData.fromCharData([0,d.NULL_CELL_CHAR,d.NULL_CELL_WIDTH,d.NULL_CELL_CODE]),this._whitespaceCell=c.CellData.fromCharData([0,d.WHITESPACE_CELL_CHAR,d.WHITESPACE_CELL_WIDTH,d.WHITESPACE_CELL_CODE]),this._isClearing=!1,this._memoryCleanupPosition=0,this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops(),this._memoryCleanupQueue=new o.IdleTaskQueue(this._logService),this._register((0,r.toDisposable)(()=>this._memoryCleanupQueue.clear())),this._register((0,r.toDisposable)(()=>this.clearAllMarkers())),this._stringCache=this._register(new h.BufferLineStringCache)}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new n.ExtendedAttrs),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new n.ExtendedAttrs),this._whitespaceCell}getBlankLine(e,t){return new a.BufferLine(this._stringCache,this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){const e=this.ybase+this.y-this.ydisp;return e>=0&&et.MAX_BUFFER_SIZE?t.MAX_BUFFER_SIZE:i}fillViewportRows(e){if(0===this.lines.length){e??=a.DEFAULT_ATTR_DATA;let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this._stringCache.clear(),this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){const i=this.getNullCell(a.DEFAULT_ATTR_DATA);this._stringCache.clear();let s=0;const r=this._getCorrectBufferLength(t);if(r>this.lines.maxLength&&(this.lines.maxLength=r),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+o+1?(this.ybase--,o++,this.ydisp>0&&this.ydisp--):this.lines.push(new a.BufferLine(this._stringCache,e,i,!1)));else for(let e=this._rows;e>t;e--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(r0&&(this.lines.trimStart(e),this.ybase=Math.max(this.ybase-e,0),this.ydisp=Math.max(this.ydisp-e,0),this.savedY=Math.max(this.savedY-e,0)),this.lines.maxLength=r}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),o&&(this.y+=o),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let t=0;t0){const e=Math.max(0,this.lines.length-this.ybase-1);this.y=Math.min(this.y,e)}this._memoryCleanupQueue.clear(),s>.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue(()=>this._batchedMemoryCleanup()))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){const e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&"conpty"===e.backend&&e.buildNumber>=21376:this._hasScrollback}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){const i=this._optionsService.rawOptions.reflowCursorLine,s=(0,l.reflowLargerGetLinesToRemove)(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(a.DEFAULT_ATTR_DATA),i);if(s.length>0){const i=(0,l.reflowLargerCreateNewLayout)(this.lines,s);(0,l.reflowLargerApplyNewLayout)(this.lines,i.layout),this._reflowLargerAdjustViewport(e,t,i.countRemoved)}}_reflowLargerAdjustViewport(e,t,i){const s=this.getNullCell(a.DEFAULT_ATTR_DATA);let r=i;for(;r-- >0;)0===this.ybase?(this.y>0&&this.y--,this.lines.length=0;n--){let h=this.lines.get(n);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;const c=[h];for(;h.isWrapped&&n>0;)h=this.lines.get(--n),c.unshift(h);if(!i){const e=this.ybase+this.y;if(e>=n&&e0&&(r.push({start:n+c.length+o,newLines:p}),o+=p.length),c.push(...p);let v=_.length-1,g=_[v];0===g&&(v--,g=_[v]);let m=c.length-u-1,S=d;for(;m>=0;){const e=Math.min(S,g);if(void 0===c[v])break;if(c[v].copyCellsFrom(c[m],S-e,g-e,e,!0),g-=e,0===g&&(v--,g=_[v]),S-=e,0===S){m--;const e=Math.max(m,0);S=(0,l.getWrappedLineTrimmedLength)(c,e,this._cols)}}for(let t=0;t0;)0===this.ybase?this.y0){const e=[],t=[];for(let e=0;e=0;l--)if(a&&a.start>s+h){for(let e=a.newLines.length-1;e>=0;e--)this.lines.set(l--,a.newLines[e]);l++,e.push({index:s+1,amount:a.newLines.length}),h+=a.newLines.length,a=r[++n]}else this.lines.set(l,t[s--]);let l=0;for(let t=e.length-1;t>=0;t--)e[t].index+=l,this.lines.onInsertEmitter.fire(e[t]),l+=e[t].amount;const c=Math.max(0,i+o-this.lines.maxLength);c>0&&this.lines.onTrimEmitter.fire(c)}}translateBufferLineToString(e,t,i=0,s){const r=this.lines.get(e);return r?r.translateToString(t,i,s):""}getWrappedRangeForLine(e){let t=e,i=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;i+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(e??=this.x;!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=e,t.line<0&&t.dispose()})),t.register(this.lines.onInsert(e=>{t.line>=e.index&&(t.line+=e.amount)})),t.register(this.lines.onDelete(e=>{t.line>=e.index&&t.linee.index&&(t.line-=e.amount)})),t.register(t.onDispose(()=>this._removeMarker(t))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}}t.Buffer=f},6107(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferLine=t.DEFAULT_ATTR_DATA=void 0;const s=i(5451),r=i(3055),o=i(8938),n=i(726),a=i(4220);t.DEFAULT_ATTR_DATA=Object.freeze(new s.AttributeData);let h=0;const l=new r.CellData,c=new a.StringBuilder;class d{constructor(e,t,i,s=!1){this._stringCache=e,this.isWrapped=s,this._combined={},this._extendedAttrs={},this._data=new Uint32Array(3*t);const n=i??r.CellData.fromCharData([0,o.NULL_CELL_CHAR,o.NULL_CELL_WIDTH,o.NULL_CELL_CODE]);for(let e=0;e>22,2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):i]}set(e,t){this._invalidateStringCache(),this._data[3*e+1]=t[o.CHAR_DATA_ATTR_INDEX],t[o.CHAR_DATA_CHAR_INDEX].length>1?(this._combined[e]=t[1],this._data[3*e+0]=2097152|e|t[o.CHAR_DATA_WIDTH_INDEX]<<22):this._data[3*e+0]=t[o.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|t[o.CHAR_DATA_WIDTH_INDEX]<<22}getWidth(e){return this._data[3*e+0]>>22}hasWidth(e){return 12582912&this._data[3*e+0]}getFg(e){return this._data[3*e+1]}getBg(e){return this._data[3*e+2]}hasContent(e){return 4194303&this._data[3*e+0]}getCodePoint(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):2097151&t}isCombined(e){return 2097152&this._data[3*e+0]}getString(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e]:2097151&t?(0,n.stringFromCodePoint)(2097151&t):""}isProtected(e){return 536870912&this._data[3*e+2]}loadCell(e,i){return h=3*e,i.content=this._data[h+0],i.fg=this._data[h+1],i.bg=this._data[h+2],2097152&i.content?i.combinedData=this._combined[e]:i.combinedData="",268435456&i.bg?i.extended=this._extendedAttrs[e]:i.extended=t.DEFAULT_ATTR_DATA.extended.clone(),i}setCell(e,t){this._invalidateStringCache(),2097152&t.content&&(this._combined[e]=t.combinedData),268435456&t.bg&&(this._extendedAttrs[e]=t.extended),this._data[3*e+0]=t.content,this._data[3*e+1]=t.fg,this._data[3*e+2]=t.bg}setCellFromCodepoint(e,t,i,s){this._invalidateStringCache(),268435456&s.bg&&(this._extendedAttrs[e]=s.extended),this._data[3*e+0]=t|i<<22,this._data[3*e+1]=s.fg,this._data[3*e+2]=s.bg}addCodepointToCell(e,t,i){this._invalidateStringCache();let s=this._data[3*e+0];2097152&s?this._combined[e]+=(0,n.stringFromCodePoint)(t):2097151&s?(this._combined[e]=(0,n.stringFromCodePoint)(2097151&s)+(0,n.stringFromCodePoint)(t),s&=-2097152,s|=2097152):s=t|1<<22,i&&(s&=-12582913,s|=i<<22),this._data[3*e+0]=s}insertCells(e,t,i){if(this._invalidateStringCache(),(e%=this.length)&&2===this.getWidth(e-1)&&this.setCellFromCodepoint(e-1,0,1,i),t=0;--i)this.setCell(e+t+i,this.loadCell(e+i,l));for(let s=0;sthis.length){if(this._data.buffer.byteLength>=4*i)this._data=new Uint32Array(this._data.buffer,0,i);else{const e=new Uint32Array(i);e.set(this._data),this._data=e}for(let i=this.length;i=e&&delete this._combined[s]}const s=Object.keys(this._extendedAttrs);for(let t=0;t=e&&delete this._extendedAttrs[i]}}return this.length=e,4*i*2=0;--e)if(4194303&this._data[3*e+0])return e+(this._data[3*e+0]>>22);return 0}getNoBgTrimmedLength(){for(let e=this.length-1;e>=0;--e)if(4194303&this._data[3*e+0]||50331648&this._data[3*e+2])return e+(this._data[3*e+0]>>22);return 0}copyCellsFrom(e,t,i,s,r){this._invalidateStringCache();const o=e._data;if(r)for(let r=s-1;r>=0;r--){for(let e=0;e<3;e++)this._data[3*(i+r)+e]=o[3*(t+r)+e];this._copyCellMapsFrom(e,t+r,i+r)}else for(let r=0;r>22||1}s&&s.push(t);const h=c.toString();if(c.reset(),r){const t=this._getStringCacheEntry(!0);t.value=h,t.isTrimmed=!!e}return h}_getStringCacheEntry(e){const t=this._stringCacheEntryRef?.deref();if(t&&t.generation===this._stringCache.generation)return t;if(!e)return;const i=this._stringCache.allocateEntry();return this._stringCacheEntryRef=new WeakRef(i),i}_invalidateStringCache(){const e=this._getStringCacheEntry(!1);e&&(e.value=void 0,e.isTrimmed=!1)}_copyCellMapsFrom(e,t,i){const s=3*t;2097152&e._data[s+0]&&(this._combined[i]=e._combined[t]),268435456&e._data[s+2]&&(this._extendedAttrs[i]=e._extendedAttrs[t])}_copySparseMapsFrom(e){this._combined={},this._extendedAttrs={};for(let t=0;tthis.entries.clear()))}touch(){this._scheduleClear()}allocateEntry(){const e={value:void 0,isTrimmed:!1,generation:this.generation};return this.entries.add(e),this._scheduleClear(),e}clear(){this._clearTimeout.clear(),this._lastAccessTimestamp=0,this.generation++;for(const e of this.entries)e.value=void 0,e.isTrimmed=!1;this.entries.clear()}_scheduleClear(){this._lastAccessTimestamp=Date.now(),this._clearTimeout.value||this._scheduleClearTimeout(15e3)}_scheduleClearTimeout(e){this._clearTimeout.value=(0,s.disposableTimeout)(()=>{const e=Date.now()-this._lastAccessTimestamp;e>=15e3?this.clear():this._scheduleClearTimeout(15e3-e)},e)}}t.BufferLineStringCache=o},9384(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.getRangeLength=function(e,t){if(e.start.y>e.end.y)throw new Error(`Buffer range end (${e.end.x}, ${e.end.y}) cannot be before start (${e.start.x}, ${e.start.y})`);return t*(e.end.y-e.start.y)+(e.end.x-e.start.x+1)}},732(e,t){function i(e,t,i){if(t===e.length-1)return e[t].getTrimmedLength();const s=!e[t].hasContent(i-1)&&1===e[t].getWidth(i-1),r=2===e[t+1].getWidth(0);return s&&r?i-1:i}Object.defineProperty(t,"__esModule",{value:!0}),t.reflowLargerGetLinesToRemove=function(e,t,s,r,o,n){const a=[];for(let h=0;h=h&&r0&&(e>_||0===d[e].getTrimmedLength());e--)v++;v>0&&(a.push(h+d.length-v),a.push(v)),h+=d.length-1}return a},t.reflowLargerCreateNewLayout=function(e,t){const i=[];let s=0,r=t[s],o=0;for(let n=0;nl&&(n-=l,a++);const c=2===e[a].getWidth(n-1);c&&n--;const d=c?s-1:s;r.push(d),h+=d}return r},t.getWrappedLineTrimmedLength=i},4097(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferSet=void 0;const s=i(4812),r=i(1073),o=i(8636);class n extends s.Disposable{constructor(e,t,i){super(),this._optionsService=e,this._bufferService=t,this._logService=i,this._normalBuffer=this._register(new s.MutableDisposable),this._altBuffer=this._register(new s.MutableDisposable),this._onBufferActivate=this._register(new o.Emitter),this.onBufferActivate=this._onBufferActivate.event,this.reset(),this._register(this._optionsService.onSpecificOptionChange("scrollback",()=>this.resize(this._bufferService.cols,this._bufferService.rows))),this._register(this._optionsService.onSpecificOptionChange("tabStopWidth",()=>this.setupTabStops()))}reset(){this._normal=new r.Buffer(!0,this._optionsService,this._bufferService,this._logService),this._normalBuffer.value=this._normal,this._normal.fillViewportRows(),this._alt=new r.Buffer(!1,this._optionsService,this._bufferService,this._logService),this._altBuffer.value=this._alt,this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}}t.BufferSet=n},3055(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CellData=void 0;const s=i(726),r=i(8938),o=i(5451);class n extends o.AttributeData{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new o.ExtendedAttrs,this.combinedData=""}static fromCharData(e){const t=new n;return t.setFromCharData(e),t}isCombined(){return 2097152&this.content}getWidth(){return this.content>>22}getChars(){return 2097152&this.content?this.combinedData:2097151&this.content?(0,s.stringFromCodePoint)(2097151&this.content):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):2097151&this.content}setFromCharData(e){this.fg=e[r.CHAR_DATA_ATTR_INDEX],this.bg=0;let t=!1;if(e[r.CHAR_DATA_CHAR_INDEX].length>2)t=!0;else if(2===e[r.CHAR_DATA_CHAR_INDEX].length){const i=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0);if(55296<=i&&i<=56319){const s=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(1);56320<=s&&s<=57343?this.content=1024*(i-55296)+s-56320+65536|e[r.CHAR_DATA_WIDTH_INDEX]<<22:t=!0}else t=!0}else this.content=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|e[r.CHAR_DATA_WIDTH_INDEX]<<22;t&&(this.combinedData=e[r.CHAR_DATA_CHAR_INDEX],this.content=2097152|e[r.CHAR_DATA_WIDTH_INDEX]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}attributesEquals(e){if(this.getFgColorMode()!==e.getFgColorMode()||this.getFgColor()!==e.getFgColor())return!1;if(this.getBgColorMode()!==e.getBgColorMode()||this.getBgColor()!==e.getBgColor())return!1;if(this.isInverse()!==e.isInverse())return!1;if(this.isBold()!==e.isBold())return!1;if(this.isUnderline()!==e.isUnderline())return!1;if(this.isUnderline()){if(this.getUnderlineStyle()!==e.getUnderlineStyle())return!1;const t=this.isUnderlineColorDefault(),i=e.isUnderlineColorDefault();if(!t||!i){if(t!==i)return!1;if(this.getUnderlineColor()!==e.getUnderlineColor())return!1;if(this.getUnderlineColorMode()!==e.getUnderlineColorMode())return!1}}return this.isOverline()===e.isOverline()&&this.isBlink()===e.isBlink()&&this.isInvisible()===e.isInvisible()&&this.isItalic()===e.isItalic()&&this.isDim()===e.isDim()&&this.isStrikethrough()===e.isStrikethrough()}}t.CellData=n},8938(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.WHITESPACE_CELL_CODE=t.WHITESPACE_CELL_WIDTH=t.WHITESPACE_CELL_CHAR=t.NULL_CELL_CODE=t.NULL_CELL_WIDTH=t.NULL_CELL_CHAR=t.CHAR_DATA_CODE_INDEX=t.CHAR_DATA_WIDTH_INDEX=t.CHAR_DATA_CHAR_INDEX=t.CHAR_DATA_ATTR_INDEX=t.DEFAULT_EXT=t.DEFAULT_ATTR=t.DEFAULT_COLOR=void 0,t.DEFAULT_COLOR=0,t.DEFAULT_ATTR=t.DEFAULT_COLOR<<9|256,t.DEFAULT_EXT=0,t.CHAR_DATA_ATTR_INDEX=0,t.CHAR_DATA_CHAR_INDEX=1,t.CHAR_DATA_WIDTH_INDEX=2,t.CHAR_DATA_CODE_INDEX=3,t.NULL_CELL_CHAR="",t.NULL_CELL_WIDTH=1,t.NULL_CELL_CODE=0,t.WHITESPACE_CELL_CHAR=" ",t.WHITESPACE_CELL_WIDTH=1,t.WHITESPACE_CELL_CODE=32},8158(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Marker=void 0;const s=i(4812),r=i(8636);class o{get id(){return this._id}constructor(e){this.line=e,this.isDisposed=!1,this._disposables=[],this._id=o._nextId++,this._onDispose=this.register(new r.Emitter),this.onDispose=this._onDispose.event}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),(0,s.dispose)(this._disposables),this._disposables.length=0)}register(e){return this._disposables.push(e),e}}t.Marker=o,o._nextId=1},6760(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CHARSET=t.CHARSETS=void 0,t.CHARSETS={},t.DEFAULT_CHARSET=t.CHARSETS.B,t.CHARSETS[0]={"`":"◆",a:"▒",b:"␉",c:"␌",d:"␍",e:"␊",f:"°",g:"±",h:"␤",i:"␋",j:"┘",k:"┐",l:"┌",m:"└",n:"┼",o:"⎺",p:"⎻",q:"─",r:"⎼",s:"⎽",t:"├",u:"┤",v:"┴",w:"┬",x:"│",y:"≤",z:"≥","{":"π","|":"≠","}":"£","~":"·"},t.CHARSETS.A={"#":"£"},t.CHARSETS.B=void 0,t.CHARSETS[4]={"#":"£","@":"¾","[":"ij","\\":"½","]":"|","{":"¨","|":"f","}":"¼","~":"´"},t.CHARSETS.C=t.CHARSETS[5]={"[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS.R={"#":"£","@":"à","[":"°","\\":"ç","]":"§","{":"é","|":"ù","}":"è","~":"¨"},t.CHARSETS.Q={"@":"à","[":"â","\\":"ç","]":"ê","^":"î","`":"ô","{":"é","|":"ù","}":"è","~":"û"},t.CHARSETS.K={"@":"§","[":"Ä","\\":"Ö","]":"Ü","{":"ä","|":"ö","}":"ü","~":"ß"},t.CHARSETS.Y={"#":"£","@":"§","[":"°","\\":"ç","]":"é","`":"ù","{":"à","|":"ò","}":"è","~":"ì"},t.CHARSETS.E=t.CHARSETS[6]={"@":"Ä","[":"Æ","\\":"Ø","]":"Å","^":"Ü","`":"ä","{":"æ","|":"ø","}":"å","~":"ü"},t.CHARSETS.Z={"#":"£","@":"§","[":"¡","\\":"Ñ","]":"¿","{":"°","|":"ñ","}":"ç"},t.CHARSETS.H=t.CHARSETS[7]={"@":"É","[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS["="]={"#":"ù","@":"à","[":"é","\\":"ç","]":"ê","^":"î",_:"è","`":"ô","{":"ä","|":"ö","}":"ü","~":"û"}},706(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.evaluateKeyboardEvent=function(e,t,s,r){const o={type:0,cancel:!1,key:void 0},n=(e.shiftKey?1:0)|(e.altKey?2:0)|(e.ctrlKey?4:0)|(e.metaKey?8:0);switch(e.keyCode){case 0:"UIKeyInputUpArrow"===e.key?o.key=t?"OA":"":"UIKeyInputLeftArrow"===e.key?o.key=t?"OD":"":"UIKeyInputRightArrow"===e.key?o.key=t?"OC":"":"UIKeyInputDownArrow"===e.key&&(o.key=t?"OB":"");break;case 8:o.key=e.ctrlKey?"\b":"",e.altKey&&(o.key=""+o.key);break;case 9:if(e.shiftKey){o.key="";break}o.key="\t",o.cancel=!0;break;case 13:"c"===e.key&&e.ctrlKey?o.key="":o.key=e.altKey?"\r":"\r",o.cancel=!0;break;case 27:o.key="",e.altKey&&(o.key=""),o.cancel=!0;break;case 37:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"D":t?"OD":"";break;case 39:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"C":t?"OC":"";break;case 38:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"A":t?"OA":"";break;case 40:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"B":t?"OB":"";break;case 45:e.shiftKey||e.ctrlKey||(o.key="[2~");break;case 46:o.key=n?"[3;"+(n+1)+"~":"[3~";break;case 36:o.key=n?"[1;"+(n+1)+"H":t?"OH":"";break;case 35:o.key=n?"[1;"+(n+1)+"F":t?"OF":"";break;case 33:e.shiftKey?o.type=2:e.ctrlKey?o.key="[5;"+(n+1)+"~":o.key="[5~";break;case 34:e.shiftKey?o.type=3:e.ctrlKey?o.key="[6;"+(n+1)+"~":o.key="[6~";break;case 112:o.key=n?"[1;"+(n+1)+"P":"OP";break;case 113:o.key=n?"[1;"+(n+1)+"Q":"OQ";break;case 114:o.key=n?"[1;"+(n+1)+"R":"OR";break;case 115:o.key=n?"[1;"+(n+1)+"S":"OS";break;case 116:o.key=n?"[15;"+(n+1)+"~":"[15~";break;case 117:o.key=n?"[17;"+(n+1)+"~":"[17~";break;case 118:o.key=n?"[18;"+(n+1)+"~":"[18~";break;case 119:o.key=n?"[19;"+(n+1)+"~":"[19~";break;case 120:o.key=n?"[20;"+(n+1)+"~":"[20~";break;case 121:o.key=n?"[21;"+(n+1)+"~":"[21~";break;case 122:o.key=n?"[23;"+(n+1)+"~":"[23~";break;case 123:o.key=n?"[24;"+(n+1)+"~":"[24~";break;default:if(!e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)if(s&&!r||!e.altKey||e.metaKey)if(!s||e.altKey||e.ctrlKey||e.shiftKey||!e.metaKey){if(e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.keyCode>=48&&1===e.key.length)o.key=e.key;else if(e.key&&e.ctrlKey&&e.shiftKey)switch(e.code){case"Minus":o.key="";break;case"Digit2":o.key="\0";break;case"Digit6":o.key=""}}else 65===e.keyCode&&(o.type=1);else{const t=i[e.keyCode],s=t?.[e.shiftKey?1:0];if(s)o.key=""+s;else if(e.keyCode>=65&&e.keyCode<=90){const t=e.ctrlKey?e.keyCode-64:e.keyCode+32;let i=String.fromCharCode(t);e.shiftKey&&(i=i.toUpperCase()),o.key=""+i}else if(32===e.keyCode)o.key=""+(e.ctrlKey?"\0":" ");else if("Dead"===e.key&&e.code.startsWith("Key")){let t=e.code.slice(3,4);e.shiftKey||(t=t.toLowerCase()),o.key=""+t,o.cancel=!0}}else e.keyCode>=65&&e.keyCode<=90?o.key=String.fromCharCode(e.keyCode-64):32===e.keyCode?o.key="\0":e.keyCode>=51&&e.keyCode<=55?o.key=String.fromCharCode(e.keyCode-51+27):56===e.keyCode?o.key="":"/"===e.key?o.key="":219===e.keyCode?o.key="":220===e.keyCode?o.key="":221===e.keyCode&&(o.key="")}return o};const i={48:["0",")"],49:["1","!"],50:["2","@"],51:["3","#"],52:["4","$"],53:["5","%"],54:["6","^"],55:["7","&"],56:["8","*"],57:["9","("],186:[";",":"],187:["=","+"],188:[",","<"],189:["-","_"],190:[".",">"],191:["/","?"],192:["`","~"],219:["[","{"],220:["\\","|"],221:["]","}"],222:["'",'"']}},7241(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.KittyKeyboard=void 0,t.KittyKeyboard=class{constructor(){this._functionalKeyCodes={Escape:27,Enter:13,Tab:9,Backspace:127,CapsLock:57358,ScrollLock:57359,NumLock:57360,PrintScreen:57361,Pause:57362,ContextMenu:57363,F13:57376,F14:57377,F15:57378,F16:57379,F17:57380,F18:57381,F19:57382,F20:57383,F21:57384,F22:57385,F23:57386,F24:57387,F25:57388,KP_0:57399,KP_1:57400,KP_2:57401,KP_3:57402,KP_4:57403,KP_5:57404,KP_6:57405,KP_7:57406,KP_8:57407,KP_9:57408,KP_Decimal:57409,KP_Divide:57410,KP_Multiply:57411,KP_Subtract:57412,KP_Add:57413,KP_Enter:57414,KP_Equal:57415,ShiftLeft:57441,ShiftRight:57447,ControlLeft:57442,ControlRight:57448,AltLeft:57443,AltRight:57449,MetaLeft:57444,MetaRight:57450,MediaPlayPause:57430,MediaStop:57432,MediaTrackNext:57435,MediaTrackPrevious:57436,AudioVolumeDown:57438,AudioVolumeUp:57439,AudioVolumeMute:57440},this._csiTildeKeys={Insert:2,Delete:3,PageUp:5,PageDown:6,F5:15,F6:17,F7:18,F8:19,F9:20,F10:21,F11:23,F12:24},this._csiLetterKeys={ArrowUp:"A",ArrowDown:"B",ArrowRight:"C",ArrowLeft:"D",Home:"H",End:"F"},this._ss3FunctionKeys={F1:"P",F2:"Q",F3:"R",F4:"S"}}_getNumpadKeyCode(e){if(e.code.startsWith("Numpad")){const t=e.code.slice(6);if(t>="0"&&t<="9")return 57399+parseInt(t,10);switch(t){case"Decimal":return 57409;case"Divide":return 57410;case"Multiply":return 57411;case"Subtract":return 57412;case"Add":return 57413;case"Enter":return 57414;case"Equal":return 57415}}}_getModifierKeyCode(e){switch(e.code){case"ShiftLeft":return 57441;case"ShiftRight":return 57447;case"ControlLeft":return 57442;case"ControlRight":return 57448;case"AltLeft":return 57443;case"AltRight":return 57449;case"MetaLeft":return 57444;case"MetaRight":return 57450}}_encodeModifiers(e){let t=0;return e.shiftKey&&(t|=1),e.altKey&&(t|=2),e.ctrlKey&&(t|=4),e.metaKey&&(t|=8),t>0?t+1:0}_getKeyCode(e,t){const i=this._getNumpadKeyCode(e);if(void 0!==i)return i;const s=this._getModifierKeyCode(e);if(void 0!==s)return s;const r=this._functionalKeyCodes[e.key];if(void 0!==r)return r;if((e.shiftKey||t&&e.altKey)&&e.code){if(e.code.startsWith("Digit")&&6===e.code.length){const t=e.code.charAt(5);if(t>="0"&&t<="9")return t.charCodeAt(0)}if(e.code.startsWith("Key")&&4===e.code.length)return e.code.charAt(3).toLowerCase().charCodeAt(0)}if(1===e.key.length){const t=e.key.codePointAt(0);return t>=65&&t<=90?t+32:t}}_isModifierKey(e){return"Shift"===e.key||"Control"===e.key||"Alt"===e.key||"Meta"===e.key}_isLockKey(e){return"CapsLock"===e.key||"NumLock"===e.key||"ScrollLock"===e.key}_buildCsiLetterSequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"["+e}_buildSs3Sequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"O"+e}_buildCsiTildeSequence(e,t,i,s){const r=s&&1!==i;let o="["+e;return(t>0||r)&&(o+=";"+(t>0?t:"1"),r&&(o+=":"+i)),o+="~",o}_buildCsiUSequence(e,t,i,s,r,o,n){const a=!!(2&r);let h,l="["+t;4&r&&e.shiftKey&&1===e.key.length&&!o&&!n&&(h=e.key.codePointAt(0),l+=":"+h);const c=16&r&&3!==s&&1===e.key.length&&!o&&!n&&!e.ctrlKey?e.key.codePointAt(0):void 0,d=a&&1!==s&&(3===s||void 0===c);return(i>0||d||void 0!==c)&&(l+=";",i>0?l+=i:d&&(l+="1"),d&&(l+=":"+s)),void 0!==c&&(l+=";"+c),l+="u",l}evaluate(e,t,i=1,s=!1){const r={type:0,cancel:!1,key:void 0},o=this._encodeModifiers(e),n=this._isModifierKey(e),a=!!(2&t);if(!a&&3===i)return r;if(n&&!(8&t))return r;if(this._isLockKey(e)&&!(8&t))return r;const h=this._csiLetterKeys[e.key];if(h)return r.key=this._buildCsiLetterSequence(h,o,i,a),r.cancel=!0,r;const l=this._ss3FunctionKeys[e.key];if(l)return r.key=this._buildSs3Sequence(l,o,i,a),r.cancel=!0,r;const c=this._csiTildeKeys[e.key];if(void 0!==c)return r.key=this._buildCsiTildeSequence(c,o,i,a),r.cancel=!0,r;const d=this._getKeyCode(e,s);if(void 0===d)return r;const _=13===d||9===d||127===d;if(_&&3===i&&!(8&t))return r;const u=void 0!==this._functionalKeyCodes[e.key]||void 0!==this._getNumpadKeyCode(e);if(8&t||a&&3===i||(1&t||a)&&(u&&!_||o>0&&1!==e.key.length||o-1>1))r.key=this._buildCsiUSequence(e,d,o,i,t,u,n),r.cancel=!0;else{const t=13===d?"\r":9===d?"\t":127===d?"":void 0;t?r.key=t:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||(r.key=e.key)}return r}static shouldUseProtocol(e){return e>0}}},726(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Utf8ToUtf32=t.StringToUtf32=void 0,t.stringFromCodePoint=function(e){return e>65535?(e-=65536,String.fromCharCode(55296+(e>>10))+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)},t.utf32ToString=function(e,t=0,i=e.length){let s="";for(let r=t;r65535?(t-=65536,s+=String.fromCharCode(55296+(t>>10))+String.fromCharCode(t%1024+56320)):s+=String.fromCharCode(t)}return s},t.StringToUtf32=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){const i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){const i=e.charCodeAt(r++);56320<=i&&i<=57343?t[s++]=1024*(this._interim-55296)+i-56320+65536:(t[s++]=this._interim,t[s++]=i),this._interim=0}for(let o=r;o=i)return this._interim=r,s;const n=e.charCodeAt(o);56320<=n&&n<=57343?t[s++]=1024*(r-55296)+n-56320+65536:(t[s++]=r,t[s++]=n);continue}65279!==r&&(t[s++]=r)}return s}},t.Utf8ToUtf32=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){const i=e.length;if(!i)return 0;let s,r,o,n,a,h=0,l=0;if(this.interim[0]){let s=!1,r=this.interim[0];r&=192==(224&r)?31:224==(240&r)?15:7;let o,n=0;for(;(o=this.interim[++n])&&n<4;)r<<=6,r|=63&o;const a=192==(224&this.interim[0])?2:224==(240&this.interim[0])?3:4,c=a-n;for(;l=i)return 0;if(o=e[l++],128!=(192&o)){l--,s=!0;break}this.interim[n++]=o,r<<=6,r|=63&o}s||(2===a?r<128?l--:t[h++]=r:3===a?r<2048||r>=55296&&r<=57343||65279===r||(t[h++]=r):r<65536||r>1114111||(t[h++]=r)),this.interim.fill(0)}const c=i-4;let d=l;for(;d=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(a=(31&s)<<6|63&r,a<128){d--;continue}t[h++]=a}else if(224==(240&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(a=(15&s)<<12|(63&r)<<6|63&o,a<2048||a>=55296&&a<=57343||65279===a)continue;t[h++]=a}else if(240==(248&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,this.interim[2]=o,h;if(n=e[d++],128!=(192&n)){d--;continue}if(a=(7&s)<<18|(63&r)<<12|(63&o)<<6|63&n,a<65536||a>1114111)continue;t[h++]=a}}return h}}},7428(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeV6=void 0;const s=i(6415),r=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],o=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]];let n;t.UnicodeV6=class{constructor(){if(this.version="6",!n){n=new Uint8Array(65536),n.fill(1),n[0]=0,n.fill(0,1,32),n.fill(0,127,160),n.fill(2,4352,4448),n[9001]=2,n[9002]=2,n.fill(2,11904,42192),n[12351]=1,n.fill(2,44032,55204),n.fill(2,63744,64256),n.fill(2,65040,65050),n.fill(2,65072,65136),n.fill(2,65280,65377),n.fill(2,65504,65511);for(let e=0;et[r][1])return!1;for(;r>=s;)if(i=s+r>>1,e>t[i][1])s=i+1;else{if(!(e=131072&&e<=196605||e>=196608&&e<=262141?2:1}charProperties(e,t){let i=this.wcwidth(e),r=0===i&&0!==t;if(r){const e=s.UnicodeService.extractWidth(t);0===e?r=!1:e>i&&(i=e)}return s.UnicodeService.createPropertyValue(0,i,r)}}},9249(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Win32InputMode=void 0,t.Win32InputMode=class{constructor(){this._codeToVk={KeyA:65,KeyB:66,KeyC:67,KeyD:68,KeyE:69,KeyF:70,KeyG:71,KeyH:72,KeyI:73,KeyJ:74,KeyK:75,KeyL:76,KeyM:77,KeyN:78,KeyO:79,KeyP:80,KeyQ:81,KeyR:82,KeyS:83,KeyT:84,KeyU:85,KeyV:86,KeyW:87,KeyX:88,KeyY:89,KeyZ:90,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,F16:127,F17:128,F18:129,F19:130,F20:131,F21:132,F22:133,F23:134,F24:135,Numpad0:96,Numpad1:97,Numpad2:98,Numpad3:99,Numpad4:100,Numpad5:101,Numpad6:102,Numpad7:103,Numpad8:104,Numpad9:105,NumpadMultiply:106,NumpadAdd:107,NumpadSeparator:108,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,NumLock:144,ArrowUp:38,ArrowDown:40,ArrowLeft:37,ArrowRight:39,Home:36,End:35,PageUp:33,PageDown:34,Insert:45,Delete:46,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,CapsLock:20,ScrollLock:145,Escape:27,Enter:13,Tab:9,Space:32,Backspace:8,Pause:19,ContextMenu:93,PrintScreen:44,Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,IntlBackslash:226},this._codeToScancode={KeyQ:16,KeyW:17,KeyE:18,KeyR:19,KeyT:20,KeyY:21,KeyU:22,KeyI:23,KeyO:24,KeyP:25,KeyA:30,KeyS:31,KeyD:32,KeyF:33,KeyG:34,KeyH:35,KeyJ:36,KeyK:37,KeyL:38,KeyZ:44,KeyX:45,KeyC:46,KeyV:47,KeyB:48,KeyN:49,KeyM:50,Digit1:2,Digit2:3,Digit3:4,Digit4:5,Digit5:6,Digit6:7,Digit7:8,Digit8:9,Digit9:10,Digit0:11,F1:59,F2:60,F3:61,F4:62,F5:63,F6:64,F7:65,F8:66,F9:67,F10:68,F11:87,F12:88,Numpad0:82,Numpad1:79,Numpad2:80,Numpad3:81,Numpad4:75,Numpad5:76,Numpad6:77,Numpad7:71,Numpad8:72,Numpad9:73,NumpadMultiply:55,NumpadAdd:78,NumpadSubtract:74,NumpadDecimal:83,NumpadDivide:53,NumpadEnter:28,NumLock:69,ArrowUp:72,ArrowDown:80,ArrowLeft:75,ArrowRight:77,Home:71,End:79,PageUp:73,PageDown:81,Insert:82,Delete:83,ShiftLeft:42,ShiftRight:54,ControlLeft:29,ControlRight:29,AltLeft:56,AltRight:56,CapsLock:58,ScrollLock:70,Escape:1,Enter:28,Tab:15,Space:57,Backspace:14,Pause:69,Semicolon:39,Equal:13,Comma:51,Minus:12,Period:52,Slash:53,Backquote:41,BracketLeft:26,Backslash:43,BracketRight:27,Quote:40},this._enhancedKeyCodes=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Insert","Delete","NumpadEnter","NumpadDivide","ControlRight","AltRight","PrintScreen","Pause","ContextMenu","MetaLeft","MetaRight"]),this._keyToControlChar={Enter:13,Backspace:8,Tab:9,Escape:27}}_getVirtualKeyCode(e){const t=this._codeToVk[e.code];return void 0!==t?t:e.keyCode||0}_getScanCode(e){return this._codeToScancode[e.code]||0}_getUnicodeChar(e){if(e.ctrlKey&&!e.altKey&&!e.metaKey){if("Enter"===e.key)return 10;if("Backspace"===e.key)return 127}const t=this._keyToControlChar[e.key];if(void 0!==t)return t;if(1===e.key.length){const t=e.key.codePointAt(0)||0;if(e.ctrlKey&&!e.altKey&&!e.metaKey){if(t>=65&&t<=90)return t-64;if(t>=97&&t<=122)return t-96}return t}return 0}_getControlKeyState(e){let t=0;return e.shiftKey&&(t|=16),e.ctrlKey&&("ControlRight"===e.code?t|=4:t|=8),e.altKey&&("AltRight"===e.code?t|=1:t|=2),this._enhancedKeyCodes.has(e.code)&&(t|=256),t}evaluateKeyboardEvent(e,t){return{type:0,cancel:!0,key:`[${this._getVirtualKeyCode(e)};${this._getScanCode(e)};${this._getUnicodeChar(e)};${t?1:0};${this._getControlKeyState(e)};1_`}}}},3562(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WriteBuffer=void 0;const s=i(3132),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._action=e,this._writeBuffer=[],this._callbacks=[],this._pendingData=0,this._bufferOffset=0,this._isSyncWriting=!1,this._syncCalls=0,this._didUserInput=!1,this._innerWriteTimer=this._register(new s.TimeoutTimer),this._onWriteParsed=this._register(new o.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._register((0,r.toDisposable)(()=>{this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0}))}handleUserInput(){this._didUserInput=!0}flushSync(){if(this._store.isDisposed)return;if(this._isSyncWriting)return;let e;this._isSyncWriting=!0;let t=!1;for(;e=this._writeBuffer.shift();){t=!0,this._action(e);const i=this._callbacks.shift();i&&i()}this._pendingData=0,this._bufferOffset=2147483647,this._writeBuffer.length=0,this._callbacks.length=0,this._isSyncWriting=!1,t&&this._onWriteParsed.fire()}writeSync(e,t){if(this._store.isDisposed)return;if(void 0!==t&&this._syncCalls>t)return void(this._syncCalls=0);if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;let i;for(this._isSyncWriting=!0;i=this._writeBuffer.shift();){this._action(i);const e=this._callbacks.shift();e&&e()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(!this._store.isDisposed){if(this._pendingData>5e7)throw new Error("write data discarded, use flow control to avoid losing data");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput)return this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),void this._innerWrite();this._scheduleInnerWrite()}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}}_scheduleInnerWrite(e=0,t=!0){this._store.isDisposed||this._innerWriteTimer.cancelAndSet(()=>this._innerWrite(e,t),0)}_innerWrite(e=0,t=!0){if(this._store.isDisposed)return;const i=e||performance.now();for(;this._writeBuffer.length>this._bufferOffset;){const e=this._writeBuffer[this._bufferOffset],s=this._action(e,t);if(s){const e=e=>{this._store.isDisposed||(performance.now()-i>=12?this._scheduleInnerWrite(0,e):this._innerWrite(i,e))};return void s.catch(e=>(queueMicrotask(()=>{throw e}),Promise.resolve(!1))).then(e)}const r=this._callbacks[this._bufferOffset];if(r&&r(),this._bufferOffset++,this._pendingData-=e.length,performance.now()-i>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),this._scheduleInnerWrite()):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}}t.WriteBuffer=n},8693(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.parseColor=function(e){if(!e)return;let t=e.toLowerCase();if(t.startsWith("rgb:")){t=t.slice(4);const e=i.exec(t);if(e){const t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(t.startsWith("#")&&(t=t.slice(1),s.exec(t)&&[3,6,9,12].includes(t.length))){const e=t.length/3,i=[0,0,0];for(let s=0;s<3;++s){const r=parseInt(t.slice(e*s,e*s+e),16);i[s]=1===e?r<<4:2===e?r:3===e?r>>4:r>>8}return i}},t.toRgbString=function(e,t=16){const[i,s,o]=e;return`rgb:${r(i,t)}/${r(s,t)}/${r(o,t)}`};const i=/^([\da-f])\/([\da-f])\/([\da-f])$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/,s=/^[\da-f]+$/;function r(e,t){const i=e.toString(16),s=i.length<2?"0"+i:i;switch(t){case 4:return i[0];case 8:return s;case 12:return(s+s).slice(0,3);default:return s+s}}},2607(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.ApcHandler=t.ApcParser=void 0;const s=i(726),r=i(4220),o=[];t.ApcParser=class{constructor(){this._handlers=Object.create(null),this._active=o,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._ident=0}start(e){if(this.reset(),this._ident=e,this._active=this._handlers[e]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._ident,"START")}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}end(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"END",e);this._active=o,this._ident=0}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.ApcHandler=n,n._payloadLimit=1e7},9823(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DcsHandler=t.DcsParser=void 0;const s=i(726),r=i(7262),o=i(4220),n=[];t.DcsParser=class{constructor(){this._handlers=Object.create(null),this._active=n,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=n}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].unhook(!1);this._stack.paused=!1,this._active=n,this._ident=0}hook(e,t){if(this.reset(),this._ident=e,this._active=this._handlers[e]||n,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].hook(t);else this._handlerFb(this._ident,"HOOK",t)}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}unhook(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].unhook(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].unhook(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"UNHOOK",e);this._active=n,this._ident=0}};const a=new r.Params;a.addParam(0);class h{constructor(e){this._handler=e,this._data=new o.LimitedStringBuilder(h._payloadLimit),this._params=a,this._hitLimit=!1}hook(e){this._params=e.length>1||e.params[0]?e.clone():a,this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}unhook(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString(),this._params),t instanceof Promise))return t.then(e=>(this._params=a,this._data.reset(),this._hitLimit=!1,e));return this._params=a,this._data.reset(),this._hitLimit=!1,t}}t.DcsHandler=h,h._payloadLimit=1e7},6717(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EscapeSequenceParser=t.VT500_TRANSITION_TABLE=t.TransitionTable=void 0;const s=i(4812),r=i(7262),o=i(1346),n=i(9823),a=i(2607);class h{constructor(e){this.table=new Uint16Array(e)}setDefault(e,t){this.table.fill(e<<8|t)}add(e,t,i,s){this.table[t<<8|e]=i<<8|s}addMany(e,t,i,s){for(let r=0;rt),i=(e,i)=>t.slice(e,i),s=i(32,127),r=i(0,24);r.push(25),r.push.apply(r,i(28,32));const o=i(0,17);e.setDefault(1,0),e.addMany(s,0,2,0);for(const t of o)e.addMany([24,26,153,154],t,3,0),e.addMany(i(128,144),t,3,0),e.addMany(i(144,152),t,3,0),e.add(156,t,0,0),e.add(27,t,11,1),e.add(157,t,4,8),e.addMany([152,158],t,0,7),e.add(159,t,11,14),e.add(155,t,11,3),e.add(144,t,11,9);return e.addMany(r,0,3,0),e.addMany(r,1,3,1),e.add(127,1,0,1),e.addMany(r,8,0,8),e.addMany(r,3,3,3),e.add(127,3,0,3),e.addMany(r,4,3,4),e.add(127,4,0,4),e.addMany(r,6,3,6),e.addMany(r,5,3,5),e.add(127,5,0,5),e.addMany(r,2,3,2),e.add(127,2,0,2),e.add(93,1,4,8),e.addMany(s,8,5,8),e.add(127,8,5,8),e.addMany([156,27,24,26,7],8,6,0),e.addMany(i(28,32),8,0,8),e.addMany([88,94],1,0,7),e.addMany(s,7,0,7),e.addMany(r,7,0,7),e.add(156,7,0,0),e.add(127,7,0,7),e.add(95,1,11,14),e.addMany(r,14,0,14),e.add(127,14,0,14),e.addMany(i(32,48),14,9,15),e.addMany(i(48,127),14,15,16),e.addMany(i(48,127),15,15,16),e.addMany(r,15,0,15),e.addMany(i(32,48),15,9,15),e.add(127,15,0,15),e.addMany(s,16,16,16),e.addMany(r,16,0,16),e.addMany(i(8,14),16,16,16),e.add(127,16,0,16),e.addMany([27,156,24,26],16,17,0),e.add(91,1,11,3),e.addMany(i(64,127),3,7,0),e.addMany(i(48,60),3,8,4),e.addMany([60,61,62,63],3,9,4),e.addMany(i(48,60),4,8,4),e.addMany(i(64,127),4,7,0),e.addMany([60,61,62,63],4,0,6),e.addMany(i(32,64),6,0,6),e.add(127,6,0,6),e.addMany(i(64,127),6,0,0),e.addMany(i(32,48),3,9,5),e.addMany(i(32,48),5,9,5),e.addMany(i(48,64),5,0,6),e.addMany(i(64,127),5,7,0),e.addMany(i(32,48),4,9,5),e.addMany(i(32,48),1,9,2),e.addMany(i(32,48),2,9,2),e.addMany(i(48,127),2,10,0),e.addMany(i(48,80),1,10,0),e.addMany(i(81,88),1,10,0),e.addMany([89,90,92],1,10,0),e.addMany(i(96,127),1,10,0),e.add(80,1,11,9),e.addMany(r,9,0,9),e.add(127,9,0,9),e.addMany(i(32,48),9,9,12),e.addMany(i(48,60),9,8,10),e.addMany([60,61,62,63],9,9,10),e.addMany(r,11,0,11),e.addMany(i(32,128),11,0,11),e.addMany(r,10,0,10),e.add(127,10,0,10),e.addMany(i(48,60),10,8,10),e.addMany([60,61,62,63],10,0,11),e.addMany(i(32,48),10,9,12),e.addMany(r,12,0,12),e.add(127,12,0,12),e.addMany(i(32,48),12,9,12),e.addMany(i(48,64),12,0,11),e.addMany(i(64,127),12,12,13),e.addMany(i(64,127),10,12,13),e.addMany(i(64,127),9,12,13),e.addMany(r,13,13,13),e.addMany(s,13,13,13),e.add(127,13,0,13),e.addMany([27,156,24,26],13,14,0),e.add(l,0,2,0),e.add(l,8,5,8),e.add(l,6,0,6),e.add(l,11,0,11),e.add(l,13,13,13),e.add(l,16,16,16),e}();class c extends s.Disposable{constructor(e=t.VT500_TRANSITION_TABLE){super(),this._transitions=e,this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0},this.initialState=0,this.currentState=this.initialState,this._params=new r.Params,this._params.addParam(0),this._collect=0,this.precedingJoinState=0,this._printHandlerFb=(e,t,i)=>{},this._executeHandlerFb=e=>{},this._csiHandlerFb=(e,t)=>{},this._escHandlerFb=e=>{},this._errorHandlerFb=e=>e,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this._register((0,s.toDisposable)(()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._escHandlers=Object.create(null)})),this._oscParser=this._register(new o.OscParser),this._dcsParser=this._register(new n.DcsParser),this._apcParser=this._register(new a.ApcParser),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:"\\"},()=>!0)}_identifier(e,t=[64,126]){let i=0;if(e.prefix){if(e.prefix.length>1)throw new Error("only one byte as prefix supported");if(i=e.prefix.charCodeAt(0),i<60||i>63)throw new Error("prefix must be in range 0x3c .. 0x3f")}if(e.intermediates){if(e.intermediates.length>2)throw new Error("only two bytes as intermediates are supported");for(let t=0;ts||s>47)throw new Error("intermediate must be in range 0x20 .. 0x2f");i<<=8,i|=s}}if(1!==e.final.length)throw new Error("final must be a single byte");const s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return i<<=8,i|=s,i}identToString(e){const t=[];for(;e;)t.push(String.fromCharCode(255&e)),e>>=8;return t.reverse().join("")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){const i=this._identifier(e,[48,126]);this._escHandlers[i]??=[];const s=this._escHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){const i=e.charCodeAt(0);this._executeHandlers[i]=t,i<24&&(this._executeHandlersArr[i]=t)}clearExecuteHandler(e){const t=e.charCodeAt(0);this._executeHandlers[t]&&delete this._executeHandlers[t],t<24&&(this._executeHandlersArr[t]=void 0)}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){const i=this._identifier(e);this._csiHandlers[i]??=[];const s=this._csiHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}registerApcHandler(e,t){return e.prefix=void 0,this._apcParser.registerHandler(this._identifier(e,[48,126]),t)}clearApcHandler(e){e.prefix=void 0,this._apcParser.clearHandler(this._identifier(e,[48,126]))}setApcHandlerFallback(e){this._apcParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._apcParser.reset(),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0,0!==this._parseStack.state&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,i,s,r){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=i,this._parseStack.transition=s,this._parseStack.chunkPos=r}parse(e,t,i){let s,r,o,n=0;if(this._parseStack.state)if(2===this._parseStack.state)this._parseStack.state=0,n=this._parseStack.chunkPos+1;else{if(void 0===i||1===this._parseStack.state)throw this._parseStack.state=1,new Error("improper continuation due to previous async handler, giving up parsing");const t=this._parseStack.handlers;let r=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](this._params),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 4:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 6:if(s=e[this._parseStack.chunkPos],o=this._dcsParser.unhook(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 5:if(s=e[this._parseStack.chunkPos],o=this._oscParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 7:if(s=e[this._parseStack.chunkPos],o=this._apcParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0}this._parseStack.state=0,n=this._parseStack.chunkPos+1,this.precedingJoinState=0,this.currentState=255&this._parseStack.transition}for(let i=n;i=60&&n<=63&&(this._collect=n,s++);let a=!1;for(;s=48&&n<=57)this._params.addDigit(n-48);else if(59===n)this._params.addParam(0);else{if(58!==n){if(n>=64&&n<=126){const e=this._csiHandlers[this._collect<<8|n];let t=e?e.length-1:-1;for(;t>=0&&(o=e[t](this._params),!0!==o);t--)if(o instanceof Promise)return r=1792,this._preserveStack(3,e,t,r,s),o;t<0&&this._csiHandlerFb(this._collect<<8|n,this._params),this.precedingJoinState=0,i=s,this.currentState=0,a=!0;break}break}this._params.addSubParam(-1)}a||(i=s-1,this.currentState=4);continue}switch(r=this._transitions.table[this.currentState<<8|(s>8){case 2:let n=i;const a=t-4;for(;n=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l););if(n>=a)for(;n=32&&(e[n]<=126||e[n]>=l);)n++;this._printHandler(e,i,n),i=n-1;break;case 3:this._executeHandlers[s]?this._executeHandlers[s]():this._executeHandlerFb(s),this.precedingJoinState=0;break;case 0:break;case 1:if(this._errorHandler({position:i,code:s,currentState:this.currentState,collect:this._collect,params:this._params,abort:!1}).abort)return;break;case 7:const h=this._csiHandlers[this._collect<<8|s];let c=h?h.length-1:-1;for(;c>=0&&(o=h[c](this._params),!0!==o);c--)if(o instanceof Promise)return this._preserveStack(3,h,c,r,i),o;c<0&&this._csiHandlerFb(this._collect<<8|s,this._params),this.precedingJoinState=0;break;case 8:do{switch(s){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(s-48)}}while(++i47&&s<60);i--;break;case 9:this._collect<<=8,this._collect|=s;break;case 10:const d=this._escHandlers[this._collect<<8|s];let _=d?d.length-1:-1;for(;_>=0&&(o=d[_](),!0!==o);_--)if(o instanceof Promise)return this._preserveStack(4,d,_,r,i),o;_<0&&this._escHandlerFb(this._collect<<8|s),this.precedingJoinState=0;break;case 11:this._params.resetZdm(),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|s,this._params);break;case 13:for(let r=i+1;;++r)if(r>=t||24===(s=e[r])||26===s||27===s||s>127&&s=t||(s=e[r])<32||s>127&&s=32&&e[s]<127||e[s]>=8&&e[s]<14||e[s]>=l))){this._apcParser.put(e,i,s),i=s-1;break}break;case 17:if(o=this._apcParser.end(24!==s&&26!==s),o)return this._preserveStack(7,[],0,r,i),o;27===s&&(r|=1),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0}this.currentState=255&r}}}t.EscapeSequenceParser=c},1346(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OscHandler=t.OscParser=void 0;const s=i(726),r=i(4220),o=[];t.OscParser=class{constructor(){this._state=0,this._active=o,this._id=-1,this._handlers=Object.create(null),this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(2===this._state)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._id,"START")}_put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._id,"PUT",(0,s.utf32ToString)(e,t,i))}start(){this.reset(),this._state=1}put(e,t,i){if(3!==this._state){if(1===this._state)for(;t0&&this._put(e,t,i)}}end(e,t=!0){if(0!==this._state){if(3!==this._state)if(1===this._state&&this._start(),this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._id,"END",e);this._active=o,this._id=-1,this._state=0}}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.OscHandler=n,n._payloadLimit=1e7},7262(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Params=void 0;class i{static fromArray(e){const t=new i;if(!e.length)return t;for(let i=Array.isArray(e[0])?1:0;i256)throw new Error("maxSubParamsLength must not be greater than 256");this.params=new Int32Array(e),this.length=0,this._subParams=new Int32Array(t),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(e),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}clone(){const e=new i(this.maxLength,this.maxSubParamsLength);return e.params.set(this.params),e.length=this.length,e._subParams.set(this._subParams),e._subParamsLength=this._subParamsLength,e._subParamsIdx.set(this._subParamsIdx),e._rejectDigits=this._rejectDigits,e._rejectSubDigits=this._rejectSubDigits,e._digitIsSub=this._digitIsSub,e}toArray(){const e=[];for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&e.push(Array.prototype.slice.call(this._subParams,i,s))}return e}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}resetZdm(){this.length=1,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1,this._subParamsIdx[0]=0,this.params[0]=0}addParam(e){if(this._digitIsSub=!1,this.length>=this.maxLength)this._rejectDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=e>2147483647?2147483647:e}}addSubParam(e){if(this._digitIsSub=!0,this.length)if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength)this._rejectSubDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParams[this._subParamsLength++]=e>2147483647?2147483647:e,this._subParamsIdx[this.length-1]++}}hasSubParams(e){return(255&this._subParamsIdx[e])-(this._subParamsIdx[e]>>8)>0}getSubParams(e){const t=this._subParamsIdx[e]>>8,i=255&this._subParamsIdx[e];return i-t>0?this._subParams.subarray(t,i):null}getSubParamsAll(){const e={};for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&(e[t]=this._subParams.slice(i,s))}return e}addDigit(e){let t;if(this._rejectDigits||!(t=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;const i=this._digitIsSub?this._subParams:this.params,s=i[t-1];i[t-1]=~s?Math.min(10*s+e,2147483647):e}}t.Params=i},3027(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.AddonManager=void 0,t.AddonManager=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){const i={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(i),t.dispose=()=>this._wrappedAddonDispose(i),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let i=0;i=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new s.CellData)}translateToString(e,t,i){return this._line.translateToString(e,t,i)}}},5101(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferNamespaceApi=void 0;const s=i(3235),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._core=e,this._onBufferChange=this._register(new o.Emitter),this.onBufferChange=this._onBufferChange.event,this._normal=new s.BufferApiView(this._core.buffers.normal,"normal"),this._alternate=new s.BufferApiView(this._core.buffers.alt,"alternate"),this._register(this._core.buffers.onBufferActivate(()=>this._onBufferChange.fire(this.active)))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw new Error("Active buffer is neither normal nor alternate")}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}}t.BufferNamespaceApi=n},6097(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ParserApi=void 0,t.ParserApi=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,e=>t(e.toArray()))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,(e,i)=>t(e,i.toArray()))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}registerApcHandler(e,t){return this._core.registerApcHandler(e,t)}}},4335(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeApi=void 0,t.UnicodeApi=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}}},9640(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferService=void 0;const o=i(4812),n=i(4097),a=i(6501),h=i(8636);let l=class extends o.Disposable{get buffer(){return this.buffers.active}constructor(e,t){super(),this.isUserScrolling=!1,this._onResize=this._register(new h.Emitter),this.onResize=this._onResize.event,this._onScroll=this._register(new h.Emitter),this.onScroll=this._onScroll.event,this.cols=Math.max(e.rawOptions.cols||0,2),this.rows=Math.max(e.rawOptions.rows||0,1),this.buffers=this._register(new n.BufferSet(e,this,t)),this._register(this.buffers.onBufferActivate(e=>{this._onScroll.fire(e.activeBuffer.ydisp)}))}resize(e,t){const i=this.cols!==e,s=this.rows!==t;this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t,colsChanged:i,rowsChanged:s})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){const i=this.buffer;let s;s=this._cachedBlankLine,s&&s.length===this.cols&&s.getFg(0)===e.fg&&s.getBg(0)===e.bg||(s=i.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;const r=i.ybase+i.scrollTop,o=i.ybase+i.scrollBottom;if(0===i.scrollTop){const e=i.lines.isFull;o===i.lines.length-1?e?i.lines.recycle().copyFrom(s):i.lines.push(s.clone()):i.lines.splice(o+1,0,s.clone()),e?this.isUserScrolling&&(i.ydisp=Math.max(i.ydisp-1,0)):(i.ybase++,this.isUserScrolling||i.ydisp++)}else{const e=o-r+1;i.lines.shiftElements(r+1,e-1,-1),i.lines.set(o,s.clone())}this.isUserScrolling||(i.ydisp=i.ybase),this._onScroll.fire(i.ydisp)}scrollLines(e,t){const i=this.buffer;if(e<0){if(0===i.ydisp)return;this.isUserScrolling=!0}else e+i.ydisp>=i.ybase&&(this.isUserScrolling=!1);const s=i.ydisp;i.ydisp=Math.max(Math.min(i.ydisp+e,i.ybase),0),s!==i.ydisp&&(t||this._onScroll.fire(i.ydisp))}};t.BufferService=l,t.BufferService=l=s([r(0,a.IOptionsService),r(1,a.ILogService)],l)},5746(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.CharsetService=void 0,t.CharsetService=class{constructor(){this.glevel=0,this._charsets=[]}get charsets(){return this._charsets}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(e){this.glevel=e,this.charset=this._charsets[e]}setgCharset(e,t){this._charsets[e]=t,this.glevel===e&&(this.charset=t)}}},4071(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CoreService=void 0;const o=i(4812),n=i(6501),a=i(8636),h=Object.freeze({insertMode:!1}),l=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,colorSchemeUpdates:!1,cursorBlink:void 0,cursorStyle:void 0,origin:!1,reverseWraparound:!1,sendFocus:!1,synchronizedOutput:!1,win32InputMode:!1,wraparound:!0});let c=class extends o.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._logService=t,this._optionsService=i,this.isCursorHidden=!1,this._onData=this._register(new a.Emitter),this.onData=this._onData.event,this._onUserInput=this._register(new a.Emitter),this.onUserInput=this._onUserInput.event,this._onBinary=this._register(new a.Emitter),this.onBinary=this._onBinary.event,this._onRequestScrollToBottom=this._register(new a.Emitter),this.onRequestScrollToBottom=this._onRequestScrollToBottom.event,this.isCursorInitialized=i.rawOptions.showCursorImmediately??!1,this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}reset(){this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;const i=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&i.ybase!==i.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data "${e}"`),this._logService.trace("sending data (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary "${e}"`),this._logService.trace("sending binary (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onBinary.fire(e))}};t.CoreService=c,t.CoreService=c=s([r(0,n.IBufferService),r(1,n.ILogService),r(2,n.IOptionsService)],c)},4720(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationLineCache=t.DecorationService=void 0;const o=i(3132),n=i(4103),a=i(4812),h=i(6501),l=i(3087),c=i(8636);let d=0,_=0,u=class extends a.Disposable{get decorations(){return this._decorations.values()}constructor(e,t){super(),this._logService=e,this._bufferService=t,this._lineCache=this._register(new f),this._onDecorationRegistered=this._register(new c.Emitter),this.onDecorationRegistered=this._onDecorationRegistered.event,this._onDecorationRemoved=this._register(new c.Emitter),this.onDecorationRemoved=this._onDecorationRemoved.event,this._decorations=new l.SortedList(e=>e?.marker.line,this._logService),this._register((0,a.toDisposable)(()=>this.reset())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)})),this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)}registerDecoration(e){if(e.marker.isDisposed)return;const t=new p(e);if(t){const e=t.marker.onDispose(()=>t.dispose()),i=t.onDispose(()=>{i.dispose(),t&&(this._decorations.delete(t)&&(this._lineCache.remove(t),this._onDecorationRemoved.fire(t)),e.dispose())});this._decorations.insert(t),this._lineCache.add(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(const e of this._decorations.values())e.dispose();this._decorations.clear(),this._lineCache.clear()}*getDecorationsAtCell(e,t,i){const s=this._lineCache.getDecorationsOnLine(t);if(s)for(const t of s)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&(yield t)}forEachDecorationAtCell(e,t,i,s){const r=this._lineCache.getDecorationsOnLine(t);if(r)for(const t of r)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&s(t)}};t.DecorationService=u,t.DecorationService=u=s([r(0,h.ILogService),r(1,h.IBufferService)],u);class f extends a.Disposable{constructor(){super(...arguments),this._decorationsByLine=new Map,this._decorations=new Set,this._bufferLineListeners=this._register(new a.MutableDisposable),this._lineIndexSyncTimer=this._register(new o.MicrotaskTimer),this._lineIndexSyncCallbacks=[]}clear(){this._lineIndexSyncCallbacks.length=0,this._lineIndexSyncTimer.cancel(),this._decorationsByLine.clear(),this._decorations.clear()}add(e){this._decorations.add(e),this._addToLineBuckets(e)}remove(e){this._decorations.delete(e),this._removeFromLineBuckets(e)}getDecorationsOnLine(e){return this._decorationsByLine.get(e)}attachToBufferLines(e){const t=new a.DisposableStore;this._bufferLineListeners.value=t,t.add(e.onTrim(e=>this._handleBufferLinesTrim(e))),t.add(e.onInsert(e=>this._handleBufferLinesInsert(e))),t.add(e.onDelete(e=>this._handleBufferLinesDelete(e)))}_getDecorationHeight(e){return e.options.height??1}_addToLineBuckets(e){const t=e.marker.line;if(t<0)return;e._indexedStartLine=t;const i=this._getDecorationHeight(e);for(let s=t;s=0&&this._addToLineBuckets(e)}_scheduleLineIndexSync(e){this._lineIndexSyncCallbacks.push(e),this._lineIndexSyncTimer.set(()=>{const e=this._lineIndexSyncCallbacks;this._lineIndexSyncCallbacks=[];for(const t of e)t()})}_handleBufferLinesTrim(e){if(e<=0)return;const t=new Map;for(const[i,s]of this._decorationsByLine){const r=i-e;r<0||this._mergeLineBucket(t,r,s)}this._decorationsByLine.clear();for(const[e,i]of t)this._decorationsByLine.set(e,i);for(const t of this._decorations)t.marker.isDisposed||(t._indexedStartLine-=e)}_handleBufferLinesInsert(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesInsert(e))}_handleBufferLinesDelete(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesDelete(e))}_mergeLineBucket(e,t,i){const s=e.get(t);if(s)for(let e=0,t=i.length;et&&(s.push(e),this._removeFromLineBuckets(e))}const r=new Map;for(const[e,s]of this._decorationsByLine){const o=e>=t?e+i:e;this._mergeLineBucket(r,o,s)}this._decorationsByLine.clear();for(const[e,t]of r)this._decorationsByLine.set(e,t);for(const e of this._decorations)e.marker.isDisposed||e._indexedStartLine>=t&&(e._indexedStartLine=e.marker.line);for(const e of s)this._addToLineBuckets(e)}_applyBufferLinesDelete(e){const t=e.index+e.amount,i=new Map;for(const[s,r]of this._decorationsByLine){if(s>=e.index&&s=t?s-e.amount:s;this._mergeLineBucket(i,o,r)}this._decorationsByLine.clear();for(const[e,t]of i)this._decorationsByLine.set(e,t);const s=[];for(const i of this._decorations){if(i.marker.isDisposed)continue;const r=i._indexedStartLine,o=this._getDecorationHeight(i);r>=t?i._indexedStartLine=i.marker.line:rt&&s.push(i)}for(const e of s)this._reindexDecoration(e)}}t.DecorationLineCache=f;class p extends a.DisposableStore{get backgroundColorRGB(){return null===this._cachedBg&&(this.options.backgroundColor?this._cachedBg=n.css.toColor(this.options.backgroundColor):this._cachedBg=void 0),this._cachedBg}get foregroundColorRGB(){return null===this._cachedFg&&(this.options.foregroundColor?this._cachedFg=n.css.toColor(this.options.foregroundColor):this._cachedFg=void 0),this._cachedFg}constructor(e){super(),this.options=e,this.onRenderEmitter=this.add(new c.Emitter),this.onRender=this.onRenderEmitter.event,this._onDispose=this.add(new c.Emitter),this.onDispose=this._onDispose.event,this._cachedBg=null,this._cachedFg=null,this.marker=e.marker,this._indexedStartLine=e.marker.line,this.options.overviewRulerOptions&&!this.options.overviewRulerOptions.position&&(this.options.overviewRulerOptions.position="full")}dispose(){this._onDispose.fire(),super.dispose()}}},6025(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.InstantiationService=t.ServiceCollection=void 0;const s=i(6501),r=i(6201);class o{constructor(...e){this._entries=new Map;for(const[t,i]of e)this.set(t,i)}set(e,t){const i=this._entries.get(e);return this._entries.set(e,t),i}forEach(e){for(const[t,i]of this._entries.entries())e(t,i)}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)}}t.ServiceCollection=o,t.InstantiationService=class{constructor(){this._services=new o,this._services.set(s.IInstantiationService,this)}setService(e,t){this._services.set(e,t)}getService(e){return this._services.get(e)}createInstance(e,...t){const i=(0,r.getServiceDependencies)(e).sort((e,t)=>e.index-t.index),s=[];for(const t of i){const i=this._services.get(t.id);if(!i)throw new Error(`[createInstance] ${e.name} depends on UNKNOWN service ${t.id._id}.`);s.push(i)}const o=i.length>0?i[0].index:t.length;if(t.length!==o)throw new Error(`[createInstance] First service dependency of ${e.name} at position ${o+1} conflicts with ${t.length} static arguments`);return new e(...[...t,...s])}}},7276(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.LogService=void 0;const o=i(4812),n=i(6501),a={trace:n.LogLevelEnum.TRACE,debug:n.LogLevelEnum.DEBUG,info:n.LogLevelEnum.INFO,warn:n.LogLevelEnum.WARN,error:n.LogLevelEnum.ERROR,off:n.LogLevelEnum.OFF};let h=class extends o.Disposable{get logLevel(){return this._logLevel}constructor(e){super(),this._optionsService=e,this._logLevel=n.LogLevelEnum.OFF,this._updateLogLevel(),this._register(this._optionsService.onSpecificOptionChange("logLevel",()=>this._updateLogLevel()))}_updateLogLevel(){this._logLevel=a[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;t!1},X10:{events:1,restrict:e=>4!==e.button&&1===e.action&&(e.ctrl=!1,e.alt=!1,e.shift=!1,!0)},VT200:{events:19,restrict:e=>32!==e.action},DRAG:{events:23,restrict:e=>32!==e.action||3!==e.button},ANY:{events:31,restrict:e=>!0}};function n(e,t){let i=(e.ctrl?16:0)|(e.shift?4:0)|(e.alt?8:0);return 4===e.button?(i|=64,i|=e.action):(i|=3&e.button,4&e.button&&(i|=64),8&e.button&&(i|=128),32===e.action?i|=32:0!==e.action||t||(i|=3)),i}const a=String.fromCharCode,h={DEFAULT:e=>{const t=[n(e,!1)+32,e.col+32,e.row+32];return t[0]>255||t[1]>255||t[2]>255?"":`${a(t[0])}${a(t[1])}${a(t[2])}`},SGR:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.col};${e.row}${t}`},SGR_PIXELS:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.x};${e.y}${t}`}};class l extends s.Disposable{constructor(){super(),this._protocols={},this._encodings={},this._activeProtocol="",this._activeEncoding="",this._onProtocolChange=this._register(new r.Emitter),this.onProtocolChange=this._onProtocolChange.event;for(const e of Object.keys(o))this.addProtocol(e,o[e]);for(const e of Object.keys(h))this.addEncoding(e,h[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return 0!==this._protocols[this._activeProtocol].events}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol "${e}"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding "${e}"`);this._activeEncoding=e}reset(){this.activeProtocol="NONE",this.activeEncoding="DEFAULT"}setCustomWheelEventHandler(e){this._customWheelEventHandler=e}allowCustomWheelEvent(e){return!this._customWheelEventHandler||!1!==this._customWheelEventHandler(e)}restrictMouseEvent(e){return this._protocols[this._activeProtocol].restrict(e)}encodeMouseEvent(e){return this._encodings[this._activeEncoding](e)}get isDefaultEncoding(){return"DEFAULT"===this._activeEncoding}get isPixelEncoding(){return"SGR_PIXELS"===this._activeEncoding}}t.MouseStateService=l},56(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OptionsService=t.DEFAULT_OPTIONS=void 0;const s=i(4812),r=i(701),o=i(8636);t.DEFAULT_OPTIONS={cols:80,rows:24,showCursorImmediately:!1,cursorBlink:!1,blinkIntervalDuration:0,cursorStyle:"block",cursorWidth:1,cursorInactiveStyle:"outline",drawBoldTextInBrightColors:!0,documentOverride:null,fastScrollSensitivity:5,fontFamily:"monospace",fontSize:15,fontWeight:"normal",fontWeightBold:"bold",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:"info",logger:null,scrollback:1e3,scrollbar:{showScrollbar:!0},scrollOnEraseInDisplay:!1,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,mouseEventsRequireAlt:!1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},reflowCursorLine:!1,rescaleOverlappingGlyphs:!1,rightClickSelectsWord:r.isMac,windowOptions:{},windowsPty:{},wordSeparator:" ()[]{}',\"`",altClickMovesCursor:!0,convertEol:!1,termName:"xterm",quirks:{},vtExtensions:{}};const n=["normal","bold","100","200","300","400","500","600","700","800","900"];class a extends s.Disposable{constructor(e){super(),this._onOptionChange=this._register(new o.Emitter),this.onOptionChange=this._onOptionChange.event;const i={...t.DEFAULT_OPTIONS};for(const t in e)if(t in i)try{const s=e[t];i[t]=this._sanitizeAndValidateOption(t,s)}catch(e){console.error(e)}this.rawOptions=i,this.options={...i},this._setupOptions(),this._register((0,s.toDisposable)(()=>{this.rawOptions.linkHandler=null,this.rawOptions.documentOverride=null}))}onSpecificOptionChange(e,t){return this.onOptionChange(i=>{i===e&&t(this.rawOptions[e])})}onMultipleOptionChange(e,t){return this.onOptionChange(i=>{-1!==e.indexOf(i)&&t()})}_setupOptions(){const e=e=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);return this.rawOptions[e]},i=(e,i)=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);i=this._sanitizeAndValidateOption(e,i),this.rawOptions[e]!==i&&(this.rawOptions[e]=i,this._onOptionChange.fire(e))};for(const t in this.rawOptions){const s={get:e.bind(this,t),set:i.bind(this,t)};Object.defineProperty(this.options,t,s)}}_sanitizeAndValidateOption(e,i){switch(e){case"cursorStyle":if(i||(i=t.DEFAULT_OPTIONS[e]),!function(e){return"block"===e||"underline"===e||"bar"===e}(i))throw new Error(`"${i}" is not a valid value for ${e}`);break;case"wordSeparator":i||(i=t.DEFAULT_OPTIONS[e]);break;case"fontWeight":case"fontWeightBold":if("number"==typeof i&&1<=i&&i<=1e3)break;i=n.includes(i)?i:t.DEFAULT_OPTIONS[e];break;case"blinkIntervalDuration":if((i=Math.floor(i))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"cursorWidth":i=Math.floor(i);case"lineHeight":case"tabStopWidth":if(i<1)throw new Error(`${e} cannot be less than 1, value: ${i}`);break;case"minimumContrastRatio":i=Math.max(1,Math.min(21,Math.round(10*i)/10));break;case"scrollback":if((i=Math.min(i,4294967295))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"fastScrollSensitivity":case"scrollSensitivity":if(i<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${i}`);break;case"rows":case"cols":if(!i&&0!==i)throw new Error(`${e} must be numeric, value: ${i}`);break;case"windowsPty":i=i??{}}return i}}t.OptionsService=a},8811(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkService=void 0;const o=i(6501);let n=class{constructor(e){this._bufferService=e,this._nextId=1,this._entriesWithId=new Map,this._dataByLinkId=new Map}registerLink(e){const t=this._bufferService.buffer;if(void 0===e.id){const i=t.addMarker(t.ybase+t.y),s={data:e,id:this._nextId++,lines:[i]};return i.onDispose(()=>this._removeMarkerFromLink(s,i)),this._dataByLinkId.set(s.id,s),s.id}const i=e,s=this._getEntryIdKey(i),r=this._entriesWithId.get(s);if(r)return this.addLineToLink(r.id,t.ybase+t.y),r.id;const o=t.addMarker(t.ybase+t.y),n={id:this._nextId++,key:this._getEntryIdKey(i),data:i,lines:[o]};return o.onDispose(()=>this._removeMarkerFromLink(n,o)),this._entriesWithId.set(n.key,n),this._dataByLinkId.set(n.id,n),n.id}addLineToLink(e,t){const i=this._dataByLinkId.get(e);if(i&&i.lines.every(e=>e.line!==t)){const e=this._bufferService.buffer.addMarker(t);i.lines.push(e),e.onDispose(()=>this._removeMarkerFromLink(i,e))}}getLinkData(e){return this._dataByLinkId.get(e)?.data}_getEntryIdKey(e){return`${e.id};;${e.uri}`}_removeMarkerFromLink(e,t){const i=e.lines.indexOf(t);-1!==i&&(e.lines.splice(i,1),0===e.lines.length&&(void 0!==e.data.id&&this._entriesWithId.delete(e.key),this._dataByLinkId.delete(e.id)))}};t.OscLinkService=n,t.OscLinkService=n=s([r(0,o.IBufferService)],n)},6201(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.serviceRegistry=void 0,t.getServiceDependencies=function(e){return e.di$dependencies||[]},t.createDecorator=function(e){if(t.serviceRegistry.has(e))return t.serviceRegistry.get(e);const i=function(e,t,s){if(3!==arguments.length)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");!function(e,t,i){t.di$target===t?t.di$dependencies.push({id:e,index:i}):(t.di$dependencies=[{id:e,index:i}],t.di$target=t)}(i,e,s)};return i._id=e,t.serviceRegistry.set(e,i),i},t.serviceRegistry=new Map},6501(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IDecorationService=t.IUnicodeService=t.IOscLinkService=t.IOptionsService=t.ILogService=t.LogLevelEnum=t.IInstantiationService=t.ICharsetService=t.ICoreService=t.IMouseStateService=t.IBufferService=void 0;const s=i(6201);var r;t.IBufferService=(0,s.createDecorator)("BufferService"),t.IMouseStateService=(0,s.createDecorator)("MouseStateService"),t.ICoreService=(0,s.createDecorator)("CoreService"),t.ICharsetService=(0,s.createDecorator)("CharsetService"),t.IInstantiationService=(0,s.createDecorator)("InstantiationService"),function(e){e[e.TRACE=0]="TRACE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.OFF=5]="OFF"}(r||(t.LogLevelEnum=r={})),t.ILogService=(0,s.createDecorator)("LogService"),t.IOptionsService=(0,s.createDecorator)("OptionsService"),t.IOscLinkService=(0,s.createDecorator)("OscLinkService"),t.IUnicodeService=(0,s.createDecorator)("UnicodeService"),t.IDecorationService=(0,s.createDecorator)("DecorationService")},6415(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeService=void 0;const s=i(8636);class r{constructor(){this._providers=Object.create(null),this._active="",this._onChange=new s.Emitter,this.onChange=this._onChange.event}static extractShouldJoin(e){return!!(1&e)}static extractWidth(e){return e>>1&3}static extractCharKind(e){return e>>3}static createPropertyValue(e,t,i=!1){return(16777215&e)<<3|(3&t)<<1|(i?1:0)}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(e){if(!this._providers[e])throw new Error(`unknown Unicode version "${e}"`);this._active=e,this._activeProvider=this._providers[e],this._onChange.fire(e)}register(e){this._providers[e.version]=e,this._active||(this.activeVersion=e.version)}wcwidth(e){return this._activeProvider.wcwidth(e)}getStringCellWidth(e){let t=0,i=0;const s=e.length;for(let o=0;o=s)return t+this.wcwidth(n);const i=e.charCodeAt(o);56320<=i&&i<=57343?n=1024*(n-55296)+i-56320+65536:t+=this.wcwidth(i)}const a=this.charProperties(n,i);let h=r.extractWidth(a);r.extractShouldJoin(a)&&(h-=r.extractWidth(i)),t+=h,i=a}return t}charProperties(e,t){return this._activeProvider.charProperties(e,t)}}t.UnicodeService=r}},t={};return function i(s){var r=t[s];if(void 0!==r)return r.exports;var o=t[s]={exports:{}};return e[s].call(o.exports,o,o.exports,i),o.exports}(6081)})()); -+!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(globalThis,()=>(()=>{"use strict";var e={2840(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=r.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this._register(new c.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this._register(this._terminal.onResize(e=>this._handleResize(e.rows))),this._register(this._terminal.onRender(e=>this._refreshRows(e.start,e.end))),this._register(this._terminal.onScroll(()=>this._refreshRows())),this._register(this._terminal.onA11yChar(e=>this._handleChar(e))),this._register(this._terminal.onLineFeed(()=>this._handleChar("\n"))),this._register(this._terminal.onA11yTab(e=>this._handleTab(e))),this._register(this._terminal.onKey(e=>this._handleKey(e.key))),this._register(this._terminal.onBlur(()=>this._clearLiveRegion())),this._register(this._renderService.onDimensionsChange(()=>this._refreshRowsDimensions())),this._register((0,f.addDisposableListener)(r,"selectionchange",()=>this._handleSelectionChange())),this._register(this._coreBrowserService.onDprChange(()=>this._refreshRowsDimensions())),this._refreshRowsDimensions(),this._refreshRows(),this._register((0,d.toDisposable)(()=>{this._accessibilityContainer.remove(),this._rowElements.length=0}))}_handleTab(e){for(let t=0;t0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,"\n"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent=l.tooMuchOutput.get())))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.lines.get(i.ydisp+r),t=[],o=e?.translateToString(!0,void 0,void 0,t)||"",n=(i.ydisp+r+1).toString(),a=this._rowElements[r];a&&(0===o.length?(a.textContent=" ",this._rowColumns.set(a,[0,1])):(a.textContent=o,this._rowColumns.set(a,t)),a.setAttribute("aria-posinset",n),a.setAttribute("aria-setsize",s),this._alignRowWidth(a))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent===l.tooMuchOutput.get()&&this._clearLiveRegion(),this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute("aria-posinset")===(0===t?"1":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,o;if(0===t?(r=i,o=this._rowElements.pop(),this._rowContainer.removeChild(o)):(r=this._rowElements.shift(),o=i,this._rowContainer.removeChild(r)),r.removeEventListener("focus",this._topBoundaryFocusListener),o.removeEventListener("focus",this._bottomBoundaryFocusListener),0===t){const e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement("afterbegin",e)}else{const e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._terminal.scrollLines(0===t?-1:1),this._rowElements[0===t?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleSelectionChange(){if(0===this._rowElements.length)return;const e=this._coreBrowserService.mainDocument.getSelection();if(!e)return;if(e.isCollapsed)return void(this._rowContainer.contains(e.anchorNode)&&this._terminal.clearSelection());if(!e.anchorNode||!e.focusNode)return void console.error("anchorNode and/or focusNode are null");let t={node:e.anchorNode,offset:e.anchorOffset},i={node:e.focusNode,offset:e.focusOffset};if((t.node.compareDocumentPosition(i.node)&Node.DOCUMENT_POSITION_PRECEDING||t.node===i.node&&t.offset>i.offset)&&([t,i]=[i,t]),t.node.compareDocumentPosition(this._rowElements[0])&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_FOLLOWING)&&(t={node:this._rowElements[0].childNodes[0],offset:0}),!this._rowContainer.contains(t.node))return;const s=this._rowElements.slice(-1)[0];if(i.node.compareDocumentPosition(s)&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_PRECEDING)&&(i={node:s,offset:s.textContent?.length??0}),!this._rowContainer.contains(i.node))return;const r=({node:e,offset:t})=>{const i=e instanceof Text?e.parentNode:e;let s=parseInt(i?.getAttribute("aria-posinset"),10)-1;if(isNaN(s))return console.warn("row is invalid. Race condition?"),null;const r=this._rowColumns.get(i);if(!r)return console.warn("columns is null. Race condition?"),null;let o=t=this._terminal.cols&&(++s,o=0),{row:s,column:o}},o=r(t),n=r(i);if(o&&n){if(o.row>n.row||o.row===n.row&&o.column>=n.column)throw new Error("invalid range");this._terminal.select(o.column,o.row,(n.row-o.row)*this._terminal.cols-o.column+n.column)}}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener("focus",this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;ee;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const e=this._coreBrowserService.mainDocument.createElement("div");return e.setAttribute("role","listitem"),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){Object.assign(this._accessibilityContainer.style,{width:`${this._renderService.dimensions.css.canvas.width}px`,fontSize:`${this._terminal.options.fontSize}px`}),this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;ethis._onBell.fire())),this._register(this._inputHandler.onRequestRefreshRows(e=>this.refresh(e?.start??0,e?.end??this.rows-1))),this._register(this._inputHandler.onRequestSendFocus(()=>this._reportFocus())),this._register(this._inputHandler.onRequestReset(()=>this.reset())),this._register(this._inputHandler.onRequestWindowsOptionsReport(e=>this._reportWindowsOptions(e))),this._register(this._inputHandler.onColor(e=>this._handleColorEvent(e))),this._register(I.EventUtils.forward(this._inputHandler.onCursorMove,this._onCursorMove)),this._register(I.EventUtils.forward(this._inputHandler.onTitleChange,this._onTitleChange)),this._register(I.EventUtils.forward(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this._register(I.EventUtils.forward(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this._register(this._bufferService.onResize(e=>this._afterResize(e.cols,e.rows))),this._register((0,N.toDisposable)(()=>{this._customKeyEventHandler=void 0,this.element?.parentNode?.removeChild(this.element)}))}_handleColorEvent(e){if(this._themeService)for(const t of e){let e,i;switch(t.index){case 256:e="foreground",i="10";break;case 257:e="background",i="11";break;case 258:e="cursor",i="12";break;default:e="ansi",i="4;"+t.index}switch(t.type){case 0:const s=E.color.toColorRGB("ansi"===e?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`]${i};${(0,R.toRgbString)(s)}\\`);break;case 1:if("ansi"===e)this._themeService.modifyColors(e=>e.ansi[t.index]=E.channels.toColor(...t.color));else{const i=e;this._themeService.modifyColors(e=>e[i]=E.channels.toColor(...t.color))}break;case 2:this._themeService.restoreColor(t.index)}}}_reportColorScheme(){if(!this._themeService)return;const e=E.rgb.relativeLuminance(this._themeService.colors.background.rgba>>8)>8)?1:2;this.coreService.triggerDataEvent(`[?997;${e}n`)}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(A.AccessibilityManager,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.add("focus"),this._showCursor(),this._onFocus.fire()}blur(){return this.textarea?.blur()}_handleTextAreaBlur(){this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.blur(),this.textarea.value="",this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.remove("focus"),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;const e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;const i=Math.min(this.buffer.x,this.cols-1),s=this._renderService.dimensions.css.cell.height,r=t.getWidth(i),o=this._renderService.dimensions.css.cell.width*r,n=this.buffer.y*this._renderService.dimensions.css.cell.height,a=i*this._renderService.dimensions.css.cell.width;this.textarea.style.left=a+"px",this.textarea.style.top=n+"px",this.textarea.style.width=o+"px",this.textarea.style.height=s+"px",this.textarea.style.lineHeight=s+"px",this.textarea.style.zIndex="-5"}_initGlobal(){this._bindKeys(),this._register((0,H.addDisposableListener)(this.element,"copy",e=>{this.hasSelection()&&(0,a.copyHandler)(e,this._selectionService)}));const e=e=>(0,a.handlePasteEvent)(e,this.textarea,this.coreService,this.optionsService);this._register((0,H.addDisposableListener)(this.textarea,"paste",e)),this._register((0,H.addDisposableListener)(this.element,"paste",e)),L.isFirefox?this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>{2===e.button&&(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})):this._register((0,H.addDisposableListener)(this.element,"contextmenu",e=>{(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})),L.isLinux&&this._register((0,H.addDisposableListener)(this.element,"auxclick",e=>{1===e.button&&(0,a.moveTextAreaUnderMouseCursor)(e,this.textarea,this.screenElement)}))}_bindKeys(){this._register((0,H.addDisposableListener)(this.textarea,"keyup",e=>this._keyUp(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keydown",e=>this._keyDown(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keypress",e=>this._keyPress(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"compositionstart",()=>{this._syncTextArea(),this._compositionHelper.compositionstart(),this._compositionHelper.updateCompositionElements()})),this._register((0,H.addDisposableListener)(this.textarea,"compositionupdate",e=>this._compositionHelper.compositionupdate(e))),this._register((0,H.addDisposableListener)(this.textarea,"compositionend",e=>{this._compositionHelper instanceof u.CompositionHelper?this._compositionHelper.compositionend(e)&&this.textarea.dispatchEvent(new CustomEvent("xterm-composition-transaction-accepted",{bubbles:!0})):this._compositionHelper.compositionend()})),this._register((0,H.addDisposableListener)(this.textarea,"input",e=>this._inputEvent(e),!0)),this._register(this.onRender(()=>this._compositionHelper.updateCompositionElements()))}open(e){if(!e)throw new Error("Terminal requires a parent element.");if(e.isConnected||this._logService.debug("Terminal.open was called on an element that was not attached to the DOM"),this.element?.ownerDocument.defaultView&&this._coreBrowserService)return void(this.element.ownerDocument.defaultView!==this._coreBrowserService.window&&(this._coreBrowserService.window=this.element.ownerDocument.defaultView));this._document=e.ownerDocument,this.options.documentOverride&&this.options.documentOverride instanceof Document&&(this._document=this.optionsService.rawOptions.documentOverride),this.element=this._document.createElement("div"),this.element.dir="ltr",this.element.classList.add("terminal"),this.element.classList.add("xterm"),this.element.classList.toggle("allow-transparency",this.options.allowTransparency),this._register(this.optionsService.onSpecificOptionChange("allowTransparency",e=>this.element.classList.toggle("allow-transparency",e))),e.appendChild(this.element);const t=this._document.createDocumentFragment();this._viewportElement=this._document.createElement("div"),this._viewportElement.classList.add("xterm-viewport"),t.appendChild(this._viewportElement),this.screenElement=this._document.createElement("div"),this.screenElement.classList.add("xterm-screen"),this._register((0,H.addDisposableListener)(this.screenElement,"mousemove",e=>this.updateCursorStyle(e))),this._helperContainer=this._document.createElement("div"),this._helperContainer.classList.add("xterm-helpers"),this.screenElement.appendChild(this._helperContainer),t.appendChild(this.screenElement);const i=this.textarea=this._document.createElement("textarea");this.textarea.classList.add("xterm-helper-textarea"),this.textarea.setAttribute("aria-label",h.promptLabel.get()),L.isChromeOS||this.textarea.setAttribute("aria-multiline","false"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.tabIndex=0,this._register(this.optionsService.onSpecificOptionChange("disableStdin",()=>i.readOnly=this.optionsService.rawOptions.disableStdin)),this.textarea.readOnly=this.optionsService.rawOptions.disableStdin,this._coreBrowserService=this._register(this._instantiationService.createInstance(g.CoreBrowserService,this.textarea,e.ownerDocument.defaultView??window,this._document??("undefined"!=typeof window?window.document:null))),this._instantiationService.setService(C.ICoreBrowserService,this._coreBrowserService),this._register((0,H.addDisposableListener)(this.textarea,"focus",e=>this._handleTextAreaFocus(e))),this._register((0,H.addDisposableListener)(this.textarea,"blur",()=>this._handleTextAreaBlur())),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(p.CharSizeService,this._document,this._helperContainer),this._instantiationService.setService(C.ICharSizeService,this._charSizeService),this._themeService=this._instantiationService.createInstance(k.ThemeService),this._instantiationService.setService(C.IThemeService,this._themeService),this._register(this._inputHandler.onRequestColorSchemeQuery(()=>this._reportColorScheme())),this._register(this._themeService.onChangeColors(()=>{this.coreService.decPrivateModes.colorSchemeUpdates&&this._reportColorScheme()})),this._characterJoinerService=this._instantiationService.createInstance(v.CharacterJoinerService),this._instantiationService.setService(C.ICharacterJoinerService,this._characterJoinerService),this._renderService=this._register(this._instantiationService.createInstance(y.RenderService,this.rows,this.screenElement)),this._instantiationService.setService(C.IRenderService,this._renderService),this._register(this._renderService.onRenderedViewportChange(e=>this._onRender.fire(e))),this._register(this._renderService.onDimensionsChange(e=>this._onDimensionsChange.fire({css:{canvas:{...e.css.canvas},cell:{...e.css.cell}},device:{canvas:{...e.device.canvas},cell:{...e.device.cell},char:{...e.device.char}}}))),this.onResize(e=>this._renderService.resize(e.cols,e.rows)),this._compositionView=this._document.createElement("div"),this._compositionView.classList.add("composition-view"),this._compositionHelper=this._instantiationService.createInstance(u.CompositionHelper,this.textarea,this._compositionView),this._register((0,N.toDisposable)(()=>{this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.dispose()})),this._helperContainer.appendChild(this._compositionView),this._mouseCoordsService=this._instantiationService.createInstance(S.MouseCoordsService),this._instantiationService.setService(C.IMouseCoordsService,this._mouseCoordsService);const s=this._linkifier.value=this._register(this._instantiationService.createInstance(O.Linkifier,this.screenElement));this.element.appendChild(t);try{this._onWillOpen.fire(this.element)}catch(e){this._logService.error("onWillOpen handler threw an exception",e)}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._register(this.onCursorMove(()=>{this._renderService.handleCursorMove(),this._syncTextArea()})),this._register(this.onResize(()=>{this._renderService.handleResize(this.cols,this.rows),this._syncTextArea()})),this._register(this.onBlur(()=>this._renderService.handleBlur())),this._register(this.onFocus(()=>this._renderService.handleFocus())),this._viewport=this._register(this._instantiationService.createInstance(c.Viewport,this.element,this.screenElement)),this._register(this._viewport.onRequestScrollLines(e=>{super.scrollLines(e,!1),this.refresh(0,this.rows-1)})),this._selectionService=this._register(this._instantiationService.createInstance(w.SelectionService,this.element,this.screenElement,s)),this._instantiationService.setService(C.ISelectionService,this._selectionService),this._mouseService=this._instantiationService.createInstance(b.MouseService),this._instantiationService.setService(C.IMouseService,this._mouseService),this._register(this._selectionService.onRequestScrollLines(e=>this.scrollLines(e.amount,e.suppressScrollEvent))),this._register(this._selectionService.onSelectionChange(()=>this._onSelectionChange.fire())),this._register(this._selectionService.onRequestRedraw(e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode))),this._register(this._selectionService.onLinuxMouseSelection(e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()})),this._register(I.EventUtils.any(this._onScroll.event,this._inputHandler.onScroll)(()=>{this._selectionService.refresh(),this._viewport?.queueSync()})),this._register(this._instantiationService.createInstance(d.BufferDecorationRenderer,this.screenElement)),this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>this._selectionService.handleMouseDown(e))),this.mouseStateService.areMouseEventsActive&&!this.options.mouseEventsRequireAlt?(this._selectionService.disable(),this.element.classList.add("enable-mouse-events")):(this._selectionService.enable(),this.element.classList.remove("enable-mouse-events")),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(A.AccessibilityManager,this)),this._register(this.optionsService.onSpecificOptionChange("screenReaderMode",e=>this._handleScreenReaderModeOptionChange(e)));const r=this.options.scrollbar?.showScrollbar??!0,o=this.options.scrollbar?.width;r&&o&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange("scrollbar",e=>{const t=(e?.showScrollbar??!0)&&!!e?.width;!this._overviewRulerRenderer&&t&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement)))}),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this._mouseService.bindMouse({element:this.element,screenElement:this.screenElement,document:this._document,handleTouchScroll:e=>this._viewport?.handleTouchScroll(e)},e=>this._register(e),()=>this.focus())}_createRenderer(){return this._instantiationService.createInstance(f.DomRenderer,this,this._document,this.element,this.screenElement,this._viewportElement,this._helperContainer,this.linkifier)}refresh(e,t,i=!1){this._renderService?.refreshRows(e,t,i)}updateCursorStyle(e){this._selectionService?.shouldColumnSelect(e)?this.element.classList.add("column-select"):this.element.classList.remove("column-select")}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t){this._viewport?this._viewport.scrollLines(e):super.scrollLines(e,t),this.refresh(0,this.rows-1)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){e&&this._viewport?this._viewport.scrollToLine(this.buffer.ybase,!0):this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}paste(e){(0,a.paste)(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}attachCustomWheelEventHandler(e){this.mouseStateService.setCustomWheelEventHandler(e)}registerLinkProvider(e){return this._linkProviderService.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");const t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return!!this._selectionService&&this._selectionService.hasSelection}select(e,t,i){this._selectionService.setSelection(e,t,i)}getSelection(){return this._selectionService?this._selectionService.selectionText:""}getSelectionPosition(){if(this._selectionService&&this._selectionService.hasSelection)return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){this._selectionService?.clearSelection()}selectAll(){this._selectionService?.selectAll()}selectLines(e,t){this._selectionService?.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;const t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(!0),!1;t||"Dead"!==e.key&&"AltGraph"!==e.key||(this._unprocessedDeadKey=!0);const i=this._keyboardService.evaluateKeyDown(e);if(this.updateCursorStyle(e),3===i.type||2===i.type){const t=this.rows-1;return this.scrollLines(2===i.type?-t:t),e.preventDefault(),e.stopPropagation(),!1}if(1===i.type&&this.selectAll(),this._isThirdLevelShift(this.browser,e))return!0;if(i.cancel&&(e.preventDefault(),e.stopPropagation()),!i.key)return!0;if(!this._keyboardService.useKitty&&!this._keyboardService.useWin32InputMode&&e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&1===e.key.length&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)return!0;if(this._unprocessedDeadKey)return this._unprocessedDeadKey=!1,!0;""!==i.key&&"\r"!==i.key||(this.textarea.value="");const s=this._keyboardService.useWin32InputMode&&W(e);if(this._onKey.fire({key:i.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(i.key,!s),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey)return e.preventDefault(),e.stopPropagation(),!1;this._keyDownHandled=!0}_isThirdLevelShift(e,t){const i=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState("AltGraph");return"keypress"===t.type?i:i&&(!t.keyCode||t.keyCode>47)}_keyUp(e){if(this._keyDownSeen=!1,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return;W(e)||this.focus();const t=this._keyboardService.evaluateKeyUp(e);if(t?.key){const i=this._keyboardService.useWin32InputMode&&W(e);this.coreService.triggerDataEvent(t.key,!i)}this.updateCursorStyle(e),this._keyPressHandled=!1}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled)return!1;if(this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;if(e.charCode)t=e.charCode;else if(null===e.which||void 0===e.which)t=e.keyCode;else{if(0===e.which||0===e.charCode)return!1;t=e.which}return!(!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)||(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this._compositionHelper.keypress?.(t)||this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,0))}_inputEvent(e){if(e.data&&"insertText"===e.inputType&&!this.optionsService.rawOptions.screenReaderMode&&this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.input(e.data))return!0;if(e.data&&"insertText"===e.inputType&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;const t=e.data;return this.coreService.triggerDataEvent(t,!0),!0}return!1}resize(e,t){e!==this.cols||t!==this.rows?super.resize(e,t):this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure()}_afterResize(e,t){this._charSizeService?.measure()}clear(){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;efunction(e){const t=l(e);for(t.animFrameRequested=!1,t.current=t.next,t.next=[],t.inAnimationFrameRunner=!0;t.current.length>0;)t.current.sort(a.sort),t.current.shift().execute();t.inAnimationFrameRunner=!1}(e))),r};const s=i(3132);function r(e){const t=e;if(t?.ownerDocument?.defaultView)return t.ownerDocument.defaultView;const i=e;return i?.view?i.view:window}class o{constructor(e,t,i,s){this._node=e,this._type=t,this._handler=i,this._options=s,e.addEventListener(t,i,s)}dispose(){this._node&&this._handler&&(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}}function n(e,t,i,s){return new o(e,t,i,s)}t.eventType={CLICK:"click",MOUSE_DOWN:"mousedown",MOUSE_OVER:"mouseover",MOUSE_LEAVE:"mouseleave",KEY_DOWN:"keydown",KEY_UP:"keyup",INPUT:"input",BLUR:"blur",FOCUS:"focus",CHANGE:"change",POINTER_DOWN:"pointerdown",POINTER_MOVE:"pointermove",POINTER_UP:"pointerup",MOUSE_WHEEL:"wheel",WHEEL:"wheel"};class a{constructor(e,t){this._runner=e,this.priority=t,this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(e){console.error(e)}}static sort(e,t){return t.priority-e.priority}}const h=new Map;function l(e){let t=h.get(e);return t||(t={next:[],current:[],animFrameRequested:!1,inAnimationFrameRunner:!1},h.set(e,t)),t}class c extends s.IntervalTimer{constructor(e){super(),this._defaultTarget=e?r(e):void 0}cancelAndSet(e,t,i){super.cancelAndSet(e,t,i??this._defaultTarget??window)}}t.WindowIntervalTimer=c},8906(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Linkifier=void 0;const o=i(4812),n=i(6501),a=i(7098),h=i(8636),l=i(4159);let c=class extends o.Disposable{get currentLink(){return this._currentLink}constructor(e,t,i,s,r){super(),this._element=e,this._mouseCoordsService=t,this._renderService=i,this._bufferService=s,this._linkProviderService=r,this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this._register(new h.Emitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this._register(new h.Emitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this._register((0,o.toDisposable)(()=>{(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0,this._lastMouseEvent=void 0,this._activeProviderReplies?.clear()})),this._register(this._bufferService.onResize(()=>{this._clearCurrentLink(),this._wasResized=!0})),this._register((0,l.addDisposableListener)(this._element,"mouseleave",()=>{this._isMouseOut=!0,this._clearCurrentLink()})),this._register((0,l.addDisposableListener)(this._element,"mousemove",this._handleMouseMove.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mousedown",this._handleMouseDown.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mouseup",this._handleMouseUp.bind(this)))}_handleMouseMove(e){this._lastMouseEvent=e;const t=this._positionFromMouseEvent(e,this._element);if(!t)return;this._isMouseOut=!1;const i=e.composedPath();for(let e=0;e{e?.forEach(e=>{e.link.dispose&&e.link.dispose()})}),this._activeProviderReplies=new Map,this._activeLine=e.y);let i=!1;for(const[s,r]of this._linkProviderService.linkProviders.entries())if(t){const t=this._activeProviderReplies?.get(s);t&&(i=this._checkLinkProviderResult(s,e,i))}else r.provideLinks(e.y,t=>{if(this._isMouseOut)return;const r=t?.map(e=>({link:e}));this._activeProviderReplies?.set(s,r),i=this._checkLinkProviderResult(s,e,i),this._activeProviderReplies?.size===this._linkProviderService.linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)})}_removeIntersectingLinks(e,t){const i=new Set;for(let s=0;se?this._bufferService.cols:s.link.range.end.x;for(let e=o;e<=n;e++){if(i.has(e)){r.splice(t--,1);break}i.add(e)}}}}_checkLinkProviderResult(e,t,i){if(!this._activeProviderReplies)return i;const s=this._activeProviderReplies.get(e);let r=!1;for(let t=0;tthis._linkAtPosition(e.link,t));e&&(i=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviderService.linkProviders.length&&!i)for(let e=0;ethis._linkAtPosition(e.link,t));if(s){i=!0,this._handleNewLink(s);break}}return i}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._currentLink)return;const t=this._positionFromMouseEvent(e,this._element);var i,s;t&&this._mouseDownLink&&(i=this._mouseDownLink.link,s=this._currentLink.link,i.text===s.text&&i.range.start.x===s.range.start.x&&i.range.start.y===s.range.start.y&&i.range.end.x===s.range.end.x&&i.range.end.y===s.range.end.y)&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){this._currentLink&&this._lastMouseEvent&&(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0)}_handleNewLink(e){if(!this._lastMouseEvent)return;const t=this._positionFromMouseEvent(this._lastMouseEvent,this._element);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:void 0===e.link.decorations||e.link.decorations.underline,pointerCursor:void 0===e.link.decorations||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>this._currentLink?.state?.decorations.pointerCursor,set:e=>{this._currentLink?.state&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&this._element.classList.toggle("xterm-cursor-pointer",e))}},underline:{get:()=>this._currentLink?.state?.decorations.underline,set:t=>{this._currentLink?.state&&this._currentLink?.state?.decorations.underline!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e=>{if(!this._currentLink)return;const t=0===e.start?0:e.start+1+this._bufferService.buffer.ydisp,i=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=i&&(this._clearCurrentLink(t,i),this._lastMouseEvent)){const e=this._positionFromMouseEvent(this._lastMouseEvent,this._element);e&&this._askForLink(e,!1)}})))}_linkHover(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add("xterm-cursor-pointer")),t.hover&&t.hover(i,t.text)}_fireUnderlineEvent(e,t){const i=e.range,s=this._bufferService.buffer.ydisp,r=this._createLinkUnderlineEvent(i.start.x-1,i.start.y-s-1,i.end.x,i.end.y-s-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(r)}_linkLeave(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove("xterm-cursor-pointer")),t.leave&&t.leave(i,t.text)}_linkAtPosition(e,t){const i=e.range.start.y*this._bufferService.cols+e.range.start.x,s=e.range.end.y*this._bufferService.cols+e.range.end.x,r=t.y*this._bufferService.cols+t.x;return i<=r&&r<=s}_positionFromMouseEvent(e,t){const i=this._mouseCoordsService.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(i)return{x:i[0],y:i[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,i,s,r){return{x1:e,y1:t,x2:i,y2:s,cols:this._bufferService.cols,fg:r}}};t.Linkifier=c,t.Linkifier=c=s([r(1,a.IMouseCoordsService),r(2,a.IRenderService),r(3,n.IBufferService),r(4,a.ILinkProviderService)],c)},7721(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.tooMuchOutput=t.promptLabel=void 0;let i="Terminal input";const s={get:()=>i,set:e=>i=e};t.promptLabel=s;let r="Too much output to announce, navigate to rows manually to read";const o={get:()=>r,set:e=>r=e};t.tooMuchOutput=o},3285(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkProvider=void 0;const o=i(3055),n=i(6501);let a=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i,this._workCell=new o.CellData}provideLinks(e,t){const i=this._bufferService.buffer.lines.get(e-1);if(!i)return void t(void 0);const s=[],r=this._optionsService.rawOptions.linkHandler,o=this._workCell,n=i.getTrimmedLength();let a=-1,l=-1,c=!1;for(let t=0;tr?r.activate(e,t,d):h(0,t),hover:(e,t)=>r?.hover?.(e,t,d),leave:(e,t)=>r?.leave?.(e,t,d)})}c=!1,o.hasExtendedAttrs()&&o.extended.urlId?(l=t,a=o.extended.urlId):(l=-1,a=-1)}}t(s)}_getRangeWithLineWrap(e,t,i,s){let r=e,o=t,n=e,a=i;for(;0===o;){const e=this._bufferService.buffer.lines.get(r-1);if(!e?.isWrapped)break;const t=this._bufferService.buffer.lines.get(r-2);if(!t)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,i-1,s))break;let n=i-1;for(;n>0&&this._hasUrlId(t,n-1,s);)n--;r--,o=n}for(;;){const e=this._bufferService.buffer.lines.get(n-1);if(!e)break;if(a!==e.getTrimmedLength())break;const t=this._bufferService.buffer.lines.get(n);if(!t?.isWrapped)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,0,s))break;let r=1;for(;rthis._innerRefresh()),this._animationFrame}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return void this._runRefreshCallbacks();const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(const e of this._refreshCallbacks)e(0);this._refreshCallbacks=[]}}},4292(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.TimeBasedDebouncer=void 0,t.TimeBasedDebouncer=class{constructor(e,t=1e3){this._renderCallback=e,this._debounceThresholdMS=t,this._lastRefreshMs=0,this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0),this._additionalRefreshRequested=!1}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t;const s=performance.now();if(s-this._lastRefreshMs>=this._debounceThresholdMS)void 0!==this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0,this._additionalRefreshRequested=!1),this._lastRefreshMs=s,this._innerRefresh();else if(!this._additionalRefreshRequested){const e=s-this._lastRefreshMs,t=this._debounceThresholdMS-e;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout(()=>{this._lastRefreshMs=performance.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0},t)}}_innerRefresh(){if(void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return;const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t)}}},9302(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_ANSI_COLORS=void 0;const s=i(4103);t.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const e=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],t=[0,95,135,175,215,255];for(let i=0;i<216;i++){const r=t[i/36%6|0],o=t[i/6%6|0],n=t[i%6];e.push({css:s.channels.toCss(r,o,n),rgba:s.channels.toRgba(r,o,n)})}for(let t=0;t<24;t++){const i=8+10*t;e.push({css:s.channels.toCss(i,i,i),rgba:s.channels.toRgba(i,i,i)})}return e})())},4017(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Viewport=void 0;const o=i(7098),n=i(4812),a=i(6501),h=i(4159),l=i(8566),c=i(8636),d=i(7880);let _=class extends n.Disposable{constructor(e,t,i,s,r,o,a,_,u){super(),this._bufferService=i,this._coreService=r,this._optionsService=_,this._renderService=u,this._onRequestScrollLines=this._register(new c.Emitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._isSyncing=!1,this._isHandlingScroll=!1,this._suppressOnScrollHandler=!1,this._needsSyncOnRender=!1;const f=this._register(new d.Scrollable({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:e=>(0,h.scheduleAtNextAnimationFrame)(s.window,e)}));this._register(this._optionsService.onSpecificOptionChange("smoothScrollDuration",()=>{f.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)})),this._scrollableElement=this._register(new l.SmoothScrollableElement(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,verticalHasArrows:this._optionsService.rawOptions.scrollbar?.showArrows??!1,...this._getChangeOptions()},f)),this._register(this._optionsService.onMultipleOptionChange(["scrollSensitivity","fastScrollSensitivity","scrollbar"],()=>this._scrollableElement.updateOptions(this._getChangeOptions()))),this._register(o.onProtocolChange(e=>{this._scrollableElement.updateOptions({handleMouseWheel:!(16&e)})})),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{e.style.backgroundColor=a.colors.background.css,this._scrollableElement.getDomNode().style.backgroundColor=a.colors.background.css})),e.appendChild(this._scrollableElement.getDomNode()),this._register((0,n.toDisposable)(()=>this._scrollableElement.getDomNode().remove())),this._styleElement=s.mainDocument.createElement("style"),t.appendChild(this._styleElement),this._register((0,n.toDisposable)(()=>this._styleElement.remove())),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{this._styleElement.textContent=[".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {",` background: ${a.colors.scrollbarSliderBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {",` background: ${a.colors.scrollbarSliderHoverBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {",` background: ${a.colors.scrollbarSliderActiveBackground.css};`,"}"].join("\n")})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(e=>this._handleScroll(e)))}scrollLines(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){const e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,i=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:i,verticalHasArrows:t}}queueSync(e){void 0!==e&&(this._latestYDisp=e),void 0===this._queuedAnimationFrame&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){this._renderService&&!this._isSyncing&&(this._coreService.decPrivateModes.synchronizedOutput?this._needsSyncOnRender=!0:(this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1))}_handleScroll(e){if(!this._renderService)return;if(this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;const t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),i=t-this._bufferService.buffer.ydisp;0!==i&&(this._latestYDisp=t,this._onRequestScrollLines.fire(i)),this._isHandlingScroll=!1}handleTouchScroll(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};t.Viewport=_,t.Viewport=_=s([r(2,a.IBufferService),r(3,o.ICoreBrowserService),r(4,a.ICoreService),r(5,a.IMouseStateService),r(6,o.IThemeService),r(7,a.IOptionsService),r(8,o.IRenderService)],_)},4196(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferDecorationRenderer=void 0;const o=i(7098),n=i(4812),a=i(6501);let h=class extends n.Disposable{constructor(e,t,i,s,r){super(),this._screenElement=e,this._bufferService=t,this._coreBrowserService=i,this._decorationService=s,this._renderService=r,this._decorationElements=new Map,this._altBufferIsActive=!1,this._dimensionsChanged=!1,this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(e=>this._removeDecoration(e))),this._register((0,n.toDisposable)(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){void 0===this._animationFrame&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(const e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){const t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer","top"===e?.options?.layer),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",t.style.top=(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height+"px",t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;const i=e.options.x??0;return i&&i>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){const t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let i=this._decorationElements.get(e);i||(i=this._createElement(e),e.element=i,this._decorationElements.set(e,i),this._container.appendChild(i),e.onDispose(()=>{this._decorationElements.delete(e),i.remove()})),i.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(i.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,i.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",i.style.top=t*this._renderService.dimensions.css.cell.height+"px",i.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(i)}}_refreshXPosition(e,t=e.element){if(!t)return;const i=e.options.x??0;"right"===(e.options.anchor||"left")?t.style.right=i?i*this._renderService.dimensions.css.cell.width+"px":"":t.style.left=i?i*this._renderService.dimensions.css.cell.width+"px":""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};t.BufferDecorationRenderer=h,t.BufferDecorationRenderer=h=s([r(1,a.IBufferService),r(2,o.ICoreBrowserService),r(3,a.IDecorationService),r(4,o.IRenderService)],h)},957(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ColorZoneStore=void 0,t.ColorZoneStore=class{constructor(){this._zones=[],this._zonePool=[],this._zonePoolIndex=0,this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(e){if(e.options.overviewRulerOptions){for(const t of this._zones)if(t.color===e.options.overviewRulerOptions.color&&t.position===e.options.overviewRulerOptions.position){if(this._lineIntersectsZone(t,e.marker.line))return;if(this._lineAdjacentToZone(t,e.marker.line,e.options.overviewRulerOptions.position))return void this._addLineToZone(t,e.marker.line)}if(this._zonePoolIndex=e.startBufferLine&&t<=e.endBufferLine}_lineAdjacentToZone(e,t,i){return t>=e.startBufferLine-this._linePadding[i||"full"]&&t<=e.endBufferLine+this._linePadding[i||"full"]}_addLineToZone(e,t){e.startBufferLine=Math.min(e.startBufferLine,t),e.endBufferLine=Math.max(e.endBufferLine,t)}}},9925(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OverviewRulerRenderer=void 0;const o=i(957),n=i(7098),a=i(4812),h=i(6501),l={full:0,left:0,center:0,right:0},c={full:0,left:0,center:0,right:0},d={full:0,left:0,center:0,right:0};let _=class extends a.Disposable{get _width(){const e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??1?e?.width??0:0}constructor(e,t,i,s,r,n,h,l){super(),this._viewportElement=e,this._screenElement=t,this._bufferService=i,this._decorationService=s,this._renderService=r,this._optionsService=n,this._themeService=h,this._coreBrowserService=l,this._colorZoneStore=new o.ColorZoneStore,this._shouldUpdateDimensions=!0,this._shouldUpdateAnchor=!0,this._lastKnownBufferLength=0,this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register((0,a.toDisposable)(()=>this._canvas?.remove()));const c=this._canvas.getContext("2d");if(!c)throw new Error("Ctx cannot be null");this._ctx=c,this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register((0,a.toDisposable)(()=>{void 0!==this._animationFrame&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}_refreshDrawConstants(){const e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);c.full=this._canvas.width,c.left=e,c.center=t,c.right=e,this._refreshDrawHeightConstants(),d.full=1,d.left=1,d.center=1+c.left,d.right=1+c.left+c.center}_refreshDrawHeightConstants(){l.full=Math.round(2*this._coreBrowserService.dpr);const e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);l.left=t,l.center=t,l.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;const e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(const e of this._decorationService.decorations)this._colorZoneStore.addDecoration(e);this._ctx.lineWidth=1,this._renderRulerOutline();const e=this._colorZoneStore.zones;for(const t of e)"full"!==t.position&&this._renderColorZone(t);for(const t of e)"full"===t.position&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect(d[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-l[e.position||"full"]/2),c[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+l[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};t.OverviewRulerRenderer=_,t.OverviewRulerRenderer=_=s([r(2,h.IBufferService),r(3,h.IDecorationService),r(4,n.IRenderService),r(5,h.IOptionsService),r(6,n.IThemeService),r(7,n.ICoreBrowserService)],_)},3618(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CompositionHelper=void 0;const o=i(7098),n=i(6501),a="xterm-composition-session-end";let h=class{get isComposing(){return this._isComposing}get hasPendingCompositionFinalization(){return void 0!==this._pendingComposition}get _isSendingComposition(){return this.hasPendingCompositionFinalization}get _pendingKeypressData(){return this._pendingComposition?.keypressData??""}constructor(e,t,i,s,r,o){this._textarea=e,this._compositionView=t,this._bufferService=i,this._optionsService=s,this._coreService=r,this._renderService=o,this._isComposing=!1,this._isAwaitingCompositionEnd=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionStartValue="",this._compositionStartSelection={start:0,end:0},this._compositionHasObservedProgress=!1,this._compositionTransactionId=0,this._compositionTimers=new Set}compositionstart(){this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=void 0,this._cancelDeferredTimer(this._compositionViewTimer),this._compositionViewTimer=void 0,this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._pendingComposition&&(this._cancelPendingFinalizer(this._pendingComposition),this._endPendingCompositionSession(this._pendingComposition),this._settlePendingComposition(this._pendingComposition)),void 0!==this._textareaChangeTimer&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);const e=this._textarea.selectionStart??this._textarea.value.length,t=this._textarea.selectionEnd??e;this._compositionPosition.start=Math.min(e,t),this._compositionPosition.end=Math.max(e,t),this._compositionStartValue=this._textarea.value,this._compositionStartSelection={start:e,end:t},this._compositionHasObservedProgress=!1,this._pendingComposition&&(this._pendingComposition.nextCompositionStart=this._compositionPosition.start),this._compositionTransactionId++,this._isComposing=!0,this._isAwaitingCompositionEnd=!0,this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionView.classList.add("active"),this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-session-start",{bubbles:!0,detail:{id:this._compositionTransactionId}}))}compositionupdate(e){this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._compositionHasObservedProgress||=this._hasCompositionProgress(),e.data?.length>0&&(this._lastCompositionData=e.data),this._compositionView.textContent=`‎${e.data??""}‎`,this.updateCompositionElements();const t=this._compositionTransactionId;this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=this._defer(()=>{if(this._isComposing&&this._compositionTransactionId===t){this._compositionHasObservedProgress||=this._hasCompositionProgress();const e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)}})}compositionend(e){if(!this._isAwaitingCompositionEnd)return!1;if(!this._isComposing){const t=this._pendingComposition;return t?.transactionId===this._compositionTransactionId&&(t.endData=e?.data??"",this._updatePostCompositionInputExpectation(t)),!1}const t=e?.data??"";if(this._compositionHasObservedProgress||=this._hasCompositionProgress(),!this._compositionEndBelongsToCurrentTransaction(t)){const e=this._pendingComposition;return e&&e.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(e),this._deferCompositionEnd(t),!1}return this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._finalizeComposition(!0,t),!0}blur(){if(this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._isComposing){const e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)}(this._isComposing||this.hasPendingCompositionFinalization)&&this._finalizeComposition(!1)}dispose(){void 0!==this._textareaChangeTimer&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);for(const e of this._compositionTimers)clearTimeout(e);this._compositionTimers.clear(),this._compositionPositionTimer=void 0,this._compositionViewTimer=void 0,this._compositionEndTimer=void 0,this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionTransactionId++}keydown(e){if(this._canceledKey?.code===e.code&&this._canceledKey.timeStamp===e.timeStamp)return this._canceledKey=void 0,!1;if("Escape"===e.key&&(this._isComposing||this.hasPendingCompositionFinalization))return this._canceledKey={code:e.code,timeStamp:e.timeStamp},this._cancelComposition(),!1;if(this._isComposing||this.hasPendingCompositionFinalization){if(20===e.keyCode||229===e.keyCode)return!1;if(16===e.keyCode||17===e.keyCode||18===e.keyCode)return!1;this._finalizeComposition(!1)}return 229!==e.keyCode||(this._handleAnyTextareaChanges(),!1)}keypress(e){const t=this._pendingComposition;return!(!t||(t.keypressMayOverlapComposition?(t.keypressData+=e,0):t.expectsPostCompositionInput&&0===t.keypressData.length?(t.keypressData=e,0):(this._sendPendingComposition(t),1)))}input(e){if(this._isComposing)return this._compositionHasObservedProgress||=this._hasCompositionProgress(),this._compositionInputData+=e,!0;const t=this._pendingComposition;if(!t)return!1;if(t.expectsPostCompositionInput)return t.inputData+=e,t.expectsPostCompositionInput=!1,this._sendPendingComposition(t),!0;const i=e.length>0&&this._getPendingTextareaInput(t)===e&&this._getPendingTextareaInput(t,!0)===e;return this._sendPendingComposition(t),i||this._coreService.triggerDataEvent(e,!0),!0}_finalizeComposition(e,t=""){const i=this._isComposing;if(this._compositionView.classList.remove("active"),this._isComposing=!1,!e||i)if(e){this._pendingComposition&&this._sendPendingComposition(this._pendingComposition);const e={transactionId:this._compositionTransactionId,lifecycleSettled:!1,sessionEnded:!1,position:{start:this._compositionPosition.start,end:this._compositionPosition.end},suffix:this._compositionSuffix,dataAlreadySent:this._dataAlreadySent,compositionData:this._lastCompositionData,endData:t,inputData:this._compositionInputData,keypressData:"",keypressMayOverlapComposition:0===this._lastCompositionData.length&&0===t.length,expectsPostCompositionInput:!1};this._updatePostCompositionInputExpectation(e),this._pendingComposition=e,e.finalizerTimer=this._defer(()=>{e.finalizerTimer=void 0,this._compositionTransactionId===e.transactionId&&(this._isAwaitingCompositionEnd=!1),this._pendingComposition===e&&this._sendPendingComposition(e,!0)})}else if(this._pendingComposition&&this._sendPendingComposition(this._pendingComposition,!0),i){const e=this._getCompositionInput(this._compositionPosition.start+this._dataAlreadySent.length,this._compositionSuffix);this._sendCompositionInput(this._compositionTransactionId,e)}}_sendPendingComposition(e,t=!1){this._cancelPendingFinalizer(e),this._pendingComposition===e&&(this._pendingComposition=void 0);const i=this._getPendingTextareaInput(e,t),s=this._removeAlreadySentData(e.inputData||e.keypressData,e.dataAlreadySent),r=this._mergeTextObservations(i||e.endData||e.compositionData,s,e.keypressMayOverlapComposition);this._sendCompositionInput(e.transactionId,r,!e.sessionEnded),this._settlePendingComposition(e)}_cancelPendingFinalizer(e){void 0!==e.finalizerTimer&&(clearTimeout(e.finalizerTimer),this._compositionTimers.delete(e.finalizerTimer),e.finalizerTimer=void 0)}_settlePendingComposition(e){e.lifecycleSettled||(e.lifecycleSettled=!0,this._dispatchCompositionTransactionSettled())}_mergeTextObservations(e,t,i){if(!t||e.includes(t))return e;if(!e||t.includes(e))return t;if(i){let i=Math.min(e.length,t.length);for(;i>0&&!e.endsWith(t.substring(0,i));)i--;let s=Math.min(e.length,t.length);for(;s>0&&!t.endsWith(e.substring(0,s));)s--;return i>s?e+t.substring(i):t+e.substring(s)}let s=Math.min(e.length,t.length);for(;s>0&&!e.endsWith(t.substring(0,s));)s--;return e+t.substring(s)}_updatePostCompositionInputExpectation(e){e.expectsPostCompositionInput=(e.endData.length>0||e.compositionData.length>0)&&0===e.inputData.length&&0===this._getPendingTextareaInput(e).length}_getPendingTextareaInput(e,t=!1){const i=this._textarea.value,s=e.position.start+e.dataAlreadySent.length;if(void 0!==e.nextCompositionStart)return i.substring(s,Math.max(s,e.nextCompositionStart));const r=e.suffix.length>0&&i.endsWith(e.suffix)?i.length-e.suffix.length:i.length,o=(e.endData||e.compositionData).length,n=t?r:Math.max(e.position.end,s+o);return i.substring(s,Math.max(s,Math.min(r,n)))}_getCompositionInput(e,t){const i=this._textarea.value,s=t.length>0&&i.endsWith(t)?i.length-t.length:i.length;return i.substring(e,Math.max(e,s))}_removeAlreadySentData(e,t){return 0===t.length?e:e.startsWith(t)?e.substring(t.length):t.includes(e)?"":e}_cancelComposition(){const e=this._pendingComposition;e&&this._isComposing&&e.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(e);const t=this._isComposing?this._compositionTransactionId:this._pendingComposition?.transactionId??0,i=void 0!==e&&this._pendingComposition===e;this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionView.classList.remove("active"),this._textarea.value=this._textarea.value.substring(0,this._compositionPosition.start)+this._compositionSuffix,this._sendCompositionInput(t,""),i&&e&&this._settlePendingComposition(e)}_sendCompositionInput(e,t,i=!0){let s=!1;if(i){const i=new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:{id:e,data:t}});this._dispatchCompositionSessionEvent(i),s=i.defaultPrevented}t.length>0&&!s&&this._coreService.triggerDataEvent(t,!0)}_endPendingCompositionSession(e){if(e.sessionEnded)return;e.sessionEnded=!0;const t=this._getPendingTextareaInput(e)||e.endData||e.compositionData;this._dispatchCompositionSessionEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:{id:e.transactionId,data:t,dataPendingReconciliation:!0}}))}_dispatchCompositionSessionEvent(e){"function"==typeof this._textarea.dispatchEvent&&this._textarea.dispatchEvent(e)}_dispatchCompositionTransactionSettled(){this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-settled",{bubbles:!0}))}_deferCompositionEnd(e){this._cancelDeferredTimer(this._compositionEndTimer);const t=this._compositionTransactionId,i=this._defer(()=>{if(this._compositionEndTimer!==i||!this._isComposing||this._compositionTransactionId!==t||!this._compositionEndBelongsToCurrentTransaction(e))return;this._compositionEndTimer=void 0,this._finalizeComposition(!0,e),this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-accepted",{bubbles:!0}));const s=this._pendingComposition;s?.transactionId===t&&this._sendPendingComposition(s,!0)});this._compositionEndTimer=i}_hasCompositionProgress(){const e=this._textarea.selectionStart??this._textarea.value.length,t=this._textarea.selectionEnd??e;return this._compositionHasObservedProgress||this._textarea.value!==this._compositionStartValue||e!==this._compositionStartSelection.start||t!==this._compositionStartSelection.end}_compositionEndBelongsToCurrentTransaction(e){return this._hasCompositionProgress()||e.length>0&&e===this._lastCompositionData}_defer(e){const t=setTimeout(()=>{this._compositionTimers.delete(t),e()},0);return this._compositionTimers.add(t),t}_cancelDeferredTimer(e){void 0!==e&&(clearTimeout(e),this._compositionTimers.delete(e))}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;const e=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){const t=this._textarea.value,i=t.replace(e,"");this._dataAlreadySent=i,t.length>e.length?this._coreService.triggerDataEvent(i,!0):t.lengththis.updateCompositionElements(!0)))}}};t.CompositionHelper=h,t.CompositionHelper=h=s([r(2,n.IBufferService),r(3,n.IOptionsService),r(4,n.ICoreService),r(5,o.IRenderService)],h)},5251(e,t){function i(e,t,i){const s=i.getBoundingClientRect(),r=e.getComputedStyle(i),o=parseInt(r.getPropertyValue("padding-left"),10),n=parseInt(r.getPropertyValue("padding-top"),10);return[t.clientX-s.left-o,t.clientY-s.top-n]}Object.defineProperty(t,"__esModule",{value:!0}),t.getCoordsRelativeToElement=i,t.getCoords=function(e,t,s,r,o,n,a,h,l){if(!n)return;const c=i(e,t,s);return c[0]=Math.ceil((c[0]+(l?a/2:0))/a),c[1]=Math.ceil(c[1]/h),c[0]=Math.min(Math.max(c[0],1),r+(l?1:0)),c[1]=Math.min(Math.max(c[1],1),o),c}},9686(e,t){function i(e,t,i,o){const h=e-s(e,i),l=t-s(t,i),c=Math.abs(h-l)-function(e,t,i){let o=0;const n=e-s(e,i),a=t-s(t,i);for(let s=0;s=0&&et?"A":"B"}function o(e,t,i,s,r,o){let n=e,a=t,h="";for(;(n!==i||a!==s)&&a>=0&&ao.cols-1?(h+=o.buffer.translateBufferLineToString(a,!1,e,n),n=0,e=0,a++):!r&&n<0&&(h+=o.buffer.translateBufferLineToString(a,!1,0,e+1),n=o.cols-1,e=n,a--);return h+o.buffer.translateBufferLineToString(a,!1,e,n)}function n(e,t){return""+(t?"O":"[")+e}function a(e,t){e=Math.floor(e);let i="";for(let s=0;s0?h-s(h,l):t;const _=h,u=function(e,t,r,o,n,a){let h;return h=i(t,o,n,a).length>0?o-s(o,n):t,e=r&&he?"D":"C",a(Math.abs(l-e),n(d,h));d=c>t?"D":"C";const _=Math.abs(c-t);return a(function(e,t){return t.cols-e}(c>t?e:l,r)+(_-1)*r.cols+1+((c>t?l:e)-1),n(d,h))}},6081(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._core.options[e],i=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(const e in this._core.options){const s={get:t.bind(this,e),set:i.bind(this,e)};Object.defineProperty(this._publicOptions,e,s)}}_checkReadonlyOptions(e){if(f.includes(e))throw new Error(`Option "${e}" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw new Error("You must set the allowProposedApi option to true to use proposed API")}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get onDimensionsChange(){return this._core.onDimensionsChange}get element(){return this._core.element}get screenElement(){return this._core.screenElement}get parser(){return this._parser??=new _.ParserApi(this._core)}get unicode(){return this._checkProposedApi(),new u.UnicodeApi(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer??=this._register(new d.BufferNamespaceApi(this._core))}get markers(){return this._core.markers}get modes(){const e=this._core.coreService.decPrivateModes;let t="none";switch(this._core.mouseStateService.activeProtocol){case"X10":t="x10";break;case"VT200":t="vt200";break;case"DRAG":t="drag";break;case"ANY":t="any"}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,showCursor:!this._core.coreService.isCursorHidden,synchronizedOutputMode:e.synchronizedOutput,win32InputMode:e.win32InputMode,wraparoundMode:e.wraparound}}get dimensions(){return this._core.dimensions}get options(){return this._publicOptions}set options(e){for(const t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}input(e,t=!0){this._core.input(e,t)}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}attachCustomWheelEventHandler(e){this._core.attachCustomWheelEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){return this._verifyPositiveIntegers(e.x??0,e.width??0,e.height??0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,i){this._verifyIntegers(e,t,i),this._core.select(e,t,i)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write("\r\n",t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return{get promptLabel(){return a.promptLabel.get()},set promptLabel(e){a.promptLabel.set(e)},get tooMuchOutput(){return a.tooMuchOutput.get()},set tooMuchOutput(e){a.tooMuchOutput.set(e)}}}_verifyIntegers(...e){for(p of e)if(p===1/0||isNaN(p)||p%1!=0)throw new Error("This API only accepts integers")}_verifyPositiveIntegers(...e){for(p of e)if(p&&(p===1/0||isNaN(p)||p%1!=0||p<0))throw new Error("This API only accepts positive integers")}}t.Terminal=v},3955(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRenderer=void 0;const o=i(1433),n=i(2744),a=i(9176),h=i(6181),l=i(2274),c=i(654),d=i(7098),_=i(4103),u=i(4812),f=i(6501),p=i(8636),v=i(4159);let g=1,m=class extends u.Disposable{constructor(e,t,i,s,r,a,d,_,f,m,b,y,w,C){super(),this._terminal=e,this._document=t,this._element=i,this._screenElement=s,this._viewportElement=r,this._helperContainer=a,this._linkifier2=d,this._charSizeService=f,this._optionsService=m,this._bufferService=b,this._coreService=y,this._coreBrowserService=w,this._themeService=C,this._terminalClass=g++,this._rowElements=[],this._selectionRenderModel=(0,l.createSelectionRenderModel)(),this._lastSelectionColumnMode=!1,this._rowHasBlinkingCells=[],this._rowHasBlinkingCellsCount=0,this._onRequestRedraw=this._register(new p.Emitter),this.onRequestRedraw=this._onRequestRedraw.event,this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=(0,h.createRenderDimensions)(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(e=>this._injectCss(e))),this._injectCss(this._themeService.colors),this._rowFactory=_.createInstance(o.DomRendererRowFactory,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(e=>this._handleLinkHover(e))),this._register(this._linkifier2.onHideLinkUnderline(e=>this._handleLinkLeave(e))),this._cursorBlinkStateManager=new S(this._rowContainer,this._coreBrowserService),this._register((0,v.addDisposableListener)(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register((0,u.toDisposable)(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new c.TextBlinkStateManager(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register((0,u.toDisposable)(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new n.WidthCache,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){const e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(const e of this._rowElements)e.style.width=`${this.dimensions.css.canvas.width}px`,e.style.height=`${this.dimensions.css.cell.height}px`,e.style.lineHeight=`${this.dimensions.css.cell.height}px`,e.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));const t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${_.color.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;const i=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,r=`blink_block_${this._terminalClass}`;t+=`@keyframes ${i} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${r} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${i} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(const[i,s]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${i} { color: ${s.css}; }${this._terminalSelector} .xterm-fg-${i}.xterm-dim { color: ${_.color.multiplyOpacity(s,.5).css}; }${this._terminalSelector} .xterm-bg-${i} { background-color: ${s.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR} { color: ${_.color.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR}.xterm-dim { color: ${_.color.multiplyOpacity(_.color.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${a.INVERTED_DEFAULT_COLOR} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){const e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let e=this._rowElements.length;e<=t;e++){const e=this._document.createElement("div");this._rowContainer.appendChild(e),this._rowElements.push(e),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,i){const s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,i);let r=0,o=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(r=this._selectionRenderModel.viewportCappedStartRow,o=this._selectionRenderModel.viewportCappedEndRow));let n=0,a=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,i),this._selectionRenderModel.hasSelection){const s=this._selectionRenderModel.viewportStartRow,r=this._selectionRenderModel.viewportEndRow,o=this._selectionRenderModel.viewportCappedStartRow,h=this._selectionRenderModel.viewportCappedEndRow;n=o,a=h;const l=this._document.createDocumentFragment();if(i){const i=e[0]>t[0];l.appendChild(this._createSelectionElement(o,i?t[0]:e[0],i?e[0]:t[0],h-o+1))}else{const i=s===o?e[0]:0,n=o===r?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(o,i,n));const a=h-o-1;if(l.appendChild(this._createSelectionElement(o+1,0,this._bufferService.cols,a)),o!==h){const e=r===h?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(h,0,e))}}this._selectionContainer.appendChild(l)}let h=Math.min(r,n),l=Math.max(o,a);if(l>=0){h=Math.max(h,0),l=Math.min(l,s-1);const e=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&e>=0&&ethis.dimensions.css.canvas.width&&(n=this.dimensions.css.canvas.width-o),r.style.height=s*this.dimensions.css.cell.height+"px",r.style.top=e*this.dimensions.css.cell.height+"px",r.style.left=`${o}px`,r.style.width=`${n}px`,r}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(const e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){const i=this._bufferService.buffer,s=i.ybase+i.y,r=Math.min(i.x,this._bufferService.cols-1),o=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,n=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,a=this._optionsService.rawOptions.cursorInactiveStyle,h={hasBlinkingCells:!1};for(let l=e;l<=t;l++){const e=l+i.ydisp,t=this._rowElements[l];if(!t)continue;const c=i.lines.get(e);c?(t.replaceChildren(...this._rowFactory.createRow(c,e,e===s,n,a,r,o,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,h)),this._setRowBlinkState(l,h.hasBlinkingCells)):(t.replaceChildren(),this._setRowBlinkState(l,!1))}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,i,s,r,o){i<0&&(e=0),s<0&&(t=0);const n=this._bufferService.rows-1;i=Math.max(Math.min(i,n),0),s=Math.max(Math.min(s,n),0),r=Math.min(r,this._bufferService.cols);const a=this._bufferService.buffer,h=a.ybase+a.y,l=Math.min(a.x,r-1),c=this._optionsService.rawOptions.cursorBlink,d=this._optionsService.rawOptions.cursorStyle,_=this._optionsService.rawOptions.cursorInactiveStyle,u={hasBlinkingCells:!1};for(let n=i;n<=s;++n){const f=n+a.ydisp,p=this._rowElements[n];if(!p)continue;const v=a.lines.get(f);v?(p.replaceChildren(...this._rowFactory.createRow(v,f,f===h,d,_,l,c,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,o?n===i?e:0:-1,o?(n===s?t:r)-1:-1,u)),this._setRowBlinkState(n,u.hasBlinkingCells)):(p.replaceChildren(),this._setRowBlinkState(n,!1))}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};t.DomRenderer=m,t.DomRenderer=m=s([r(7,f.IInstantiationService),r(8,d.ICharSizeService),r(9,f.IOptionsService),r(10,f.IBufferService),r(11,f.ICoreService),r(12,d.ICoreBrowserService),r(13,d.IThemeService)],m);class S{constructor(e,t){this._rowContainer=e,this._coreBrowserService=t,this._isIdlePaused=!1,this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){void 0!==this._idleTimeout&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}}},1433(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRendererRowFactory=void 0;const o=i(9176),n=i(8938),a=i(3055),h=i(6501),l=i(4103),c=i(7098),d=i(945),_=i(6181),u=i(5451);let f=class{constructor(e,t,i,s,r,o,n){this._document=e,this._characterJoinerService=t,this._optionsService=i,this._coreBrowserService=s,this._coreService=r,this._decorationService=o,this._themeService=n,this._workCell=new a.CellData,this._columnSelectMode=!1,this.defaultSpacing=0}handleSelectionChanged(e,t,i){this._selectionStart=e,this._selectionEnd=t,this._columnSelectMode=i}createRow(e,t,i,s,r,a,h,c,_,f,p,v,g){const m=[];g&&(g.hasBlinkingCells=!1);const S=this._characterJoinerService.getJoinedCharacters(t),b=this._themeService.colors;let y,w=e.getNoBgTrimmedLength();i&&w=B,F=I,W=this._workCell;if(S.length>0&&I===S[0][0]&&N){const s=S.shift(),r=this._isCellInSelection(s[0],t);for(C=s[0]+1;C=s[1],N?(H=!0,W=new d.JoinedCellData(this._workCell,e.translateToString(!0,s[0],s[1]),s[1]-s[0]),F=s[1]-1,w=W.getWidth()):B=s[1]}const z=this._isCellInSelection(I,t),K=i&&I===a,U=O&&I>=p&&I<=v;g&&W.isBlink()&&(g.hasBlinkingCells=!0),!c&&W.isBlink()&&A.push("xterm-blink-hidden");let j=!1;this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{j=!0});let $=W.getChars()||n.WHITESPACE_CELL_CHAR;if(" "===$&&(W.isUnderline()||W.isOverline())&&($=" "),k=w*_-f.get($,W.isBold(),W.isItalic()),y){if(D&&(z&&P||!z&&!P&&W.bg===x)&&(z&&P&&b.selectionForeground||W.fg===L)&&W.extended.ext===T&&U===R&&k===M&&!K&&!H&&!j&&N){W.isInvisible()?E+=n.WHITESPACE_CELL_CHAR:E+=$,D++;continue}D&&(y.textContent=E),y=this._document.createElement("span"),D=0,E=""}else y=this._document.createElement("span");if(x=W.bg,L=W.fg,T=W.extended.ext,R=U,M=k,P=z,H&&a>=I&&a<=F&&(a=I),!this._coreService.isCursorHidden&&K&&this._coreService.isCursorInitialized)if(A.push("xterm-cursor"),this._coreBrowserService.isFocused)h&&A.push("xterm-cursor-blink"),A.push("bar"===s?"xterm-cursor-bar":"underline"===s?"xterm-cursor-underline":"xterm-cursor-block");else if(r)switch(r){case"outline":A.push("xterm-cursor-outline");break;case"block":A.push("xterm-cursor-block");break;case"bar":A.push("xterm-cursor-bar");break;case"underline":A.push("xterm-cursor-underline")}if(W.isBold()&&A.push("xterm-bold"),W.isItalic()&&A.push("xterm-italic"),W.isDim()&&A.push("xterm-dim"),E=W.isInvisible()?n.WHITESPACE_CELL_CHAR:W.getChars()||n.WHITESPACE_CELL_CHAR,W.isUnderline()&&(A.push(`xterm-underline-${W.extended.underlineStyle}`)," "===E&&(E=" "),!W.isUnderlineColorDefault()))if(W.isUnderlineColorRGB())y.style.textDecorationColor=`rgb(${u.AttributeData.toColorRGB(W.getUnderlineColor()).join(",")})`;else{let e=W.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&W.isBold()&&e<8&&(e+=8),y.style.textDecorationColor=b.ansi[e].css}W.isOverline()&&(A.push("xterm-overline")," "===E&&(E=" ")),W.isStrikethrough()&&A.push("xterm-strikethrough"),U&&(y.style.textDecoration="underline");let V=W.getFgColor(),q=W.getFgColorMode(),X=W.getBgColor(),Y=W.getBgColorMode();const G=!!W.isInverse();if(G){const e=V;V=X,X=e;const t=q;q=Y,Y=t}let J,Z,Q,ee=!1;switch(this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{"top"!==e.options.layer&&ee||(e.backgroundColorRGB&&(Y=50331648,X=e.backgroundColorRGB.rgba>>8&16777215,J=e.backgroundColorRGB),e.foregroundColorRGB&&(q=50331648,V=e.foregroundColorRGB.rgba>>8&16777215,Z=e.foregroundColorRGB),ee="top"===e.options.layer)}),!ee&&z&&(J=this._coreBrowserService.isFocused?b.selectionBackgroundOpaque:b.selectionInactiveBackgroundOpaque,X=J.rgba>>8&16777215,Y=50331648,ee=!0,b.selectionForeground&&(q=50331648,V=b.selectionForeground.rgba>>8&16777215,Z=b.selectionForeground)),ee&&A.push("xterm-decoration-top"),Y){case 16777216:case 33554432:Q=b.ansi[X],A.push(`xterm-bg-${X}`);break;case 50331648:Q=l.channels.toColor(X>>16,X>>8&255,255&X),this._addStyle(y,`background-color:#${(X>>>0).toString(16).padStart(6,"0")}`);break;default:G?(Q=b.foreground,A.push(`xterm-bg-${o.INVERTED_DEFAULT_COLOR}`)):Q=b.background}switch(J||W.isDim()&&(J=l.color.multiplyOpacity(Q,.5)),q){case 16777216:case 33554432:W.isBold()&&V<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(V+=8),this._applyMinimumContrast(y,Q,b.ansi[V],W,J,void 0)||A.push(`xterm-fg-${V}`);break;case 50331648:const e=l.channels.toColor(V>>16&255,V>>8&255,255&V);this._applyMinimumContrast(y,Q,e,W,J,Z)||this._addStyle(y,`color:#${V.toString(16).padStart(6,"0")}`);break;default:this._applyMinimumContrast(y,Q,b.foreground,W,J,Z)||G&&A.push(`xterm-fg-${o.INVERTED_DEFAULT_COLOR}`)}A.length&&(y.className=A.join(" "),A.length=0),K||H||j||!N?y.textContent=E:D++,k!==this.defaultSpacing&&(y.style.letterSpacing=`${k}px`),m.push(y),I=F}return y&&D&&(y.textContent=E),m}_applyMinimumContrast(e,t,i,s,r,o){if(1===this._optionsService.rawOptions.minimumContrastRatio||(0,_.treatGlyphAsBackgroundColor)(s.getCode()))return!1;const n=this._getContrastCache(s);let a;if(r||o||(a=n.getColor(t.rgba,i.rgba)),void 0===a){const e=this._optionsService.rawOptions.minimumContrastRatio/(s.isDim()?2:1);a=l.color.ensureContrastRatio(r??t,o??i,e),n.setColor((r??t).rgba,(o??i).rgba,a??null)}return!!a&&(this._addStyle(e,`color:${a.css}`),!0)}_getContrastCache(e){return e.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(e,t){e.setAttribute("style",`${e.getAttribute("style")||""}${t};`)}_isCellInSelection(e,t){const i=this._selectionStart,s=this._selectionEnd;return!(!i||!s)&&(this._columnSelectMode?i[0]<=s[0]?e>=i[0]&&t>=i[1]&&e=i[1]&&e>=s[0]&&t<=s[1]:t>i[1]&&t=i[0]&&e=i[0])}};t.DomRendererRowFactory=f,t.DomRendererRowFactory=f=s([r(1,c.ICharacterJoinerService),r(2,h.IOptionsService),r(3,c.ICoreBrowserService),r(4,h.ICoreService),r(5,h.IDecorationService),r(6,c.IThemeService)],f)},2744(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WidthCache=void 0;const s=i(6181);t.WidthCache=class{constructor(e=()=>new r){this._flat=new Float32Array(256),this._font="",this._fontSize=0,this._weight="normal",this._weightBold="bold",this._canvasElements=[],this._canvasElements=[e(),e(),e(),e()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(e,t,i,s){e===this._font&&t===this._fontSize&&i===this._weight&&s===this._weightBold||(this._font=e,this._fontSize=t,this._weight=i,this._weightBold=s,this._canvasElements[0].setFont(e,t,i,!1),this._canvasElements[1].setFont(e,t,s,!1),this._canvasElements[2].setFont(e,t,i,!0),this._canvasElements[3].setFont(e,t,s,!0),this.clear())}get(e,t,i){let s;if(!t&&!i&&1===e.length&&(s=e.charCodeAt(0))<256){if(-9999!==this._flat[s])return this._flat[s];const t=this._measure(e,0);return t>0&&(this._flat[s]=t),t}let r=e;t&&(r+="B"),i&&(r+="I");let o=this._holey.get(r);if(void 0===o){let s=0;t&&(s|=1),i&&(s|=2),o=this._measure(e,s),o>0&&this._holey.set(r,o)}return o}_measure(e,t){return this._canvasElements[t].measure(e)}};class r{constructor(){"undefined"!=typeof OffscreenCanvas?(this._canvas=new OffscreenCanvas(1,1),this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d")))}setFont(e,t,i,s){const r=s?"italic":"";this._ctx.font=`${r} ${i} ${t}px ${e}`.trim()}measure(e){return this._ctx.measureText(e).width}}},9176(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.INVERTED_DEFAULT_COLOR=void 0,t.INVERTED_DEFAULT_COLOR=257},6181(e,t){function i(e){return 57508<=e&&e<=57558}function s(e){return e>=128512&&e<=128591||e>=127744&&e<=128511||e>=128640&&e<=128767||e>=9728&&e<=9983||e>=9984&&e<=10175||e>=65024&&e<=65039||e>=129280&&e<=129535||e>=127462&&e<=127487}Object.defineProperty(t,"__esModule",{value:!0}),t.throwIfFalsy=function(e){if(!e)throw new Error("value must not be falsy");return e},t.isPowerlineGlyph=i,t.isRestrictedPowerlineGlyph=function(e){return 57520<=e&&e<=57527},t.isEmoji=s,t.allowRescaling=function(e,t,r,o){return 1===t&&r>Math.ceil(1.5*o)&&void 0!==e&&e>255&&!s(e)&&!i(e)&&!function(e){return 57344<=e&&e<=63743}(e)},t.treatGlyphAsBackgroundColor=function(e){return i(e)||function(e){return 9472<=e&&e<=9631}(e)},t.createRenderDimensions=function(){return{css:{canvas:{width:0,height:0},cell:{width:0,height:0}},device:{canvas:{width:0,height:0},cell:{width:0,height:0},char:{width:0,height:0,left:0,top:0}}}},t.computeNextVariantOffset=function(e,t,i=0){return(e-(2*Math.round(t)-i))%(2*Math.round(t))}},2274(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.createSelectionRenderModel=function(){return new i};class i{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(e,t,i,s=!1){if(this.selectionStart=t,this.selectionEnd=i,!t||!i||t[0]===i[0]&&t[1]===i[1])return void this.clear();const r=e.buffers.active.ydisp,o=t[1]-r,n=i[1]-r,a=Math.max(o,0),h=Math.min(n,e.rows-1);a>=e.rows||h<0?this.clear():(this.hasSelection=!0,this.columnSelectMode=s,this.viewportStartRow=o,this.viewportEndRow=n,this.viewportCappedStartRow=a,this.viewportCappedEndRow=h,this.startCol=t[0],this.endCol=i[0])}isCellSelected(e,t,i){return!!this.hasSelection&&(i-=e.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?t>=this.startCol&&i>=this.viewportCappedStartRow&&t=this.viewportCappedStartRow&&t>=this.endCol&&i<=this.viewportCappedEndRow:i>this.viewportStartRow&&i=this.startCol&&t=this.startCol)}}},654(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TextBlinkStateManager=void 0;const s=i(4812);class r extends s.Disposable{constructor(e,t,i){super(),this._renderCallback=e,this._coreBrowserService=t,this._optionsService=i,this._intervalDuration=0,this._blinkOn=!0,this._needsBlinkInViewport=!1,this._isViewportVisible=!0,this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",e=>{this.setIntervalDuration(e)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register((0,s.toDisposable)(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(void 0!==this._interval)return;const e=this._blinkOn;return this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),void(e||this._renderCallback())}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){void 0!==this._interval&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}}t.TextBlinkStateManager=r},8501(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._domNodePointerDown(e)))}_createArrow(e){const t=this._register(new c.ScrollbarArrow(e));return this.domNode.domNode.appendChild(t.bgDomNode),this.domNode.domNode.appendChild(t.domNode),t}_createSlider(e,t,i,s){this.slider=new h.FastDomNode(document.createElement("div")),this.slider.setClassName("xterm-slider"),this.slider.setPosition("absolute"),this.slider.setTop(e),this.slider.setLeft(t),"number"==typeof i&&this.slider.setWidth(i),"number"==typeof s&&this.slider.setHeight(s),this.slider.setLayerHinting(!0),this.slider.setContain("strict"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(a.addDisposableListener(this.slider.domNode,a.eventType.POINTER_DOWN,e=>{0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))})),this._onclick(this.slider.domNode,e=>{e.leftButton&&e.stopPropagation()})}_handleElementSize(e){return this._scrollbarState.setVisibleSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollSize(e){return this._scrollbarState.setScrollSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollPosition(e){return this._scrollbarState.setScrollPosition(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(e){e.target===this.domNode.domNode&&this._handlePointerDown(e)}delegatePointerDown(e){const t=this.domNode.domNode.getClientRects()[0].top,i=t+this._scrollbarState.getSliderPosition(),s=t+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),r=this._sliderPointerPosition(e);i<=r&&r<=s?0===e.button&&(e.preventDefault(),this._sliderPointerDown(e)):this._handlePointerDown(e)}_handlePointerDown(e){let t,i;if(e.target===this.domNode.domNode&&"number"==typeof e.offsetX&&"number"==typeof e.offsetY)t=e.offsetX,i=e.offsetY;else{const s=a.getDomNodePagePosition(this.domNode.domNode);t=e.pageX-s.left,i=e.pageY-s.top}const s=this._pointerDownRelativePosition(t,i);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(s):this._scrollbarState.getDesiredScrollPositionFromOffset(s)),0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))}_sliderPointerDown(e){if(!(e.target&&e.target instanceof Element))return;const t=this._sliderPointerPosition(e),i=this._sliderOrthogonalPointerPosition(e),s=this._scrollbarState.clone();this.slider.toggleClassName("xterm-active",!0),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{const r=this._sliderOrthogonalPointerPosition(e),o=Math.abs(r-i);if(u.isWindows&&o>140)return void this._setDesiredScrollPositionNow(s.getScrollPosition());const n=this._sliderPointerPosition(e)-t;this._setDesiredScrollPositionNow(s.getDesiredScrollPositionFromDelta(n))},()=>{this.slider.toggleClassName("xterm-active",!1),this._host.handleDragEnd()}),this._host.handleDragStart()}_setDesiredScrollPositionNow(e){const t={};this.writeScrollPosition(t,e),this._scrollable.setScrollPositionNow(t)}updateScrollbarSize(e){this._updateScrollbarSize(e),this._scrollbarState.setScrollbarSize(e),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}}t.AbstractScrollbar=f},1203(e,t){function i(e){return"number"==typeof e?`${e}px`:e}Object.defineProperty(t,"__esModule",{value:!0}),t.FastDomNode=void 0,t.FastDomNode=class{constructor(e){this.domNode=e,this._width="",this._height="",this._top="",this._left="",this._bottom="",this._right="",this._className="",this._position="",this._layerHint=!1,this._contain="none"}setWidth(e){const t=i(e);this._width!==t&&(this._width=t,this.domNode.style.width=this._width)}setHeight(e){const t=i(e);this._height!==t&&(this._height=t,this.domNode.style.height=this._height)}setTop(e){const t=i(e);this._top!==t&&(this._top=t,this.domNode.style.top=this._top)}setLeft(e){const t=i(e);this._left!==t&&(this._left=t,this.domNode.style.left=this._left)}setBottom(e){const t=i(e);this._bottom!==t&&(this._bottom=t,this.domNode.style.bottom=this._bottom)}setRight(e){const t=i(e);this._right!==t&&(this._right=t,this.domNode.style.right=this._right)}setClassName(e){this._className!==e&&(this._className=e,this.domNode.className=this._className)}toggleClassName(e,t){this.domNode.classList.toggle(e,t),this._className=this.domNode.className}setPosition(e){this._position!==e&&(this._position=e,this.domNode.style.position=this._position)}setLayerHinting(e){this._layerHint!==e&&(this._layerHint=e,this.domNode.style.transform=e?"translate3d(0px, 0px, 0px)":"")}setContain(e){this._contain!==e&&(this._contain=e,this.domNode.style.contain=this._contain)}setAttribute(e,t){this.domNode.setAttribute(e,t)}}},928(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{try{e.releasePointerCapture(t)}catch{}}))}catch{o=a.getWindow(e)}this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_MOVE,e=>{e.buttons===i?(e.preventDefault(),this._pointerMoveCallback(e)):this.stopMonitoring(!0)})),this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_UP,e=>this.stopMonitoring(!0)))}}},9699(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.HorizontalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition();if(super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(t.horizontalHasArrows?t.horizontalScrollbarSize:0,2===t.horizontal?0:t.horizontalScrollbarSize,2===t.vertical?0:t.verticalScrollbarSize,s.width,s.scrollWidth,o.scrollLeft),visibility:t.horizontal,extraScrollbarClassName:"xterm-horizontal",scrollable:e,scrollByPage:t.scrollByPage}),t.horizontalHasArrows)throw new Error("horizontalHasArrows is not supported in xterm.js");this._createSlider(Math.floor((t.horizontalScrollbarSize-t.horizontalSliderSize)/2),0,void 0,t.horizontalSliderSize)}_updateSlider(e,t){this.slider.setWidth(e),this.slider.setLeft(t)}_renderDomNode(e,t){this.domNode.setWidth(e),this.domNode.setHeight(t),this.domNode.setLeft(0),this.domNode.setBottom(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollWidth)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollLeft)||this._shouldRender,this._shouldRender=this._handleElementSize(e.width)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return e}_sliderPointerPosition(e){return e.pageX}_sliderOrthogonalPointerPosition(e){return e.pageY}_updateScrollbarSize(e){this.slider.setHeight(e)}writeScrollPosition(e,t){e.scrollLeft=t}updateOptions(e){this.updateScrollbarSize(2===e.horizontal?0:e.horizontalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._visibilityController.setVisibility(e.horizontal),this._scrollByPage=e.scrollByPage}}t.HorizontalScrollbar=o},3988(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;ni&&(s=i-t),s<0&&(s=0),r<0&&(r=0),n+r>o&&(n=o-r),n<0&&(n=0),this.width=t,this.scrollWidth=i,this.scrollLeft=s,this.height=r,this.scrollHeight=o,this.scrollTop=n}equals(e){return this.rawScrollLeft===e.rawScrollLeft&&this.rawScrollTop===e.rawScrollTop&&this.width===e.width&&this.scrollWidth===e.scrollWidth&&this.scrollLeft===e.scrollLeft&&this.height===e.height&&this.scrollHeight===e.scrollHeight&&this.scrollTop===e.scrollTop}withScrollDimensions(e,t){return new o(this._forceIntegerValues,void 0!==e.width?e.width:this.width,void 0!==e.scrollWidth?e.scrollWidth:this.scrollWidth,t?this.rawScrollLeft:this.scrollLeft,void 0!==e.height?e.height:this.height,void 0!==e.scrollHeight?e.scrollHeight:this.scrollHeight,t?this.rawScrollTop:this.scrollTop)}withScrollPosition(e){return new o(this._forceIntegerValues,this.width,this.scrollWidth,void 0!==e.scrollLeft?e.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,void 0!==e.scrollTop?e.scrollTop:this.rawScrollTop)}createScrollEvent(e,t){const i=this.width!==e.width,s=this.scrollWidth!==e.scrollWidth,r=this.scrollLeft!==e.scrollLeft,o=this.height!==e.height,n=this.scrollHeight!==e.scrollHeight,a=this.scrollTop!==e.scrollTop;return{inSmoothScrolling:t,oldWidth:e.width,oldScrollWidth:e.scrollWidth,oldScrollLeft:e.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:e.height,oldScrollHeight:e.scrollHeight,oldScrollTop:e.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:i,scrollWidthChanged:s,scrollLeftChanged:r,heightChanged:o,scrollHeightChanged:n,scrollTopChanged:a}}}t.ScrollState=o;class n extends r.Disposable{constructor(e){super(),this._scrollableBrand=void 0,this._onScroll=this._register(new s.Emitter),this.onScroll=this._onScroll.event,this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new o(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){const i=this._state.withScrollDimensions(e,t);this._setState(i,Boolean(this._smoothScrolling)),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){const t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(0!==this._smoothScrollDuration){if(this._smoothScrolling){e={scrollLeft:void 0===e.scrollLeft?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:void 0===e.scrollTop?this._smoothScrolling.to.scrollTop:e.scrollTop};const i=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===i.scrollLeft&&this._smoothScrolling.to.scrollTop===i.scrollTop)return;let s;s=t?new l(this._smoothScrolling.from,i,this._smoothScrolling.startTime,this._smoothScrolling.duration):l.start(this._state,i,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{const t=this._state.withScrollPosition(e);this._smoothScrolling=l.start(this._state,t,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}else this.setScrollPositionNow(e)}hasPendingScrollAnimation(){return Boolean(this._smoothScrolling)}_performSmoothScrolling(){if(!this._smoothScrolling)return;const e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);return this._setState(t,!0),this._smoothScrolling?e.isDone?(this._smoothScrolling.dispose(),void(this._smoothScrolling=null)):void(this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})):void 0}_setState(e,t){const i=this._state;i.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(i,t)))}}t.Scrollable=n;class a{constructor(e,t,i){this.scrollLeft=e,this.scrollTop=t,this.isDone=i}}function h(e,t){const i=t-e;return function(t){return e+i*(1-(s=1-t,Math.pow(s,3)));var s}}class l{constructor(e,t,i,s){this.from=e,this.to=t,this.duration=s,this.startTime=i,this.animationFrameDisposable=null,this._initAnimations()}_initAnimations(){this._scrollLeft=this._initAnimation(this.from.scrollLeft,this.to.scrollLeft,this.to.width),this._scrollTop=this._initAnimation(this.from.scrollTop,this.to.scrollTop,this.to.height)}_initAnimation(e,t,i){if(Math.abs(e-t)>2.5*i){let n,a;return e0&&Math.abs(e.deltaY)>0)return 1;let i=.5;if(this._isAlmostInt(e.deltaX)&&this._isAlmostInt(e.deltaY)||(i+=.25),t){const s=Math.abs(e.deltaX),r=Math.abs(e.deltaY),o=Math.abs(t.deltaX),n=Math.abs(t.deltaY),a=Math.max(Math.min(s,o),1),h=Math.max(Math.min(r,n),1),l=Math.max(s,o),c=Math.max(r,n);l%a===0&&c%h===0&&(i-=.5)}return Math.min(Math.max(i,0),1)}_isAlmostInt(e){return Math.abs(Math.round(e)-e)<.01}}S.INSTANCE=new S;class b extends _.Widget{get options(){return this._options}constructor(e,t,i){let s;super(),this._onScroll=this._register(new f.Emitter),this.onScroll=this._onScroll.event,t=t??{};const r=!i;i?s=i:(t.mouseWheelSmoothScroll=!1,s=new g.Scrollable({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:t=>a.scheduleAtNextAnimationFrame(a.getWindow(e),t)})),this._options=function(e){const t={lazyRender:void 0!==e.lazyRender&&e.lazyRender,className:void 0!==e.className?e.className:"",useShadows:void 0===e.useShadows||e.useShadows,handleMouseWheel:void 0===e.handleMouseWheel||e.handleMouseWheel,flipAxes:void 0!==e.flipAxes&&e.flipAxes,consumeMouseWheelIfScrollbarIsNeeded:void 0!==e.consumeMouseWheelIfScrollbarIsNeeded&&e.consumeMouseWheelIfScrollbarIsNeeded,alwaysConsumeMouseWheel:void 0!==e.alwaysConsumeMouseWheel&&e.alwaysConsumeMouseWheel,scrollYToX:void 0!==e.scrollYToX&&e.scrollYToX,mouseWheelScrollSensitivity:void 0!==e.mouseWheelScrollSensitivity?e.mouseWheelScrollSensitivity:1,fastScrollSensitivity:void 0!==e.fastScrollSensitivity?e.fastScrollSensitivity:5,scrollPredominantAxis:void 0===e.scrollPredominantAxis||e.scrollPredominantAxis,mouseWheelSmoothScroll:void 0===e.mouseWheelSmoothScroll||e.mouseWheelSmoothScroll,listenOnDomNode:void 0!==e.listenOnDomNode?e.listenOnDomNode:null,horizontal:void 0!==e.horizontal?e.horizontal:1,horizontalScrollbarSize:void 0!==e.horizontalScrollbarSize?e.horizontalScrollbarSize:10,horizontalSliderSize:void 0!==e.horizontalSliderSize?e.horizontalSliderSize:0,horizontalHasArrows:void 0!==e.horizontalHasArrows&&e.horizontalHasArrows,vertical:void 0!==e.vertical?e.vertical:1,verticalScrollbarSize:void 0!==e.verticalScrollbarSize?e.verticalScrollbarSize:10,verticalHasArrows:void 0!==e.verticalHasArrows&&e.verticalHasArrows,verticalSliderSize:void 0!==e.verticalSliderSize?e.verticalSliderSize:0,scrollByPage:void 0!==e.scrollByPage&&e.scrollByPage};return t.horizontalSliderSize=void 0!==e.horizontalSliderSize?e.horizontalSliderSize:t.horizontalScrollbarSize,t.verticalSliderSize=void 0!==e.verticalSliderSize?e.verticalSliderSize:t.verticalScrollbarSize,v.isMac&&(t.className+=" xterm-mac"),t}(t),this._scrollable=s,this._register(this._scrollable.onScroll(e=>{this._handleScroll(e),this._onScroll.fire(e)})),r&&this._register(this._scrollable);const o={handleMouseWheel:e=>this._handleMouseWheel(e),handleDragStart:()=>this._handleDragStart(),handleDragEnd:()=>this._handleDragEnd()};this._verticalScrollbar=this._register(new d.VerticalScrollbar(this._scrollable,this._options,o)),this._horizontalScrollbar=this._register(new c.HorizontalScrollbar(this._scrollable,this._options,o)),this._domNode=document.createElement("div"),this._domNode.className="xterm-scrollable-element "+this._options.className,this._domNode.setAttribute("role","presentation"),this._domNode.style.position="relative",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._leftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topLeftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode??this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this._onmouseover(this._listenOnDomNode,e=>this._handleMouseOver(e)),this._onmouseleave(this._listenOnDomNode,e=>this._handleMouseLeave(e)),this._hideTimeout=this._register(new u.TimeoutTimer),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}dispose(){this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}updateClassName(e){this._options.className=e,v.isMac&&(this._options.className+=" xterm-mac"),this._domNode.className="xterm-scrollable-element "+this._options.className}updateOptions(e){void 0!==e.handleMouseWheel&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),void 0!==e.mouseWheelScrollSensitivity&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),void 0!==e.fastScrollSensitivity&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),void 0!==e.scrollPredominantAxis&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),void 0!==e.horizontal&&(this._options.horizontal=e.horizontal),void 0!==e.vertical&&(this._options.vertical=e.vertical),void 0!==e.horizontalHasArrows&&(this._options.horizontalHasArrows=e.horizontalHasArrows),void 0!==e.verticalHasArrows&&(this._options.verticalHasArrows=e.verticalHasArrows),void 0!==e.horizontalScrollbarSize&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),void 0!==e.verticalScrollbarSize&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),void 0!==e.scrollByPage&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}delegateScrollFromMouseWheelEvent(e){this._handleMouseWheel(new l.StandardWheelEvent(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),e)){const e=e=>{this._handleMouseWheel(new l.StandardWheelEvent(e))};this._mouseWheelToDispose.push(a.addDisposableListener(this._listenOnDomNode,a.eventType.MOUSE_WHEEL,e,{passive:!1}))}}_handleMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;const t=S.INSTANCE;t.acceptStandardWheelEvent(e);let i=!1;if(e.deltaY||e.deltaX){let s=e.deltaY*this._options.mouseWheelScrollSensitivity,r=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&r+s===0?r=s=0:Math.abs(s)>=Math.abs(r)?r=0:s=0),this._options.flipAxes&&([s,r]=[r,s]);const o=!v.isMac&&e.browserEvent&&e.browserEvent.shiftKey;!this._options.scrollYToX&&!o||r||(r=s,s=0),e.browserEvent&&e.browserEvent.altKey&&(r*=this._options.fastScrollSensitivity,s*=this._options.fastScrollSensitivity);const n=this._scrollable.getFutureScrollPosition();let a={};if(s){const e=50*s,t=n.scrollTop-(e<0?Math.floor(e):Math.ceil(e));this._verticalScrollbar.writeScrollPosition(a,t)}if(r){const e=50*r,t=n.scrollLeft-(e<0?Math.floor(e):Math.ceil(e));this._horizontalScrollbar.writeScrollPosition(a,t)}a=this._scrollable.validateScrollPosition(a),(n.scrollLeft!==a.scrollLeft||n.scrollTop!==a.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(a):this._scrollable.setScrollPositionNow(a),i=!0)}let s=i;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_handleScroll(e){this._shouldRender=this._horizontalScrollbar.handleScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.handleScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error("Please use `lazyRender` together with `renderNow`!");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){const e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,i=e.scrollLeft>0,s=i?" xterm-shadow-left":"",r=t?" xterm-shadow-top":"",o=i||t?" xterm-shadow-top-left-corner":"";this._leftShadowDomNode.setClassName(`xterm-shadow${s}`),this._topShadowDomNode.setClassName(`xterm-shadow${r}`),this._topLeftShadowDomNode.setClassName(`xterm-shadow${o}${r}${s}`)}}_handleDragStart(){this._isDragging=!0,this._reveal()}_handleDragEnd(){this._isDragging=!1,this._hide()}_handleMouseLeave(e){this._mouseIsOver=!1,this._hide()}_handleMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){this._mouseIsOver||this._isDragging||(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){this._mouseIsOver||this._isDragging||this._hideTimeout.cancelAndSet(()=>this._hide(),500)}}t.SmoothScrollableElement=b},9594(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._arrowPointerDown(e))),this._register(c.addStandardDisposableListener(this.domNode,c.eventType.POINTER_DOWN,e=>this._arrowPointerDown(e))),this._pointerdownRepeatTimer=this._register(new c.WindowIntervalTimer),this._pointerdownScheduleRepeatTimer=this._register(new l.TimeoutTimer)}_arrowPointerDown(e){e.target&&e.target instanceof Element&&(this._handleActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet(()=>{this._pointerdownRepeatTimer.cancelAndSet(()=>this._handleActivate(),1e3/24,c.getWindow(e))},200),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{},()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()}),e.preventDefault())}}t.ScrollbarArrow=d},1270(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ScrollbarState=void 0;class i{constructor(e,t,i,s,r,o){this._scrollbarSize=Math.round(t),this._oppositeScrollbarSize=Math.round(i),this._arrowSize=Math.round(e),this._visibleSize=s,this._scrollSize=r,this._scrollPosition=o,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new i(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(e){const t=Math.round(e);return this._visibleSize!==t&&(this._visibleSize=t,this._refreshComputedValues(),!0)}setScrollSize(e){const t=Math.round(e);return this._scrollSize!==t&&(this._scrollSize=t,this._refreshComputedValues(),!0)}setScrollPosition(e){const t=Math.round(e);return this._scrollPosition!==t&&(this._scrollPosition=t,this._refreshComputedValues(),!0)}setScrollbarSize(e){this._scrollbarSize=Math.round(e)}setArrowSize(e){const t=Math.round(e);this._arrowSize!==t&&(this._arrowSize=t,this._refreshComputedValues())}setOppositeScrollbarSize(e){this._oppositeScrollbarSize=Math.round(e)}static _computeValues(e,t,i,s,r){const o=Math.max(0,i-e),n=Math.max(0,o-2*t),a=s>0&&s>i;if(!a)return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(n),computedSliderRatio:0,computedSliderPosition:0};const h=Math.round(Math.max(20,Math.floor(i*n/s))),l=(n-h)/(s-i),c=r*l;return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(h),computedSliderRatio:l,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){const e=i._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=e.computedAvailableSize,this._computedIsNeeded=e.computedIsNeeded,this._computedSliderSize=e.computedSliderSize,this._computedSliderRatio=e.computedSliderRatio,this._computedSliderPosition=e.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize-this._computedSliderSize/2;return Math.round(t/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize;let i=this._scrollPosition;return t{this._domNode?.setClassName(this._visibleClassName)},0))}_hide(e){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(e?" xterm-fade":"")))}}t.ScrollbarVisibilityController=o},2650(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{s||(s=!0,this._remove(i))}}_remove(e){if(e.prev!==_.Undefined&&e.next!==_.Undefined){const t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===_.Undefined&&e.next===_.Undefined?(this._first=_.Undefined,this._last=_.Undefined):e.next===_.Undefined?(this._last=this._last.prev,this._last.next=_.Undefined):e.prev===_.Undefined&&(this._first=this._first.next,this._first.prev=_.Undefined)}*[Symbol.iterator](){let e=this._first;for(;e!==_.Undefined;)yield e.element,e=e.next}}var f;!function(e){e.TAP="-xterm-gesturetap",e.CHANGE="-xterm-gesturechange",e.START="-xterm-gesturestart",e.END="-xterm-gesturesend",e.CONTEXT_MENU="-xterm-gesturecontextmenu"}(f||(t.EventType=f={}));class p extends l.Disposable{constructor(){super(),this._dispatched=!1,this._targets=new u,this._ignoreTargets=new u,this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;const e=c;this._register(h.addDisposableListener(e.document,"touchstart",e=>this._handleTouchStart(e),{passive:!1})),this._register(h.addDisposableListener(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(h.addDisposableListener(e.document,"touchmove",e=>this._handleTouchMove(e),{passive:!1}))}static addTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._targets.push(e);return(0,l.toDisposable)(t)}static ignoreTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._ignoreTargets.push(e);return(0,l.toDisposable)(t)}static isTouchDevice(){return"ontouchstart"in c||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){const t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let i=0,s=e.targetTouches.length;i=p._holdDelay&&Math.abs(n.initialPageX-d(n.rollingPageX))<30&&Math.abs(n.initialPageY-d(n.rollingPageY))<30){const e=this._newGestureEvent(f.CONTEXT_MENU,n.initialTarget);e.pageX=d(n.rollingPageX),e.pageY=d(n.rollingPageY),this._dispatchEvent(e)}else if(1===s){const t=d(n.rollingPageX),s=d(n.rollingPageY),r=d(n.rollingTimestamps)-n.rollingTimestamps[0],o=t-n.rollingPageX[0],a=s-n.rollingPageY[0],h=[...this._targets].filter(e=>n.initialTarget instanceof Node&&e.contains(n.initialTarget));this._inertia(e,h,i,Math.abs(o)/r,o>0?1:-1,t,Math.abs(a)/r,a>0?1:-1,s)}this._dispatchEvent(this._newGestureEvent(f.END,n.initialTarget)),delete this._activeTouches[o.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){const i=document.createEvent("CustomEvent");return i.initEvent(e,!1,!0),i.initialTarget=t,i.tapCount=0,i}_dispatchEvent(e){if(e.type===f.TAP){const t=(new Date).getTime();let i;i=t-this._lastSetTapCountTime>p._clearTapCountTime?1:2,this._lastSetTapCountTime=t,e.tapCount=i}else e.type!==f.CHANGE&&e.type!==f.CONTEXT_MENU||(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(const t of this._ignoreTargets)if(t.contains(e.initialTarget))return;const t=[];for(const i of this._targets)if(i.contains(e.initialTarget)){let s=0,r=e.initialTarget;for(;r&&r!==i;)s++,r=r.parentElement;t.push([s,i])}t.sort((e,t)=>e[0]-t[0]);for(const[,i]of t)i.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,i,s,r,o,n,a,l){this._handle=h.scheduleAtNextAnimationFrame(e,()=>{const h=Date.now(),c=h-i;let d=0,_=0,u=!0;s+=p._scrollFriction*c,n+=p._scrollFriction*c,s>0&&(u=!1,d=r*s*c),n>0&&(u=!1,_=a*n*c);const v=this._newGestureEvent(f.CHANGE);v.translationX=d,v.translationY=_,t.forEach(e=>e.dispatchEvent(v)),u||this._inertia(e,t,h,s,r,o+d,n,a,l+_)})}_handleTouchMove(e){const t=Date.now();for(let i=0,s=e.changedTouches.length;i3&&(r.rollingPageX.shift(),r.rollingPageY.shift(),r.rollingTimestamps.shift()),r.rollingPageX.push(s.pageX),r.rollingPageY.push(s.pageY),r.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}}t.Gesture=p,p._scrollFriction=-.005,p._holdDelay=700,p._clearTapCountTime=400,n([function(e,t,i){let s=null,r=null;if("function"==typeof i.value?(s="value",r=i.value,0!==r.length&&console.warn("Memoize should only be used in functions with zero parameters")):"function"==typeof i.get&&(s="get",r=i.get),!r||!s)throw new Error("not supported");const o=`$memoize$${t}`;i[s]=function(...e){return this.hasOwnProperty(o)||Object.defineProperty(this,o,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,e)}),this[o]}}],p,"isTouchDevice",null)},8997(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.VerticalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition(),n=t.verticalHasArrows;super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(n?t.verticalScrollbarSize:0,2===t.vertical?0:t.verticalScrollbarSize,0,s.height,s.scrollHeight,o.scrollTop),visibility:t.vertical,extraScrollbarClassName:"xterm-vertical",scrollable:e,scrollByPage:t.scrollByPage}),this._arrowScrollDelta=0,this._setArrows(n,t.verticalScrollbarSize),this._createSlider(0,Math.floor((t.verticalScrollbarSize-t.verticalSliderSize)/2),t.verticalSliderSize,void 0)}_updateSlider(e,t){this.slider.setHeight(e),this.slider.setTop(t)}_renderDomNode(e,t){this.domNode.setWidth(t),this.domNode.setHeight(e),this.domNode.setRight(0),this.domNode.setTop(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollHeight)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollTop)||this._shouldRender,this._shouldRender=this._handleElementSize(e.height)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return t}_sliderPointerPosition(e){return e.pageY}_sliderOrthogonalPointerPosition(e){return e.pageX}_updateScrollbarSize(e){this.slider.setWidth(e)}writeScrollPosition(e,t){e.scrollTop=t}_arrowScroll(e){const t=this._scrollable.getCurrentScrollPosition();this._scrollable.setScrollPositionNow({scrollTop:t.scrollTop+e})}_setArrows(e,t){if(this._arrowScrollDelta=t,!this._arrowUp||!this._arrowDown){const e=0;this._arrowUp=this._createArrow({className:"xterm-scra xterm-arrow-up",top:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(-this._arrowScrollDelta)}),this._arrowDown=this._createArrow({className:"xterm-scra xterm-arrow-down",bottom:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(this._arrowScrollDelta)})}if(this._updateArrowSize(this._arrowUp,t),this._updateArrowSize(this._arrowDown,t),!this._arrowUp||!this._arrowDown)return;const i=e?"":"none";this._arrowUp.bgDomNode.style.display=i,this._arrowUp.domNode.style.display=i,this._arrowDown.bgDomNode.style.display=i,this._arrowDown.domNode.style.display=i}_updateArrowSize(e,t){e&&(e.bgDomNode.style.width=`${t}px`,e.bgDomNode.style.height=`${t}px`,e.domNode.style.width=`${t}px`,e.domNode.style.height=`${t}px`)}updateOptions(e){const t=e.verticalHasArrows?e.verticalScrollbarSize:0;this._scrollbarState.setArrowSize(t),this._setArrows(e.verticalHasArrows,e.verticalScrollbarSize),this.updateScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}}t.VerticalScrollbar=o},7741(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nt(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseover(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_OVER,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseleave(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_LEAVE,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}}t.Widget=c},5959(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SelectionModel=void 0,t.SelectionModel=class{constructor(e){this._bufferService=e,this.isSelectAllActive=!1,this.selectionStartLength=0}clearSelection(){this.selectionStart=void 0,this.selectionEnd=void 0,this.isSelectAllActive=!1,this.selectionStartLength=0}get finalSelectionStart(){return this.isSelectAllActive?[0,0]:this.selectionEnd&&this.selectionStart&&this.areSelectionValuesReversed()?this.selectionEnd:this.selectionStart}get finalSelectionEnd(){if(this.isSelectAllActive)return[this._bufferService.cols,this._bufferService.buffer.ybase+this._bufferService.rows-1];if(this.selectionStart){if(!this.selectionEnd||this.areSelectionValuesReversed()){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?e%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)-1]:[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[e,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[Math.max(e,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){const e=this.selectionStart,t=this.selectionEnd;return!(!e||!t)&&(e[1]>t[1]||e[1]===t[1]&&e[0]>t[0])}handleTrim(e){return this.selectionStart&&(this.selectionStart[1]-=e),this.selectionEnd&&(this.selectionEnd[1]-=e),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):!!(this.selectionStart&&this.selectionStart[1]<0)&&(this.selectionStart=[0,0],!0)}}},4792(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharSizeService=void 0;const o=i(6501),n=i(4812),a=i(8636);let h=class extends n.Disposable{get hasValidSize(){return this.width>0&&this.height>0}constructor(e,t,i){super(),this._optionsService=i,this.width=0,this.height=0,this._onCharSizeChange=this._register(new a.Emitter),this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new d(this._optionsService))}catch{this._measureStrategy=this._register(new c(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}measure(){const e=this._measureStrategy.measure();e.width===this.width&&e.height===this.height||(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};t.CharSizeService=h,t.CharSizeService=h=s([r(2,o.IOptionsService)],h);class l extends n.Disposable{constructor(){super(...arguments),this._result={width:0,height:0}}_validateAndSet(e,t){void 0!==e&&e>0&&void 0!==t&&t>0&&(this._result.width=e,this._result.height=t)}}class c extends l{constructor(e,t,i){super(),this._document=e,this._parentElement=t,this._optionsService=i,this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}}class d extends l{constructor(e){super(),this._optionsService=e,this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");const t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;const e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}}},945(e,t,i){var s,r=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},o=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharacterJoinerService=t.JoinedCellData=void 0;const n=i(5451),a=i(8938),h=i(3055),l=i(6501);class c extends n.AttributeData{constructor(e,t,i){super(),this.content=0,this.combinedData="",this.fg=e.fg,this.bg=e.bg,this.combinedData=t,this._width=i}isCombined(){return 2097152}getWidth(){return this._width}getChars(){return this.combinedData}getCode(){return 2097151}setFromCharData(e){throw new Error("not implemented")}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.JoinedCellData=c;let d=s=class{constructor(e){this._bufferService=e,this._characterJoiners=[],this._nextCharacterJoinerId=0,this._workCell=new h.CellData}register(e){const t={id:this._nextCharacterJoinerId++,handler:e};return this._characterJoiners.push(t),t.id}deregister(e){for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;tthis._screenDprMonitor.setWindow(e))),this._register(s.EventUtils.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register((0,r.addDisposableListener)(this._textarea,"focus",()=>this._isFocused=!0)),this._register((0,r.addDisposableListener)(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return void 0===this._cachedIsFocused&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}}t.CoreBrowserService=n;class a extends o.Disposable{constructor(e){super(),this._parentWindow=e,this._windowResizeListener=this._register(new o.MutableDisposable),this._onDprChange=this._register(new s.Emitter),this.onDprChange=this._onDprChange.event,this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register((0,o.toDisposable)(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=(0,r.addDisposableListener)(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){this._resolutionMediaMatchList&&this._outerListener&&(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}}},2136(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.KeyboardService=void 0;const o=i(706),n=i(7241),a=i(9249),h=i(701),l=i(6501);let c=class{constructor(e,t){this._coreService=e,this._optionsService=t}_getWin32InputMode(){return this._win32InputMode??=new a.Win32InputMode,this._win32InputMode}_getKittyKeyboard(){return this._kittyKeyboard??=new n.KittyKeyboard,this._kittyKeyboard}evaluateKeyDown(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!0);const t=this._coreService.kittyKeyboard.flags;return this.useKitty?this._getKittyKeyboard().evaluate(e,t,e.repeat?2:1,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):(0,o.evaluateKeyboardEvent)(e,this._coreService.decPrivateModes.applicationCursorKeys,h.isMac,this._optionsService.rawOptions.macOptionIsMeta)}evaluateKeyUp(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!1);const t=this._coreService.kittyKeyboard.flags;return this.useKitty&&2&t?this._getKittyKeyboard().evaluate(e,t,3,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):void 0}get useKitty(){const e=this._coreService.kittyKeyboard.flags;return!(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard||!n.KittyKeyboard.shouldUseProtocol(e))}get useWin32InputMode(){return!(!this._optionsService.rawOptions.vtExtensions?.win32InputMode||!this._coreService.decPrivateModes.win32InputMode)}};t.KeyboardService=c,t.KeyboardService=c=s([r(0,l.ICoreService),r(1,l.IOptionsService)],c)},9820(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.LinkProviderService=void 0;const s=i(4812);class r extends s.Disposable{constructor(){super(),this.linkProviders=[],this._register((0,s.toDisposable)(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{const t=this.linkProviders.indexOf(e);-1!==t&&this.linkProviders.splice(t,1)}}}}t.LinkProviderService=r},8294(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.MouseCoordsService=void 0;const o=i(4159),n=i(5251),a=i(7098);let h=class{constructor(e,t){this._charSizeService=e,this._renderService=t}getCoords(e,t,i,s,r){return(0,n.getCoords)((0,o.getWindow)(t),e,t,i,s,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,r)}getMouseReportCoords(e,t){const i=(0,n.getCoordsRelativeToElement)((0,o.getWindow)(t),e,t);if(this._charSizeService.hasValidSize)return i[0]=Math.min(Math.max(i[0],0),this._renderService.dimensions.css.canvas.width-1),i[1]=Math.min(Math.max(i[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(i[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(i[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(i[0]),y:Math.floor(i[1])}}};t.MouseCoordsService=h,t.MouseCoordsService=h=s([r(0,a.ICharSizeService),r(1,a.IRenderService)],h)},9784(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.AltMouseCursorController=t.MouseService=void 0;const o=i(4159),n=i(6501),a=i(4812),h=i(7098),l=i(2650);let c=class{constructor(e,t,i,s,r,o,n,a,h){this._renderService=e,this._mouseCoordsService=t,this._mouseStateService=i,this._coreService=s,this._bufferService=r,this._optionsService=o,this._selectionService=n,this._logService=a,this._coreBrowserService=h,this._lastEvent=null,this._wheelPartialScroll=0,this._touchScrollAccumulator=0}bindMouse(e,t,i){const{element:s,document:r}=e,n={mouseup:null,wheel:null,mousedrag:null,mousemove:null},h={target:e,focus:i,requestedEvents:n},c={mouseup:e=>this._handleMouseUp(h,e),wheel:e=>this._handleWheel(h,e),mousedrag:e=>this._handleMouseDrag(h,e),mousemove:e=>this._handleMouseMove(h,e)};this._altMouseCursor=new d(s,r,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),t(this._altMouseCursor),t(this._mouseStateService.onProtocolChange(e=>{this._handleProtocolChange(h,c,e)})),t(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(s),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,t((0,a.toDisposable)(()=>{n.mouseup&&r.removeEventListener("mouseup",n.mouseup),n.mousedrag&&r.removeEventListener("mousemove",n.mousedrag)})),t((0,o.addDisposableListener)(s,"mousedown",e=>this._handleMouseDown(h,e))),t((0,o.addDisposableListener)(s,"wheel",e=>this._handlePassiveWheel(h,e),{passive:!1})),t(l.Gesture.addTarget(e.screenElement)),t((0,o.addDisposableListener)(e.screenElement,l.EventType.START,()=>this._handleTouchStart())),t((0,o.addDisposableListener)(e.screenElement,l.EventType.CHANGE,e=>this._handleTouchChange(h,e)))}_sendEvent(e,t){const i=this._mouseCoordsService.getMouseReportCoords(t,e.target.screenElement);if(!i)return!1;let s,r;switch(t.overrideType||t.type){case"mousemove":r=32,void 0===t.buttons?(s=3,void 0!==t.button&&(s=t.button<3?t.button:3)):s=1&t.buttons?0:4&t.buttons?1:2&t.buttons?2:3;break;case"mouseup":r=0,s=t.button<3?t.button:3;break;case"mousedown":r=1,s=t.button<3?t.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;const e=t.deltaY;if(0===e)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return!1;r=e<0?0:1,s=4;break;default:return!1}if(void 0===r||void 0===s||s>4)return!1;if(4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!t.altKey)return!1;const o=4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:i.col,row:i.row,x:i.x,y:i.y,button:s,action:r,ctrl:t.ctrlKey,alt:!o&&t.altKey,shift:t.shiftKey})}_handleMouseUp(e,t){this._sendEvent(e,t),t.buttons||(e.requestedEvents.mouseup&&e.target.document.removeEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.removeEventListener("mousemove",e.requestedEvents.mousedrag))}_handleWheel(e,t){return this._sendEvent(e,t),t.preventDefault(),t.stopPropagation(),!1}_handleMouseDrag(e,t){t.buttons&&this._sendEvent(e,t)}_handleMouseMove(e,t){t.buttons||this._sendEvent(e,t)}_handleMouseDown(e,t){t.preventDefault(),e.focus(),this._mouseStateService.areMouseEventsActive&&!this._selectionService.shouldForceSelection(t)&&(this._sendEvent(e,t),e.requestedEvents.mouseup&&e.target.document.addEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.addEventListener("mousemove",e.requestedEvents.mousedrag))}_handlePassiveWheel(e,t){if(!e.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;if(!this._bufferService.buffer.hasScrollback){if(0===t.deltaY)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return t.preventDefault(),t.stopPropagation(),!1;const e=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(e,!0),t.preventDefault(),t.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(e,t){t.preventDefault(),t.stopPropagation(),e.requestedEvents.wheel?this._handleTouchScrollAsWheel(e,t):this._bufferService.buffer.hasScrollback?e.target.handleTouchScroll?.(t.translationY):this._handleTouchScrollAsKeys(t)}_handleTouchScrollAsKeys(e){const t=this._renderService?.dimensions.css.cell.height;if(!t)return;this._touchScrollAccumulator-=e.translationY;const i=Math.trunc(this._touchScrollAccumulator/t);if(0===i)return;this._touchScrollAccumulator-=i*t;const s=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(i<0?"A":"B");for(let e=0;e0?1:-1),this._wheelPartialScroll%=1):e.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(r*=this._bufferService.rows),r}_triggerMouseEvent(e){if(e.col<0||e.col>=this._bufferService.cols||e.row<0||e.row>=this._bufferService.rows)return!1;if(4===e.button&&32===e.action)return!1;if(3===e.button&&32!==e.action)return!1;if(4!==e.button&&(2===e.action||3===e.action))return!1;if(e.col++,e.row++,32===e.action&&this._lastEvent&&this._equalEvents(this._lastEvent,e,this._mouseStateService.isPixelEncoding))return!1;if(!this._mouseStateService.restrictMouseEvent(e))return!1;const t=this._mouseStateService.encodeMouseEvent(e);return t&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(t):this._coreService.triggerDataEvent(t,!0)),this._lastEvent=e,!0}_explainEvents(e){return{down:!!(1&e),up:!!(2&e),drag:!!(4&e),move:!!(8&e),wheel:!!(16&e)}}_equalEvents(e,t,i){if(i){if(e.x!==t.x)return!1;if(e.y!==t.y)return!1}else{if(e.col!==t.col)return!1;if(e.row!==t.row)return!1}return e.button===t.button&&e.action===t.action&&e.ctrl===t.ctrl&&e.alt===t.alt&&e.shift===t.shift}};t.MouseService=c,t.MouseService=c=s([r(0,h.IRenderService),r(1,h.IMouseCoordsService),r(2,n.IMouseStateService),r(3,n.ICoreService),r(4,n.IBufferService),r(5,n.IOptionsService),r(6,h.ISelectionService),r(7,n.ILogService),r(8,h.ICoreBrowserService)],c);class d{constructor(e,t,i){this._element=e,this._document=t,this._isActive=i,this._listeners=new a.MutableDisposable}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;const e=new a.DisposableStore,t=e=>this.syncFromModifier(e);e.add((0,o.addDisposableListener)(this._document,"keydown",t)),e.add((0,o.addDisposableListener)(this._document,"keyup",t)),e.add((0,o.addDisposableListener)(this._element,"mousemove",t));const i=this._element.ownerDocument?.defaultView;i&&e.add((0,o.addDisposableListener)(i,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=e}resetClass(){this._updateClass(!1)}syncFromModifier(e){this._isActive()&&this._updateClass(e.getModifierState("Alt"))}_updateClass(e){e?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}}t.AltMouseCursorController=d},5783(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.RenderService=void 0;const o=i(4852),n=i(7098),a=i(4812),h=i(6168),l=i(6501),c=i(8636);let d=class extends a.Disposable{get dimensions(){return this._renderer.value.dimensions}constructor(e,t,i,s,r,n,l,d,u,f){super(),this._rowCount=e,this._optionsService=i,this._logService=s,this._charSizeService=r,this._coreService=n,this._coreBrowserService=u,this._renderer=this._register(new a.MutableDisposable),this._observerDisposable=this._register(new a.MutableDisposable),this._isPaused=!1,this._needsFullRefresh=!1,this._isNextRenderRedrawOnly=!0,this._needsSelectionRefresh=!1,this._canvasWidth=0,this._canvasHeight=0,this._selectionState={start:void 0,end:void 0,columnSelectMode:!1},this._onDimensionsChange=this._register(new c.Emitter),this.onDimensionsChange=this._onDimensionsChange.event,this._onRenderedViewportChange=this._register(new c.Emitter),this.onRenderedViewportChange=this._onRenderedViewportChange.event,this._onRender=this._register(new c.Emitter),this.onRender=this._onRender.event,this._onRefreshRequest=this._register(new c.Emitter),this.onRefreshRequest=this._onRefreshRequest.event,this._pausedResizeTask=this._register(new h.DebouncedIdleTask(this._logService)),this._renderDebouncer=new o.RenderDebouncer((e,t)=>this._renderRows(e,t),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new _(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register((0,a.toDisposable)(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(d.onResize(()=>this._fullRefresh())),this._register(d.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(d.cols,d.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(d.buffer.y,d.buffer.y,void 0,!0))),this._register(f.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(e=>this._registerIntersectionObserver(e,t)))}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){const i=new e.IntersectionObserver(e=>this._handleIntersectionChange(e[e.length-1]),{threshold:0});this._observerDisposable.value=(0,a.toDisposable)(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=i,i.observe(t)}}_handleIntersectionChange(e){this._isPaused=void 0===e.isIntersecting?0===e.intersectionRatio:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),this._isPaused||this._charSizeService.hasValidSize||this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,i=!1,s=!1){if(this._isPaused)return void(this._needsFullRefresh=!0);if(this._coreService.decPrivateModes.synchronizedOutput)return void this._syncOutputHandler.bufferRows(e,t);const r=this._syncOutputHandler.flush();r&&(e=Math.min(e,r.start),t=Math.max(t,r.end)),s||(this._isNextRenderRedrawOnly=!1),i?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){this._renderer.value&&(this._coreService.decPrivateModes.synchronizedOutput?this._syncOutputHandler.bufferRows(e,t):(e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0))}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(e=>this.refreshRows(e.start,e.end,e.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,i){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=i,this._renderer.value?.handleSelectionChanged(e,t,i)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};t.RenderService=d,t.RenderService=d=s([r(2,l.IOptionsService),r(3,l.ILogService),r(4,n.ICharSizeService),r(5,l.ICoreService),r(6,l.IDecorationService),r(7,l.IBufferService),r(8,n.ICoreBrowserService),r(9,n.IThemeService)],d);class _{constructor(e,t,i){this._coreBrowserService=e,this._coreService=t,this._onTimeout=i,this._start=0,this._end=0,this._isBuffering=!1}bufferRows(e,t){this._isBuffering?(this._start=Math.min(this._start,e),this._end=Math.max(this._end,t)):(this._start=e,this._end=t,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;const e={start:this._start,end:this._end};return this._isBuffering=!1,e}dispose(){void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}}},2079(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleMouseMove(e),this._mouseUpListener=e=>this._handleMouseUp(e),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(e=>this._handleTrim(e)),this._register(this._bufferService.buffers.onBufferActivate(e=>this._handleBufferActivate(e))),this.enable(),this._model=new d.SelectionModel(this._bufferService),this._activeSelectionMode=0,this._register((0,u.toDisposable)(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(e=>{e.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!(!e||!t||e[0]===t[0]&&e[1]===t[1])}get selectionText(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";const i=this._bufferService.buffer,s=[];if(3===this._activeSelectionMode){if(e[0]===t[0])return"";const r=e[0]e.replace(b," ")).join(f.isWindows?"\r\n":"\n")}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._refresh())),f.isLinux&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:3===this._activeSelectionMode})}_isClickInSelection(e){const t=this._getMouseBufferCoords(e),i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!!(i&&s&&t)&&this._areCoordsInSelection(t,i,s)}isCellInSelection(e,t){const i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!(!i||!s)&&this._areCoordsInSelection([e,t],i,s)}_areCoordsInSelection(e,t,i){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){const i=this._linkifier.currentLink?.link?.range;if(i)return this._model.selectionStart=[i.start.x-1,i.start.y-1],this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols),this._model.selectionEnd=void 0,!0;const s=this._getMouseBufferCoords(e);return!!s&&(this._selectWordAt(s,t),this._model.selectionEnd=void 0,!0)}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){const t=this._mouseCoordsService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=(0,l.getCoordsRelativeToElement)(this._coreBrowserService.window,e,this._screenElement)[1];const i=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=i?0:(t>i&&(t-=i),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(14*t))}shouldForceSelection(e){return this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive?!e.altKey:f.isMac?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,!(2===e.button&&this.hasSelection||0!==e.button||this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&e.altKey)){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):1===e.detail?this._handleSingleClick(e):2===e.detail?this._handleDoubleClick(e):3===e.detail&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener("mouseup",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval(()=>this._dragScroll(),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener("mouseup",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){const t=this.hasSelection;if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0,t&&this._fireOnSelectionChange(this._model.finalSelectionStart,this._model.finalSelectionEnd,!1);const i=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);i&&i.length!==this._model.selectionStart[0]&&0===i.hasWidth(this._model.selectionStart[0])&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){const t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return(!this._optionsService.rawOptions.mouseEventsRequireAlt||!this._mouseStateService.areMouseEventsActive)&&e.altKey&&!(f.isMac&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;const t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd)return void this.refresh(!0);2===this._activeSelectionMode?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));const i=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows-1,e.lines.length-1)):(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){const t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){const t=this._mouseCoordsService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(t&&void 0!==t[0]&&void 0!==t[1]){const e=(0,c.moveToCellSequence)(t[0]-1,t[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(e,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,i=!(!e||!t||e[0]===t[0]&&e[1]===t[1]);i?e&&t&&(this._oldSelectionStart&&this._oldSelectionEnd&&e[0]===this._oldSelectionStart[0]&&e[1]===this._oldSelectionStart[1]&&t[0]===this._oldSelectionEnd[0]&&t[1]===this._oldSelectionEnd[1]||this._fireOnSelectionChange(e,t,i)):this._oldHasSelection&&this._fireOnSelectionChange(e,t,i)}_fireOnSelectionChange(e,t,i){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=i,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.value=e.activeBuffer.lines.onTrim(e=>this._handleTrim(e))}_convertViewportColToCharacterIndex(e,t){let i=t;for(let s=0;t>=s;s++){const r=e.loadCell(s,this._workCell).getChars().length;0===this._workCell.getWidth()?i--:r>1&&t!==s&&(i+=r-1)}return i}setSelection(e,t,i){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=i,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,i=!0,s=!0){if(e[0]>=this._bufferService.cols)return;const r=this._bufferService.buffer,o=r.lines.get(e[1]);if(!o)return;const n=r.translateBufferLineToString(e[1],!1);let a=this._convertViewportColToCharacterIndex(o,e[0]),h=a;const l=e[0]-a;let c=0,d=0,_=0,u=0;if(" "===n.charAt(a)){for(;a>0&&" "===n.charAt(a-1);)a--;for(;h1&&(u+=s-1,h+=s-1);t>0&&a>0&&!this._isCharWordSeparator(o.loadCell(t-1,this._workCell));){o.loadCell(t-1,this._workCell);const e=this._workCell.getChars().length;0===this._workCell.getWidth()?(c++,t--):e>1&&(_+=e-1,a-=e-1),a--,t--}for(;i1&&(u+=e-1,h+=e-1),h++,i++}}h++;let f=a+l-c+_,p=Math.min(this._bufferService.cols,h-a+c+d-_-u);if(t||""!==n.slice(a,h).trim()){if(i&&0===f&&32!==o.getCodePoint(0)){const t=r.lines.get(e[1]-1);if(t&&o.isWrapped&&32!==t.getCodePoint(this._bufferService.cols-1)){const t=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(t){const e=this._bufferService.cols-t.start;f-=e,p+=e}}}if(s&&f+p===this._bufferService.cols&&32!==o.getCodePoint(this._bufferService.cols-1)){const t=r.lines.get(e[1]+1);if(t?.isWrapped&&32!==t.getCodePoint(0)){const t=this._getWordAt([0,e[1]+1],!1,!1,!0);t&&(p+=t.length)}}return{start:f,length:p}}}_selectWordAt(e,t){const i=this._getWordAt(e,t);if(i){for(;i.start<0;)i.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[i.start,e[1]],this._model.selectionStartLength=i.length}}_selectToWordAt(e){const t=this._getWordAt(e,!0);if(t){let i=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,i--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,i++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,i]}}_isCharWordSeparator(e){return 0!==e.getWidth()&&this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){const t=this._bufferService.buffer.getWrappedRangeForLine(e),i={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols)}};t.SelectionService=y,t.SelectionService=y=n([h(3,g.IBufferService),h(4,g.ICoreService),h(5,_.IMouseCoordsService),h(6,g.IOptionsService),h(7,g.IMouseStateService),h(8,_.IRenderService),h(9,_.ICoreBrowserService)],y)},7098(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IKeyboardService=t.ILinkProviderService=t.IThemeService=t.ICharacterJoinerService=t.ISelectionService=t.IRenderService=t.IMouseService=t.IMouseCoordsService=t.ICoreBrowserService=t.ICharSizeService=void 0;const s=i(6201);t.ICharSizeService=(0,s.createDecorator)("CharSizeService"),t.ICoreBrowserService=(0,s.createDecorator)("CoreBrowserService"),t.IMouseCoordsService=(0,s.createDecorator)("MouseCoordsService"),t.IMouseService=(0,s.createDecorator)("MouseService"),t.IRenderService=(0,s.createDecorator)("RenderService"),t.ISelectionService=(0,s.createDecorator)("SelectionService"),t.ICharacterJoinerService=(0,s.createDecorator)("CharacterJoinerService"),t.IThemeService=(0,s.createDecorator)("ThemeService"),t.ILinkProviderService=(0,s.createDecorator)("LinkProviderService"),t.IKeyboardService=(0,s.createDecorator)("KeyboardService")},9078(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeService=void 0;const o=i(7174),n=i(9302),a=i(4103),h=i(4812),l=i(6501),c=i(8636),d=a.css.toColor("#ffffff"),_=a.css.toColor("#000000"),u=a.css.toColor("#ffffff"),f=_,p={css:"rgba(255, 255, 255, 0.3)",rgba:4294967117},v=d;let g=class extends h.Disposable{get colors(){return this._colors}constructor(e){super(),this._optionsService=e,this._contrastCache=new o.ColorContrastCache,this._halfContrastCache=new o.ColorContrastCache,this._onChangeColors=this._register(new c.Emitter),this.onChangeColors=this._onChangeColors.event,this._colors={foreground:d,background:_,cursor:u,cursorAccent:f,selectionForeground:void 0,selectionBackgroundTransparent:p,selectionBackgroundOpaque:a.color.blend(_,p),selectionInactiveBackgroundTransparent:p,selectionInactiveBackgroundOpaque:a.color.blend(_,p),scrollbarSliderBackground:a.color.opacity(d,.2),scrollbarSliderHoverBackground:a.color.opacity(d,.4),scrollbarSliderActiveBackground:a.color.opacity(d,.5),overviewRulerBorder:d,ansi:n.DEFAULT_ANSI_COLORS.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this._register(this._optionsService.onSpecificOptionChange("minimumContrastRatio",()=>this._contrastCache.clear())),this._register(this._optionsService.onSpecificOptionChange("theme",()=>this._setTheme(this._optionsService.rawOptions.theme)))}_setTheme(e={}){const t=this._colors;if(t.foreground=m(e.foreground,d),t.background=m(e.background,_),t.cursor=a.color.blend(t.background,m(e.cursor,u)),t.cursorAccent=a.color.blend(t.background,m(e.cursorAccent,f)),t.selectionBackgroundTransparent=m(e.selectionBackground,p),t.selectionBackgroundOpaque=a.color.blend(t.background,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundTransparent=m(e.selectionInactiveBackground,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundOpaque=a.color.blend(t.background,t.selectionInactiveBackgroundTransparent),t.selectionForeground=e.selectionForeground?m(e.selectionForeground,a.NULL_COLOR):void 0,t.selectionForeground===a.NULL_COLOR&&(t.selectionForeground=void 0),a.color.isOpaque(t.selectionBackgroundTransparent)){const e=.3;t.selectionBackgroundTransparent=a.color.opacity(t.selectionBackgroundTransparent,e)}if(a.color.isOpaque(t.selectionInactiveBackgroundTransparent)){const e=.3;t.selectionInactiveBackgroundTransparent=a.color.opacity(t.selectionInactiveBackgroundTransparent,e)}if(t.scrollbarSliderBackground=m(e.scrollbarSliderBackground,a.color.opacity(t.foreground,.2)),t.scrollbarSliderHoverBackground=m(e.scrollbarSliderHoverBackground,a.color.opacity(t.foreground,.4)),t.scrollbarSliderActiveBackground=m(e.scrollbarSliderActiveBackground,a.color.opacity(t.foreground,.5)),t.overviewRulerBorder=m(e.overviewRulerBorder,v),t.ansi=n.DEFAULT_ANSI_COLORS.slice(),t.ansi[0]=m(e.black,n.DEFAULT_ANSI_COLORS[0]),t.ansi[1]=m(e.red,n.DEFAULT_ANSI_COLORS[1]),t.ansi[2]=m(e.green,n.DEFAULT_ANSI_COLORS[2]),t.ansi[3]=m(e.yellow,n.DEFAULT_ANSI_COLORS[3]),t.ansi[4]=m(e.blue,n.DEFAULT_ANSI_COLORS[4]),t.ansi[5]=m(e.magenta,n.DEFAULT_ANSI_COLORS[5]),t.ansi[6]=m(e.cyan,n.DEFAULT_ANSI_COLORS[6]),t.ansi[7]=m(e.white,n.DEFAULT_ANSI_COLORS[7]),t.ansi[8]=m(e.brightBlack,n.DEFAULT_ANSI_COLORS[8]),t.ansi[9]=m(e.brightRed,n.DEFAULT_ANSI_COLORS[9]),t.ansi[10]=m(e.brightGreen,n.DEFAULT_ANSI_COLORS[10]),t.ansi[11]=m(e.brightYellow,n.DEFAULT_ANSI_COLORS[11]),t.ansi[12]=m(e.brightBlue,n.DEFAULT_ANSI_COLORS[12]),t.ansi[13]=m(e.brightMagenta,n.DEFAULT_ANSI_COLORS[13]),t.ansi[14]=m(e.brightCyan,n.DEFAULT_ANSI_COLORS[14]),t.ansi[15]=m(e.brightWhite,n.DEFAULT_ANSI_COLORS[15]),e.extendedAnsi){const i=Math.min(t.ansi.length-16,e.extendedAnsi.length);for(let s=0;ssetTimeout(t,e))},t.disposableTimeout=function(e,t=0,i){const r=setTimeout(()=>{e(),i&&o.dispose()},t),o=(0,s.toDisposable)(()=>{clearTimeout(r)});return i?.add(o),o};const s=i(4812);t.TimeoutTimer=class{constructor(){this._token=-1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,e()},t)}setIfNotSet(e,t){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout(()=>{this._token=-1,e()},t))}},t.MicrotaskTimer=class{constructor(){this._isScheduled=!1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(e){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,e())}))}},t.IntervalTimer=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(e,t,i=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();const s=i.setInterval(()=>{e()},t);this._disposable={dispose:()=>{i.clearInterval(s),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}}},5639(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CircularList=void 0;const s=i(4812),r=i(8636);class o extends s.Disposable{constructor(e){super(),this._maxLength=e,this.onDeleteEmitter=this._register(new r.Emitter),this.onDelete=this.onDeleteEmitter.event,this.onInsertEmitter=this._register(new r.Emitter),this.onInsert=this.onInsertEmitter.event,this.onTrimEmitter=this._register(new r.Emitter),this.onTrim=this.onTrimEmitter.event,this._array=new Array(this._maxLength),this._startIndex=0,this._length=0}get maxLength(){return this._maxLength}set maxLength(e){if(this._maxLength===e)return;const t=new Array(e);for(let i=0;ithis._length)for(let t=this._length;t=e;t--)this._array[this._getCyclicIndex(t+i.length)]=this._array[this._getCyclicIndex(t)];for(let t=0;tthis._maxLength){const e=this._length+i.length-this._maxLength;this._startIndex+=e,this._length=this._maxLength,this.onTrimEmitter.fire(e)}else this._length+=i.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,i){if(!(t<=0)){if(e<0||e>=this._length)throw new Error("start argument out of range");if(e+i<0)throw new Error("Cannot shift elements in list beyond index 0");if(i>0){for(let s=t-1;s>=0;s--)this.set(e+s+i,this.get(e+s));const s=e+t+i-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;s>>0},e.toColor=function(t,i,s,r){return{css:e.toCss(t,i,s,r),rgba:e.toRgba(t,i,s,r)}}}(n||(t.channels=n={})),function(e){function t(e,t){return o=Math.round(255*t),[i,s,r]=c.toChannels(e.rgba),{css:n.toCss(i,s,r,o),rgba:n.toRgba(i,s,r,o)}}e.blend=function(e,t){if(o=(255&t.rgba)/255,1===o)return{css:t.css,rgba:t.rgba};const a=t.rgba>>24&255,h=t.rgba>>16&255,l=t.rgba>>8&255,c=e.rgba>>24&255,d=e.rgba>>16&255,_=e.rgba>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),{css:n.toCss(i,s,r),rgba:n.toRgba(i,s,r)}},e.isOpaque=function(e){return!(255&~e.rgba)},e.ensureContrastRatio=function(e,t,i){const s=c.ensureContrastRatio(e.rgba,t.rgba,i);if(s)return n.toColor(s>>24&255,s>>16&255,s>>8&255)},e.opaque=function(e){const t=(255|e.rgba)>>>0;return[i,s,r]=c.toChannels(t),{css:n.toCss(i,s,r),rgba:t}},e.opacity=t,e.multiplyOpacity=function(e,i){return o=255&e.rgba,t(e,o*i/255)},e.toColorRGB=function(e){return[e.rgba>>24&255,e.rgba>>16&255,e.rgba>>8&255]}}(a||(t.color=a={})),function(e){let t,a;try{const e=document.createElement("canvas");e.width=1,e.height=1;const i=e.getContext("2d",{willReadFrequently:!0});i&&(t=i,t.globalCompositeOperation="copy",a=t.createLinearGradient(0,0,1,1))}catch{}e.toColor=function(e){if(e.match(/#[\da-f]{3,8}/i))switch(e.length){case 4:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),n.toColor(i,s,r);case 5:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),o=parseInt(e.slice(4,5).repeat(2),16),n.toColor(i,s,r,o);case 7:return{css:e,rgba:(parseInt(e.slice(1),16)<<8|255)>>>0};case 9:return{css:e,rgba:parseInt(e.slice(1),16)>>>0}}const h=e.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(h)return i=parseInt(h[1],10),s=parseInt(h[2],10),r=parseInt(h[3],10),o=Math.round(255*(void 0===h[5]?1:parseFloat(h[5]))),n.toColor(i,s,r,o);if("transparent"===e)return{css:"transparent",rgba:0};if(!t||!a)throw new Error("css.toColor: Unsupported css format");if(t.fillStyle=a,t.fillStyle=e,"string"!=typeof t.fillStyle)throw new Error("css.toColor: Unsupported css format");if(t.fillRect(0,0,1,1),[i,s,r,o]=t.getImageData(0,0,1,1).data,255!==o)throw new Error("css.toColor: Unsupported css format");return{rgba:n.toRgba(i,s,r,o),css:e}}}(h||(t.css=h={})),function(e){function t(e,t,i){const s=e/255,r=t/255,o=i/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:Math.pow((r+.055)/1.055,2.4))+.0722*(o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4))}e.relativeLuminance=function(e){return t(e>>16&255,e>>8&255,255&e)},e.relativeLuminance2=t}(l||(t.rgb=l={})),function(e){function t(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c0||a>0||h>0);)n-=Math.max(0,Math.ceil(.1*n)),a-=Math.max(0,Math.ceil(.1*a)),h-=Math.max(0,Math.ceil(.1*h)),c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));return(n<<24|a<<16|h<<8|255)>>>0}function a(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c>>0}e.blend=function(e,t){if(o=(255&t)/255,1===o)return t;const a=t>>24&255,h=t>>16&255,l=t>>8&255,c=e>>24&255,d=e>>16&255,_=e>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),n.toRgba(i,s,r)},e.ensureContrastRatio=function(e,i,s){const r=l.relativeLuminance(e>>8),o=l.relativeLuminance(i>>8);if(_(r,o)>8));if(n_(r,l.relativeLuminance(t>>8))?o:t}return o}const n=a(e,i,s),h=_(r,l.relativeLuminance(n>>8));if(h_(r,l.relativeLuminance(o>>8))?n:o}return n}},e.reduceLuminance=t,e.increaseLuminance=a,e.toChannels=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}}(c||(t.rgba=c={}))},5777(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CoreTerminal=void 0;const s=i(6501),r=i(6025),o=i(7276),n=i(9640),a=i(56),h=i(4071),l=i(6478),c=i(7428),d=i(6415),_=i(5746),u=i(5882),f=i(2486),p=i(3562),v=i(8811),g=i(8636),m=i(4812);let S=!1;class b extends m.Disposable{get onScroll(){return this._onScrollApi||(this._onScrollApi=this._register(new g.Emitter),this._onScroll.event(e=>{this._onScrollApi?.fire(e.position)})),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(const t in e)this.optionsService.options[t]=e[t]}constructor(e){super(),this._windowsWrappingHeuristics=this._register(new m.MutableDisposable),this._onBinary=this._register(new g.Emitter),this.onBinary=this._onBinary.event,this._onData=this._register(new g.Emitter),this.onData=this._onData.event,this._onLineFeed=this._register(new g.Emitter),this.onLineFeed=this._onLineFeed.event,this._onRender=this._register(new g.Emitter),this.onRender=this._onRender.event,this._onResize=this._register(new g.Emitter),this.onResize=this._onResize.event,this._onWriteParsed=this._register(new g.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._onScroll=this._register(new g.Emitter),this._instantiationService=new r.InstantiationService,this.optionsService=this._register(new a.OptionsService(e)),this._instantiationService.setService(s.IOptionsService,this.optionsService),this._logService=this._register(this._instantiationService.createInstance(o.LogService)),this._instantiationService.setService(s.ILogService,this._logService),this._bufferService=this._register(this._instantiationService.createInstance(n.BufferService)),this._instantiationService.setService(s.IBufferService,this._bufferService),this.coreService=this._register(this._instantiationService.createInstance(h.CoreService)),this._instantiationService.setService(s.ICoreService,this.coreService),this.mouseStateService=this._register(this._instantiationService.createInstance(l.MouseStateService)),this._instantiationService.setService(s.IMouseStateService,this.mouseStateService),this.unicodeService=this._register(this._instantiationService.createInstance(d.UnicodeService)),this.unicodeService.register(new c.UnicodeV6),this._instantiationService.setService(s.IUnicodeService,this.unicodeService),this._charsetService=this._instantiationService.createInstance(_.CharsetService),this._instantiationService.setService(s.ICharsetService,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(v.OscLinkService),this._instantiationService.setService(s.IOscLinkService,this._oscLinkService),this._inputHandler=this._register(new f.InputHandler(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.mouseStateService,this.unicodeService)),this._register(g.EventUtils.forward(this._inputHandler.onLineFeed,this._onLineFeed)),this._register(g.EventUtils.forward(this._bufferService.onResize,this._onResize)),this._register(g.EventUtils.forward(this.coreService.onData,this._onData)),this._register(g.EventUtils.forward(this.coreService.onBinary,this._onBinary)),this._register(this.coreService.onRequestScrollToBottom(()=>this.scrollToBottom(!0))),this._register(this.coreService.onUserInput(()=>this._writeBuffer.handleUserInput())),this._register(this.optionsService.onMultipleOptionChange(["windowsPty"],()=>this._handleWindowsPtyOptionChange())),this._register(this._bufferService.onScroll(()=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)})),this._writeBuffer=this._register(new p.WriteBuffer((e,t)=>this._inputHandler.parse(e,t))),this._register(g.EventUtils.forward(this._writeBuffer.onWriteParsed,this._onWriteParsed))}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=s.LogLevelEnum.WARN&&!S&&(this._logService.warn("writeSync is unreliable and will be removed soon."),S=!0),this._writeBuffer.writeSync(e,t)}input(e,t=!0){this.coreService.triggerDataEvent(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,2),t=Math.max(t,1),this._writeBuffer.flushSync(),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t){this._bufferService.scrollLines(e,t)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}registerApcHandler(e,t){return this._inputHandler.registerApcHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.mouseStateService.reset()}_handleWindowsPtyOptionChange(){let e=!1;const t=this.optionsService.rawOptions.windowsPty;t&&void 0!==t.backend&&void 0!==t.buildNumber&&(e=!!("conpty"===t.backend&&t.buildNumber<21376)),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){const e=[];e.push(this.onLineFeed(u.updateWindowsModeWrappedState.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:"H"},()=>((0,u.updateWindowsModeWrappedState)(this._bufferService),!1))),this._windowsWrappingHeuristics.value=(0,m.toDisposable)(()=>{for(const t of e)t.dispose()})}}}t.CoreTerminal=b},8636(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EventUtils=t.Emitter=void 0;const s=i(4812);var r;t.Emitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=(e,t,i)=>{if(this._disposed)return(0,s.toDisposable)(()=>{});const r={fn:e,thisArgs:t};this._listeners.push(r);const o=(0,s.toDisposable)(()=>{const e=this._listeners.indexOf(r);-1!==e&&this._listeners.splice(e,1)});return i&&(Array.isArray(i)?i.push(o):i.add(o)),o}),this._event}fire(e){if(!this._disposed)switch(this._listeners.length){case 0:return;case 1:{const{fn:t,thisArgs:i}=this._listeners[0];return void t.call(i,e)}default:{const t=this._listeners.slice();for(const{fn:i,thisArgs:s}of t)i.call(s,e)}}}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},function(e){e.forward=function(e,t){return e(e=>t.fire(e))},e.map=function(e,t){return(i,s,r)=>e(e=>i.call(s,t(e)),void 0,r)},e.any=function(...e){return(t,i,r)=>{const o=new s.DisposableStore;for(const s of e)o.add(s(e=>t.call(i,e)));return r&&(Array.isArray(r)?r.push(o):r.add(o)),o}},e.runAndSubscribe=function(e,t,i){return t(i),e(e=>t(e))}}(r||(t.EventUtils=r={}))},2486(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.InputHandler=t.WindowsOptionsReportType=void 0,t.isValidColorIndex=x;const o=i(6760),n=i(6717),a=i(4812),h=i(726),l=i(6107),c=i(8938),d=i(3055),_=i(5451),u=i(6501),f=i(6415),p=i(1346),v=i(9823),g=i(2607),m=i(8693),S=i(8636),b=i(7804),y={"(":0,")":1,"*":2,"+":3,"-":1,".":2};function w(e,t){if(e>24)return t.setWinLines||!1;switch(e){case 1:return!!t.restoreWin;case 2:return!!t.minimizeWin;case 3:return!!t.setWinPosition;case 4:return!!t.setWinSizePixels;case 5:return!!t.raiseWin;case 6:return!!t.lowerWin;case 7:return!!t.refreshWin;case 8:return!!t.setWinSizeChars;case 9:return!!t.maximizeWin;case 10:return!!t.fullscreenWin;case 11:return!!t.getWinState;case 13:return!!t.getWinPosition;case 14:return!!t.getWinSizePixels;case 15:return!!t.getScreenSizePixels;case 16:return!!t.getCellSizePixels;case 18:return!!t.getWinSizeChars;case 19:return!!t.getScreenSizeChars;case 20:return!!t.getIconTitle;case 21:return!!t.getWinTitle;case 22:return!!t.pushTitle;case 23:return!!t.popTitle;case 24:return!!t.setWinLines}return!1}var C;!function(e){e[e.GET_WIN_SIZE_PIXELS=0]="GET_WIN_SIZE_PIXELS",e[e.GET_CELL_SIZE_PIXELS=1]="GET_CELL_SIZE_PIXELS"}(C||(t.WindowsOptionsReportType=C={}));let k=0;class D extends a.Disposable{getAttrData(){return this._curAttrData}constructor(e,t,i,s,r,a,c,d,_=new n.EscapeSequenceParser){super(),this._bufferService=e,this._charsetService=t,this._coreService=i,this._logService=s,this._optionsService=r,this._oscLinkService=a,this._mouseStateService=c,this._unicodeService=d,this._parser=_,this._parseBuffer=new Uint32Array(4096),this._stringDecoder=new h.StringToUtf32,this._utf8Decoder=new h.Utf8ToUtf32,this._windowTitle="",this._iconName="",this._windowTitleStack=[],this._iconNameStack=[],this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone(),this._onRequestBell=this._register(new S.Emitter),this.onRequestBell=this._onRequestBell.event,this._onRequestRefreshRows=this._register(new S.Emitter),this.onRequestRefreshRows=this._onRequestRefreshRows.event,this._onRequestReset=this._register(new S.Emitter),this.onRequestReset=this._onRequestReset.event,this._onRequestSendFocus=this._register(new S.Emitter),this.onRequestSendFocus=this._onRequestSendFocus.event,this._onRequestSyncScrollBar=this._register(new S.Emitter),this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event,this._onRequestWindowsOptionsReport=this._register(new S.Emitter),this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event,this._onA11yChar=this._register(new S.Emitter),this.onA11yChar=this._onA11yChar.event,this._onA11yTab=this._register(new S.Emitter),this.onA11yTab=this._onA11yTab.event,this._onCursorMove=this._register(new S.Emitter),this.onCursorMove=this._onCursorMove.event,this._onLineFeed=this._register(new S.Emitter),this.onLineFeed=this._onLineFeed.event,this._onScroll=this._register(new S.Emitter),this.onScroll=this._onScroll.event,this._onTitleChange=this._register(new S.Emitter),this.onTitleChange=this._onTitleChange.event,this._onColor=this._register(new S.Emitter),this.onColor=this._onColor.event,this._onRequestColorSchemeQuery=this._register(new S.Emitter),this.onRequestColorSchemeQuery=this._onRequestColorSchemeQuery.event,this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0},this._specialColors=[256,257,258],this._register(this._parser),this._dirtyRowTracker=new E(this._bufferService),this._activeBuffer=this._bufferService.buffer,this._register(this._bufferService.buffers.onBufferActivate(e=>this._activeBuffer=e.activeBuffer)),this._parser.setCsiHandlerFallback((e,t)=>{this._logService.debug("Unknown CSI code: ",{identifier:this._parser.identToString(e),params:t.toArray()})}),this._parser.setEscHandlerFallback(e=>{this._logService.debug("Unknown ESC code: ",{identifier:this._parser.identToString(e)})}),this._parser.setExecuteHandlerFallback(e=>{this._logService.debug("Unknown EXECUTE code: ",{code:e})}),this._parser.setOscHandlerFallback((e,t,i)=>{this._logService.debug("Unknown OSC code: ",{identifier:e,action:t,data:i})}),this._parser.setDcsHandlerFallback((e,t,i)=>{"HOOK"===t&&(i=i.toArray()),this._logService.debug("Unknown DCS code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setApcHandlerFallback((e,t,i)=>{this._logService.debug("Unknown APC code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setPrintHandler((e,t,i)=>this.print(e,t,i)),this._parser.registerCsiHandler({final:"@"},e=>this.insertChars(e)),this._parser.registerCsiHandler({intermediates:" ",final:"@"},e=>this.scrollLeft(e)),this._parser.registerCsiHandler({final:"A"},e=>this.cursorUp(e)),this._parser.registerCsiHandler({intermediates:" ",final:"A"},e=>this.scrollRight(e)),this._parser.registerCsiHandler({final:"B"},e=>this.cursorDown(e)),this._parser.registerCsiHandler({final:"C"},e=>this.cursorForward(e)),this._parser.registerCsiHandler({final:"D"},e=>this.cursorBackward(e)),this._parser.registerCsiHandler({final:"E"},e=>this.cursorNextLine(e)),this._parser.registerCsiHandler({final:"F"},e=>this.cursorPrecedingLine(e)),this._parser.registerCsiHandler({final:"G"},e=>this.cursorCharAbsolute(e)),this._parser.registerCsiHandler({final:"H"},e=>this.cursorPosition(e)),this._parser.registerCsiHandler({final:"I"},e=>this.cursorForwardTab(e)),this._parser.registerCsiHandler({final:"J"},e=>this.eraseInDisplay(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"J"},e=>this.eraseInDisplay(e,!0)),this._parser.registerCsiHandler({final:"K"},e=>this.eraseInLine(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"K"},e=>this.eraseInLine(e,!0)),this._parser.registerCsiHandler({final:"L"},e=>this.insertLines(e)),this._parser.registerCsiHandler({final:"M"},e=>this.deleteLines(e)),this._parser.registerCsiHandler({final:"P"},e=>this.deleteChars(e)),this._parser.registerCsiHandler({final:"S"},e=>this.scrollUp(e)),this._parser.registerCsiHandler({final:"T"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"X"},e=>this.eraseChars(e)),this._parser.registerCsiHandler({final:"Z"},e=>this.cursorBackwardTab(e)),this._parser.registerCsiHandler({final:"^"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"`"},e=>this.charPosAbsolute(e)),this._parser.registerCsiHandler({final:"a"},e=>this.hPositionRelative(e)),this._parser.registerCsiHandler({final:"b"},e=>this.repeatPrecedingCharacter(e)),this._parser.registerCsiHandler({final:"c"},e=>this.sendDeviceAttributesPrimary(e)),this._parser.registerCsiHandler({prefix:">",final:"c"},e=>this.sendDeviceAttributesSecondary(e)),this._parser.registerCsiHandler({final:"d"},e=>this.linePosAbsolute(e)),this._parser.registerCsiHandler({final:"e"},e=>this.vPositionRelative(e)),this._parser.registerCsiHandler({final:"f"},e=>this.hVPosition(e)),this._parser.registerCsiHandler({final:"g"},e=>this.tabClear(e)),this._parser.registerCsiHandler({final:"h"},e=>this.setMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"h"},e=>this.setModePrivate(e)),this._parser.registerCsiHandler({final:"l"},e=>this.resetMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"l"},e=>this.resetModePrivate(e)),this._parser.registerCsiHandler({final:"m"},e=>this.charAttributes(e)),this._parser.registerCsiHandler({final:"n"},e=>this.deviceStatus(e)),this._parser.registerCsiHandler({prefix:"?",final:"n"},e=>this.deviceStatusPrivate(e)),this._parser.registerCsiHandler({intermediates:"!",final:"p"},e=>this.softReset(e)),this._parser.registerCsiHandler({prefix:">",final:"q"},e=>this.sendXtVersion(e)),this._parser.registerCsiHandler({intermediates:" ",final:"q"},e=>this.setCursorStyle(e)),this._parser.registerCsiHandler({final:"r"},e=>this.setScrollRegion(e)),this._parser.registerCsiHandler({final:"s"},e=>this.saveCursor(e)),this._parser.registerCsiHandler({final:"t"},e=>this.windowOptions(e)),this._parser.registerCsiHandler({final:"u"},e=>this.restoreCursor(e)),this._parser.registerCsiHandler({intermediates:"'",final:"}"},e=>this.insertColumns(e)),this._parser.registerCsiHandler({intermediates:"'",final:"~"},e=>this.deleteColumns(e)),this._parser.registerCsiHandler({intermediates:'"',final:"q"},e=>this.selectProtected(e)),this._parser.registerCsiHandler({intermediates:"$",final:"p"},e=>this.requestMode(e,!0)),this._parser.registerCsiHandler({prefix:"?",intermediates:"$",final:"p"},e=>this.requestMode(e,!1)),this._parser.registerCsiHandler({prefix:"=",final:"u"},e=>this.kittyKeyboardSet(e)),this._parser.registerCsiHandler({prefix:"?",final:"u"},e=>this.kittyKeyboardQuery(e)),this._parser.registerCsiHandler({prefix:">",final:"u"},e=>this.kittyKeyboardPush(e)),this._parser.registerCsiHandler({prefix:"<",final:"u"},e=>this.kittyKeyboardPop(e)),this._parser.setExecuteHandler("",()=>this.bell()),this._parser.setExecuteHandler("\n",()=>this.lineFeed()),this._parser.setExecuteHandler("\v",()=>this.lineFeed()),this._parser.setExecuteHandler("\f",()=>this.lineFeed()),this._parser.setExecuteHandler("\r",()=>this.carriageReturn()),this._parser.setExecuteHandler("\b",()=>this.backspace()),this._parser.setExecuteHandler("\t",()=>this.tab()),this._parser.setExecuteHandler("",()=>this.shiftOut()),this._parser.setExecuteHandler("",()=>this.shiftIn()),this._parser.setExecuteHandler("„",()=>this.index()),this._parser.setExecuteHandler("…",()=>this.nextLine()),this._parser.setExecuteHandler("ˆ",()=>this.tabSet()),this._parser.registerOscHandler(0,new p.OscHandler(e=>(this.setTitle(e),this.setIconName(e),!0))),this._parser.registerOscHandler(1,new p.OscHandler(e=>this.setIconName(e))),this._parser.registerOscHandler(2,new p.OscHandler(e=>this.setTitle(e))),this._parser.registerOscHandler(4,new p.OscHandler(e=>this.setOrReportIndexedColor(e))),this._parser.registerOscHandler(8,new p.OscHandler(e=>this.setHyperlink(e))),this._parser.registerOscHandler(10,new p.OscHandler(e=>this.setOrReportFgColor(e))),this._parser.registerOscHandler(11,new p.OscHandler(e=>this.setOrReportBgColor(e))),this._parser.registerOscHandler(12,new p.OscHandler(e=>this.setOrReportCursorColor(e))),this._parser.registerOscHandler(104,new p.OscHandler(e=>this.restoreIndexedColor(e))),this._parser.registerOscHandler(110,new p.OscHandler(e=>this.restoreFgColor(e))),this._parser.registerOscHandler(111,new p.OscHandler(e=>this.restoreBgColor(e))),this._parser.registerOscHandler(112,new p.OscHandler(e=>this.restoreCursorColor(e))),this._parser.registerEscHandler({final:"7"},()=>this.saveCursor()),this._parser.registerEscHandler({final:"8"},()=>this.restoreCursor()),this._parser.registerEscHandler({final:"D"},()=>this.index()),this._parser.registerEscHandler({final:"E"},()=>this.nextLine()),this._parser.registerEscHandler({final:"H"},()=>this.tabSet()),this._parser.registerEscHandler({final:"M"},()=>this.reverseIndex()),this._parser.registerEscHandler({final:"="},()=>this.keypadApplicationMode()),this._parser.registerEscHandler({final:">"},()=>this.keypadNumericMode()),this._parser.registerEscHandler({final:"c"},()=>this.fullReset()),this._parser.registerEscHandler({final:"n"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"o"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"|"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"}"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"~"},()=>this.setgLevel(1)),this._parser.registerEscHandler({intermediates:"%",final:"@"},()=>this.selectDefaultCharset()),this._parser.registerEscHandler({intermediates:"%",final:"G"},()=>this.selectDefaultCharset());for(const e in o.CHARSETS)this._parser.registerEscHandler({intermediates:"(",final:e},()=>this.selectCharset("("+e)),this._parser.registerEscHandler({intermediates:")",final:e},()=>this.selectCharset(")"+e)),this._parser.registerEscHandler({intermediates:"*",final:e},()=>this.selectCharset("*"+e)),this._parser.registerEscHandler({intermediates:"+",final:e},()=>this.selectCharset("+"+e)),this._parser.registerEscHandler({intermediates:"-",final:e},()=>this.selectCharset("-"+e)),this._parser.registerEscHandler({intermediates:".",final:e},()=>this.selectCharset("."+e)),this._parser.registerEscHandler({intermediates:"/",final:e},()=>this.selectCharset("/"+e));this._parser.registerEscHandler({intermediates:"#",final:"8"},()=>this.screenAlignmentPattern()),this._parser.setErrorHandler(e=>(this._logService.error("Parsing error: ",e),e)),this._parser.registerDcsHandler({intermediates:"$",final:"q"},new v.DcsHandler((e,t)=>this.requestStatusString(e,t)))}_preserveStack(e,t,i,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=i,this._parseStack.position=s}_logSlowResolvingAsync(e){if(this._logService.logLevel<=u.LogLevelEnum.WARN){let t;const i=new Promise((e,i)=>{t=setTimeout(()=>i("#SLOW_TIMEOUT"),5e3)});Promise.race([e,i]).then(()=>{void 0!==t&&clearTimeout(t)},e=>{if(void 0!==t&&clearTimeout(t),"#SLOW_TIMEOUT"!==e)throw e;console.warn("async parser handler taking longer than 5000 ms")})}}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let i,s=this._activeBuffer.x,r=this._activeBuffer.y,o=0;const n=this._parseStack.paused;if(n){if(i=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(i),i;s=this._parseStack.cursorStartX,r=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>131072&&(o=this._parseStack.position+131072)}if(this._logService.logLevel<=u.LogLevelEnum.DEBUG&&this._logService.debug("parsing data "+("string"==typeof e?` "${e}"`:` "${Array.prototype.map.call(e,e=>String.fromCharCode(e)).join("")}"`)),this._logService.logLevel===u.LogLevelEnum.TRACE&&this._logService.trace("parsing data (codes)","string"==typeof e?e.split("").map(e=>e.charCodeAt(0)):e),this._parseBuffer.length131072)for(let t=o;t0&&2===p.getWidth(this._activeBuffer.x-1)&&p.setCellFromCodepoint(this._activeBuffer.x-1,0,1,u);let v=this._parser.precedingJoinState;for(let g=t;ga)if(d){const e=p;let t=this._activeBuffer.x-m;if(this._activeBuffer.x=m,this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData(),!0)):(this._activeBuffer.y>=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),p=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y),!p)return;for(m>0&&p instanceof l.BufferLine&&p.copyCellsFrom(e,t,0,m,!1);t=0;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u);continue}if(_&&(p.insertCells(this._activeBuffer.x,r-m,this._activeBuffer.getNullCell(u)),2===p.getWidth(a-1)&&p.setCellFromCodepoint(a-1,c.NULL_CELL_CODE,c.NULL_CELL_WIDTH,u)),p.setCellFromCodepoint(this._activeBuffer.x++,s,r,u),r>0)for(;--r;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u)}this._parser.precedingJoinState=v,this._activeBuffer.x0&&0===p.getWidth(this._activeBuffer.x)&&!p.hasContent(this._activeBuffer.x)&&p.setCellFromCodepoint(this._activeBuffer.x,0,1,u),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return"t"!==e.final||e.prefix||e.intermediates?this._parser.registerCsiHandler(e,t):this._parser.registerCsiHandler(e,e=>!w(e.params[0],this._optionsService.rawOptions.windowOptions)||t(e))}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new v.DcsHandler(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new p.OscHandler(t))}registerApcHandler(e,t){return this._parser.registerApcHandler(e,new g.ApcHandler(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(0===this._activeBuffer.x&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)?.isWrapped){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;const e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){const t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){const t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){const t=e.params[0];return 0===t?delete this._activeBuffer.tabs[this._activeBuffer.x]:3===t&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){const t=e.params[0];return 1===t&&(this._curAttrData.bg|=536870912),2!==t&&0!==t||(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,i,s=!1,r=!1){const o=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);o&&(o.replaceCells(t,i,this._activeBuffer.getNullCell(this._eraseAttrData()),r),s&&(o.isWrapped=!1))}_resetBufferLine(e,t=!1){const i=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);i&&(i.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),i.isWrapped=!1)}eraseInDisplay(e,t=!1){let i;switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:for(i=this._activeBuffer.y,this._dirtyRowTracker.markDirty(i),this._eraseInBufferLine(i++,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);i=this._bufferService.cols){const e=this._activeBuffer.lines.get(i+1);e&&(e.isWrapped=!1)}for(;i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 2:if(this._optionsService.rawOptions.scrollOnEraseInDisplay){for(i=this._bufferService.rows,this._dirtyRowTracker.markRangeDirty(0,i-1);i--;){const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+i);if(e?.getTrimmedLength())break}for(;i>=0;i--)this._bufferService.scroll(this._eraseAttrData())}else{for(i=this._bufferService.rows,this._dirtyRowTracker.markDirty(i-1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0)}break;case 3:const e=this._activeBuffer.lines.length-this._bufferService.rows;e>0&&(this._activeBuffer.lines.trimStart(e),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-e,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-e,0),this._onScroll.fire(0))}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t)}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y65535?2:1}let h=a;for(let e=1;e0||(this._is("xterm")||this._is("rxvt-unicode")||this._is("screen")?this._coreService.triggerDataEvent("[?1;2c"):this._is("linux")&&this._coreService.triggerDataEvent("[?6c")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is("xterm")?this._coreService.triggerDataEvent("[>0;276;0c"):this._is("rxvt-unicode")?this._coreService.triggerDataEvent("[>85;95;0c"):this._is("linux")?this._coreService.triggerDataEvent(e.params[0]+"c"):this._is("screen")&&this._coreService.triggerDataEvent("[>83;40003;0c")),!0}sendXtVersion(e){return e.params[0]>0||this._coreService.triggerDataEvent(`P>|xterm.js(${b.XTERM_VERSION})\\`),!0}_is(e){return(this._optionsService.rawOptions.termName+"").startsWith(e)}setMode(e){for(let t=0;t(o.triggerDataEvent(`[${t?"":"?"}${e};${i}$y`),!0),_=e=>e?1:2,u=e.params[0];return t?d(u,2===u?4:4===u?_(o.modes.insertMode):12===u?3:20===u?_(c.convertEol):0):1===u?d(u,_(i.applicationCursorKeys)):3===u?d(u,c.windowOptions.setWinLines?80===a?2:132===a?1:0:0):6===u?d(u,_(i.origin)):7===u?d(u,_(i.wraparound)):8===u?d(u,3):9===u?d(u,_("X10"===s)):12===u?d(u,_(c.cursorBlink)):25===u?d(u,_(!o.isCursorHidden)):45===u?d(u,_(i.reverseWraparound)):66===u?d(u,_(i.applicationKeypad)):67===u?d(u,4):1e3===u?d(u,_("VT200"===s)):1002===u?d(u,_("DRAG"===s)):1003===u?d(u,_("ANY"===s)):1004===u?d(u,_(i.sendFocus)):1005===u?d(u,4):1006===u?d(u,_("SGR"===r)):1015===u?d(u,4):1016===u?d(u,_("SGR_PIXELS"===r)):1048===u?d(u,1):47===u||1047===u||1049===u?d(u,_(h===l)):2004===u?d(u,_(i.bracketedPasteMode)):2026===u?d(u,_(i.synchronizedOutput)):9001===u&&this._optionsService.rawOptions.vtExtensions?.win32InputMode?d(u,_(i.win32InputMode)):d(u,0)}_updateAttrColor(e,t,i,s,r){return 2===t?(e|=50331648,e&=-16777216,e|=_.AttributeData.fromColorRGB([i,s,r])):5===t&&(e&=-67108864,e|=33554432|255&i),e}_extractColor(e,t,i){const s=[0,0,-1,0,0,0];let r=0,o=0;do{if(s[o+r]=e.params[t+o],e.hasSubParams(t+o)){const i=e.getSubParams(t+o);let n=0;do{5===s[1]&&(r=1),s[o+n+1+r]=i[n]}while(++n=2||2===s[1]&&o+r>=5)break;s[1]&&(r=1)}while(++o+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,0===e&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=l.DEFAULT_ATTR_DATA.fg,e.bg=l.DEFAULT_ATTR_DATA.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(1===e.length&&0===e.params[0])return this._processSGR0(this._curAttrData),!0;const t=e.length;let i;const s=this._curAttrData;for(let r=0;r=30&&i<=37?(s.fg&=-67108864,s.fg|=16777216|i-30):i>=40&&i<=47?(s.bg&=-67108864,s.bg|=16777216|i-40):i>=90&&i<=97?(s.fg&=-67108864,s.fg|=16777224|i-90):i>=100&&i<=107?(s.bg&=-67108864,s.bg|=16777224|i-100):0===i?this._processSGR0(s):1===i?s.fg|=134217728:3===i?s.bg|=67108864:4===i?(s.fg|=268435456,this._processUnderline(e.hasSubParams(r)?e.getSubParams(r)[0]:1,s)):5===i?s.fg|=536870912:7===i?s.fg|=67108864:8===i?s.fg|=1073741824:9===i?s.fg|=2147483648:2===i?s.bg|=134217728:21===i?this._processUnderline(2,s):22===i?(s.fg&=-134217729,s.bg&=-134217729):23===i?s.bg&=-67108865:24===i?(s.fg&=-268435457,this._processUnderline(0,s)):25===i?s.fg&=-536870913:27===i?s.fg&=-67108865:28===i?s.fg&=-1073741825:29===i?s.fg&=2147483647:39===i?(s.fg&=-67108864,s.fg|=16777215&l.DEFAULT_ATTR_DATA.fg):49===i?(s.bg&=-67108864,s.bg|=16777215&l.DEFAULT_ATTR_DATA.bg):38===i||48===i||58===i?r+=this._extractColor(e,r,s):53===i?s.bg|=1073741824:55===i?s.bg&=-1073741825:221===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.fg&=-134217729:222===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.bg&=-134217729:59===i?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):this._logService.debug("Unknown SGR attribute: %d.",i);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent("");break;case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[${e};${t}R`)}return!0}deviceStatusPrivate(e){switch(e.params[0]){case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[?${e};${t}R`);break;case 15:case 25:case 26:case 53:break;case 996:(this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery??1)&&this._onRequestColorSchemeQuery.fire()}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){const t=0===e.length?1:e.params[0];if(0===t)this._coreService.decPrivateModes.cursorStyle=void 0,this._coreService.decPrivateModes.cursorBlink=void 0;else{switch(t){case 1:case 2:this._coreService.decPrivateModes.cursorStyle="block";break;case 3:case 4:this._coreService.decPrivateModes.cursorStyle="underline";break;case 5:case 6:this._coreService.decPrivateModes.cursorStyle="bar"}const e=t%2==1;this._coreService.decPrivateModes.cursorBlink=e}return!0}setScrollRegion(e){const t=e.params[0]||1;let i;return(e.length<2||(i=e.params[1])>this._bufferService.rows||0===i)&&(i=this._bufferService.rows),i>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=i-1,this._setCursor(0,0)),!0}windowOptions(e){if(!w(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;const t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:2!==t&&this._onRequestWindowsOptionsReport.fire(C.GET_WIN_SIZE_PIXELS);break;case 16:this._onRequestWindowsOptionsReport.fire(C.GET_CELL_SIZE_PIXELS);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:0!==t&&2!==t||(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),0!==t&&1!==t||(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:0!==t&&2!==t||this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),0!==t&&1!==t||this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop())}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._activeBuffer.savedCharsets=this._charsetService.charsets.slice(),this._activeBuffer.savedGlevel=this._charsetService.glevel,this._activeBuffer.savedOriginMode=this._coreService.decPrivateModes.origin,this._activeBuffer.savedWraparoundMode=this._coreService.decPrivateModes.wraparound,!0}restoreCursor(e){this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg;for(let e=0;e1;){const e=i.shift(),s=i.shift();if(/^\d+$/.exec(e)){const i=parseInt(e,10);if(x(i))if("?"===s)t.push({type:0,index:i});else{const e=(0,m.parseColor)(s);e&&t.push({type:1,index:i,color:e})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){const t=e.indexOf(";");if(-1===t)return!0;const i=e.slice(0,t).trim(),s=e.slice(t+1);return s?this._createHyperlink(i,s):!i.trim()&&this._finishHyperlink()}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();const i=e.split(":");let s;const r=i.findIndex(e=>e.startsWith("id="));return-1!==r&&(s=i[r].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){const i=e.split(";");for(let e=0;e=this._specialColors.length);++e,++t)if("?"===i[e])this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{const s=(0,m.parseColor)(i[e]);s&&this._onColor.fire([{type:1,index:this._specialColors[t],color:s}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;const t=[],i=e.split(";");for(let e=0;e=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){const e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=67108863&this._curAttrData.bg,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){const e=new d.CellData;e.content=1<<22|"E".charCodeAt(0),e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`${e}\\`),!0))('"q'===e?`P1$r${this._curAttrData.isProtected()?1:0}"q`:'"p'===e?'P1$r61;1"p':"r"===e?`P1$r${i.scrollTop+1};${i.scrollBottom+1}r`:"m"===e?"P1$r0m":" q"===e?`P1$r${{block:2,underline:4,bar:6}[s.cursorStyle]-(s.cursorBlink?1:0)} q`:"P0$r")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}kittyKeyboardSet(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=e.length>1&&e.params[1]||1,s=this._coreService.kittyKeyboard;switch(i){case 1:s.flags=t;break;case 2:s.flags|=t;break;case 3:s.flags&=~t}return!0}kittyKeyboardQuery(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=this._coreService.kittyKeyboard.flags;return this._coreService.triggerDataEvent(`[?${t}u`),!0}kittyKeyboardPush(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;return s.length>=16&&s.shift(),s.push(i.flags),i.flags=t,!0}kittyKeyboardPop(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=Math.max(1,e.params[0]||1),i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;for(let e=0;e0;e++)i.flags=s.pop();return 0===s.length&&t>0&&(i.flags=0),!0}}t.InputHandler=D;let E=class{constructor(e){this._bufferService=e,this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(e){ethis.end&&(this.end=e)}markRangeDirty(e,t){e>t&&(k=e,e=t,t=k),ethis.end&&(this.end=t)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};function x(e){return 0<=e&&e<256}E=s([r(0,u.IBufferService)],E)},4812(e,t){function i(e){return{dispose:e}}function s(e){if(!e)return e;if(Array.isArray(e)){for(const t of e)t.dispose();return[]}return e.dispose(),e}Object.defineProperty(t,"__esModule",{value:!0}),t.MutableDisposable=t.Disposable=t.DisposableStore=void 0,t.toDisposable=i,t.dispose=s,t.combinedDisposable=function(...e){return i(()=>s(e))};class r{constructor(){this._disposables=new Set,this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(e){return this._isDisposed?e.dispose():this._disposables.add(e),e}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.clear()}}clear(){for(const e of this._disposables)e.dispose();this._disposables.clear()}}t.DisposableStore=r;class o{constructor(){this._store=new r}dispose(){this._store.dispose()}_register(e){return this._store.add(e)}}t.Disposable=o,o.None=Object.freeze({dispose(){}}),t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}}},7710(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.FourKeyMap=t.TwoKeyMap=void 0;class i{constructor(){this._data={}}set(e,t,i){this._data[e]||(this._data[e]={}),this._data[e][t]=i}get(e,t){return this._data[e]?this._data[e][t]:void 0}clear(){this._data={}}}t.TwoKeyMap=i,t.FourKeyMap=class{constructor(){this._data=new i}set(e,t,s,r,o){this._data.get(e,t)||this._data.set(e,t,new i),this._data.get(e,t).set(s,r,o)}get(e,t,i,s){return this._data.get(e,t)?.get(i,s)}clear(){this._data.clear()}}},701(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.isChromeOS=t.isLinux=t.isWindows=t.isMac=t.isSafari=t.isLegacyEdge=t.isChrome=t.isFirefox=t.isNode=void 0,t.getZoomFactor=function(e){return 1},t.getSafariVersion=function(){if(!t.isSafari)return 0;const e=i.match(/Version\/(\d+)/);return null===e||e.length<2?0:parseInt(e[1],10)},t.isNode=!("undefined"==typeof process||!("title"in process)||"undefined"!=typeof navigator&&!navigator.userAgent.startsWith("Node.js/"));const i=t.isNode?"node":navigator.userAgent,s=t.isNode?"node":navigator.platform;t.isFirefox=i.includes("Firefox"),t.isChrome=i.includes("Chrome"),t.isLegacyEdge=i.includes("Edge"),t.isSafari=/^((?!chrome|android).)*safari/i.test(i),t.isMac=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(s),t.isWindows=["Windows","Win16","Win32","WinCE"].includes(s),t.isLinux=s.indexOf("Linux")>=0,t.isChromeOS=/\bCrOS\b/.test(i)},3087(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.SortedList=void 0;const s=i(6168);let r=0;t.SortedList=class{constructor(e,t){this._getKey=e,this._array=[],this._insertedValues=[],this._isFlushingInserted=!1,this._deletedIndices=[],this._isFlushingDeleted=!1,this._flushInsertedTask=new s.IdleTaskQueue(t),this._flushDeletedTask=new s.IdleTaskQueue(t)}clear(){this._array.length=0,this._insertedValues.length=0,this._flushInsertedTask.clear(),this._isFlushingInserted=!1,this._deletedIndices.length=0,this._flushDeletedTask.clear(),this._isFlushingDeleted=!1}insert(e){this._flushCleanupDeleted(),0===this._insertedValues.length&&this._flushInsertedTask.enqueue(()=>this._flushInserted()),this._insertedValues.push(e)}_flushInserted(){const e=this._insertedValues.sort((e,t)=>this._getKey(e)-this._getKey(t));let t=0,i=0;const s=new Array(this._array.length+this._insertedValues.length);for(let r=0;r=this._array.length||this._getKey(e[t])<=this._getKey(this._array[i])?(s[r]=e[t],t++):s[r]=this._array[i++];this._array=s,this._insertedValues.length=0}_flushCleanupInserted(){!this._isFlushingInserted&&this._insertedValues.length>0&&this._flushInsertedTask.flush()}delete(e){if(this._flushCleanupInserted(),0===this._array.length)return!1;const t=this._getKey(e);return void 0!==t&&(!!this._deleteAtKey(e,t)||0!==this._deletedIndices.length&&(this._flushCleanupDeleted(),this._deleteAtKey(e,t)))}_deleteAtKey(e,t){if(r=this._search(t),-1===r)return!1;if(this._getKey(this._array[r])!==t)return!1;do{if(this._array[r]===e)return 0===this._deletedIndices.length&&this._flushDeletedTask.enqueue(()=>this._flushDeleted()),this._deletedIndices.push(r),!0}while(++re-t);let t=0;const i=new Array(this._array.length-e.length);let s=0;for(let r=0;r0&&this._flushDeletedTask.flush()}*getKeyIterator(e){if(this._flushCleanupInserted(),this._flushCleanupDeleted(),0!==this._array.length&&(r=this._search(e),!(r<0||r>=this._array.length)&&this._getKey(this._array[r])===e))do{yield this._array[r]}while(++r=this._array.length)&&this._getKey(this._array[r])===e))do{t(this._array[r])}while(++r=t;){let s=t+i>>1;const r=this._getKey(this._array[s]);if(r>e)i=s-1;else{if(!(r0&&this._getKey(this._array[s-1])===e;)s--;return s}t=s+1}}return t}}},4220(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.LimitedStringBuilder=t.StringBuilder=void 0;class i{constructor(){this._chunks=[],this._length=0}get length(){return this._length}reset(){this._chunks.length=0,this._length=0}append(e){this._chunks.push(e),this._length+=e.length}toString(){return this._chunks.join("")}}t.StringBuilder=i,t.LimitedStringBuilder=class{constructor(e){this._limit=e,this._builder=new i}get length(){return this._builder.length}get limit(){return this._limit}reset(){this._builder.reset()}append(e){return this._builder.append(e),this._builder.length>this._limit&&(this._builder.reset(),!0)}toString(){return this._builder.toString()}}},6168(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DebouncedIdleTask=t.IdleTaskQueue=t.PriorityTaskQueue=void 0;class i{constructor(e){this._tasks=[],this._i=0,this._logService=e}enqueue(e){this._tasks.push(e),this._start()}flush(){for(;this._ii)return r-t<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-t))}ms`),void this._start();r=i}this.clear()}}class s extends i{_requestCallback(e){return setTimeout(()=>e(this._createDeadline(16)))}_cancelCallback(e){clearTimeout(e)}_createDeadline(e){const t=performance.now()+e;return{timeRemaining:()=>Math.max(0,t-performance.now())}}}t.PriorityTaskQueue=s,t.IdleTaskQueue="requestIdleCallback"in globalThis?class extends i{_requestCallback(e){return requestIdleCallback(e)}_cancelCallback(e){cancelIdleCallback(e)}}:s,t.DebouncedIdleTask=class{constructor(e){this._queue=new t.IdleTaskQueue(e)}set(e){this._queue.clear(),this._queue.enqueue(e)}flush(){this._queue.flush()}dispose(){this._queue.clear()}}},7804(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.XTERM_VERSION=void 0,t.XTERM_VERSION="6.1.0-beta.287"},5882(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.updateWindowsModeWrappedState=function(e){const t=e.buffer.lines.get(e.buffer.ybase+e.buffer.y-1),i=t?.get(e.cols-1),r=e.buffer.lines.get(e.buffer.ybase+e.buffer.y);r&&i&&(r.isWrapped=i[s.CHAR_DATA_CODE_INDEX]!==s.NULL_CELL_CODE&&i[s.CHAR_DATA_CODE_INDEX]!==s.WHITESPACE_CELL_CODE)};const s=i(8938)},5451(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ExtendedAttrs=t.AttributeData=void 0;class i{constructor(){this.fg=0,this.bg=0,this.extended=new s}static toColorRGB(e){return[e>>>16&255,e>>>8&255,255&e]}static fromColorRGB(e){return(255&e[0])<<16|(255&e[1])<<8|255&e[2]}clone(){const e=new i;return e.fg=this.fg,e.bg=this.bg,e.extended=this.extended.clone(),e}isInverse(){return 67108864&this.fg}isBold(){return 134217728&this.fg}isUnderline(){return this.hasExtendedAttrs()&&0!==this.extended.underlineStyle?1:268435456&this.fg}isBlink(){return 536870912&this.fg}isInvisible(){return 1073741824&this.fg}isItalic(){return 67108864&this.bg}isDim(){return 134217728&this.bg}isStrikethrough(){return 2147483648&this.fg}isProtected(){return 536870912&this.bg}isOverline(){return 1073741824&this.bg}getFgColorMode(){return 50331648&this.fg}getBgColorMode(){return 50331648&this.bg}isFgRGB(){return!(50331648&~this.fg)}isBgRGB(){return!(50331648&~this.bg)}isFgPalette(){return 16777216==(50331648&this.fg)||33554432==(50331648&this.fg)}isBgPalette(){return 16777216==(50331648&this.bg)||33554432==(50331648&this.bg)}isFgDefault(){return!(50331648&this.fg)}isBgDefault(){return!(50331648&this.bg)}isAttributeDefault(){return 0===this.fg&&0===this.bg}getFgColor(){switch(50331648&this.fg){case 16777216:case 33554432:return 255&this.fg;case 50331648:return 16777215&this.fg;default:return-1}}getBgColor(){switch(50331648&this.bg){case 16777216:case 33554432:return 255&this.bg;case 50331648:return 16777215&this.bg;default:return-1}}hasExtendedAttrs(){return 268435456&this.bg}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(268435456&this.bg&&~this.extended.underlineColor)switch(50331648&this.extended.underlineColor){case 16777216:case 33554432:return 255&this.extended.underlineColor;case 50331648:return 16777215&this.extended.underlineColor;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return 268435456&this.bg&&~this.extended.underlineColor?50331648&this.extended.underlineColor:this.getFgColorMode()}isUnderlineColorRGB(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&~this.extended.underlineColor):this.isFgRGB()}isUnderlineColorPalette(){return 268435456&this.bg&&~this.extended.underlineColor?16777216==(50331648&this.extended.underlineColor)||33554432==(50331648&this.extended.underlineColor):this.isFgPalette()}isUnderlineColorDefault(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&this.extended.underlineColor):this.isFgDefault()}getUnderlineStyle(){return 268435456&this.fg?268435456&this.bg?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}}t.AttributeData=i;class s{get ext(){return this._urlId?-469762049&this._ext|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(469762048&this._ext)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return 67108863&this._ext}set underlineColor(e){this._ext&=-67108864,this._ext|=67108863&e}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){const e=(3758096384&this._ext)>>29;return e<0?4294967288^e:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}clone(){return new s(this._ext,this._urlId)}isEmpty(){return 0===this.underlineStyle&&0===this._urlId}}t.ExtendedAttrs=s},1073(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Buffer=t.MAX_BUFFER_SIZE=void 0;const s=i(5639),r=i(4812),o=i(6168),n=i(5451),a=i(6107),h=i(3326),l=i(732),c=i(3055),d=i(8938),_=i(8158),u=i(6760);t.MAX_BUFFER_SIZE=4294967295;class f extends r.Disposable{constructor(e,t,i,n){super(),this._hasScrollback=e,this._optionsService=t,this._bufferService=i,this._logService=n,this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.tabs={},this.savedY=0,this.savedX=0,this.savedCurAttrData=a.DEFAULT_ATTR_DATA.clone(),this.savedCharset=u.DEFAULT_CHARSET,this.savedCharsets=[],this.savedGlevel=0,this.savedOriginMode=!1,this.savedWraparoundMode=!0,this.markers=[],this._nullCell=c.CellData.fromCharData([0,d.NULL_CELL_CHAR,d.NULL_CELL_WIDTH,d.NULL_CELL_CODE]),this._whitespaceCell=c.CellData.fromCharData([0,d.WHITESPACE_CELL_CHAR,d.WHITESPACE_CELL_WIDTH,d.WHITESPACE_CELL_CODE]),this._isClearing=!1,this._memoryCleanupPosition=0,this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops(),this._memoryCleanupQueue=new o.IdleTaskQueue(this._logService),this._register((0,r.toDisposable)(()=>this._memoryCleanupQueue.clear())),this._register((0,r.toDisposable)(()=>this.clearAllMarkers())),this._stringCache=this._register(new h.BufferLineStringCache)}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new n.ExtendedAttrs),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new n.ExtendedAttrs),this._whitespaceCell}getBlankLine(e,t){return new a.BufferLine(this._stringCache,this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){const e=this.ybase+this.y-this.ydisp;return e>=0&&et.MAX_BUFFER_SIZE?t.MAX_BUFFER_SIZE:i}fillViewportRows(e){if(0===this.lines.length){e??=a.DEFAULT_ATTR_DATA;let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this._stringCache.clear(),this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){const i=this.getNullCell(a.DEFAULT_ATTR_DATA);this._stringCache.clear();let s=0;const r=this._getCorrectBufferLength(t);if(r>this.lines.maxLength&&(this.lines.maxLength=r),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+o+1?(this.ybase--,o++,this.ydisp>0&&this.ydisp--):this.lines.push(new a.BufferLine(this._stringCache,e,i,!1)));else for(let e=this._rows;e>t;e--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(r0&&(this.lines.trimStart(e),this.ybase=Math.max(this.ybase-e,0),this.ydisp=Math.max(this.ydisp-e,0),this.savedY=Math.max(this.savedY-e,0)),this.lines.maxLength=r}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),o&&(this.y+=o),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let t=0;t0){const e=Math.max(0,this.lines.length-this.ybase-1);this.y=Math.min(this.y,e)}this._memoryCleanupQueue.clear(),s>.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue(()=>this._batchedMemoryCleanup()))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){const e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&"conpty"===e.backend&&e.buildNumber>=21376:this._hasScrollback}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){const i=this._optionsService.rawOptions.reflowCursorLine,s=(0,l.reflowLargerGetLinesToRemove)(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(a.DEFAULT_ATTR_DATA),i);if(s.length>0){const i=(0,l.reflowLargerCreateNewLayout)(this.lines,s);(0,l.reflowLargerApplyNewLayout)(this.lines,i.layout),this._reflowLargerAdjustViewport(e,t,i.countRemoved)}}_reflowLargerAdjustViewport(e,t,i){const s=this.getNullCell(a.DEFAULT_ATTR_DATA);let r=i;for(;r-- >0;)0===this.ybase?(this.y>0&&this.y--,this.lines.length=0;n--){let h=this.lines.get(n);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;const c=[h];for(;h.isWrapped&&n>0;)h=this.lines.get(--n),c.unshift(h);if(!i){const e=this.ybase+this.y;if(e>=n&&e0&&(r.push({start:n+c.length+o,newLines:p}),o+=p.length),c.push(...p);let v=_.length-1,g=_[v];0===g&&(v--,g=_[v]);let m=c.length-u-1,S=d;for(;m>=0;){const e=Math.min(S,g);if(void 0===c[v])break;if(c[v].copyCellsFrom(c[m],S-e,g-e,e,!0),g-=e,0===g&&(v--,g=_[v]),S-=e,0===S){m--;const e=Math.max(m,0);S=(0,l.getWrappedLineTrimmedLength)(c,e,this._cols)}}for(let t=0;t0;)0===this.ybase?this.y0){const e=[],t=[];for(let e=0;e=0;l--)if(a&&a.start>s+h){for(let e=a.newLines.length-1;e>=0;e--)this.lines.set(l--,a.newLines[e]);l++,e.push({index:s+1,amount:a.newLines.length}),h+=a.newLines.length,a=r[++n]}else this.lines.set(l,t[s--]);let l=0;for(let t=e.length-1;t>=0;t--)e[t].index+=l,this.lines.onInsertEmitter.fire(e[t]),l+=e[t].amount;const c=Math.max(0,i+o-this.lines.maxLength);c>0&&this.lines.onTrimEmitter.fire(c)}}translateBufferLineToString(e,t,i=0,s){const r=this.lines.get(e);return r?r.translateToString(t,i,s):""}getWrappedRangeForLine(e){let t=e,i=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;i+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(e??=this.x;!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=e,t.line<0&&t.dispose()})),t.register(this.lines.onInsert(e=>{t.line>=e.index&&(t.line+=e.amount)})),t.register(this.lines.onDelete(e=>{t.line>=e.index&&t.linee.index&&(t.line-=e.amount)})),t.register(t.onDispose(()=>this._removeMarker(t))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}}t.Buffer=f},6107(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferLine=t.DEFAULT_ATTR_DATA=void 0;const s=i(5451),r=i(3055),o=i(8938),n=i(726),a=i(4220);t.DEFAULT_ATTR_DATA=Object.freeze(new s.AttributeData);let h=0;const l=new r.CellData,c=new a.StringBuilder;class d{constructor(e,t,i,s=!1){this._stringCache=e,this.isWrapped=s,this._combined={},this._extendedAttrs={},this._data=new Uint32Array(3*t);const n=i??r.CellData.fromCharData([0,o.NULL_CELL_CHAR,o.NULL_CELL_WIDTH,o.NULL_CELL_CODE]);for(let e=0;e>22,2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):i]}set(e,t){this._invalidateStringCache(),this._data[3*e+1]=t[o.CHAR_DATA_ATTR_INDEX],t[o.CHAR_DATA_CHAR_INDEX].length>1?(this._combined[e]=t[1],this._data[3*e+0]=2097152|e|t[o.CHAR_DATA_WIDTH_INDEX]<<22):this._data[3*e+0]=t[o.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|t[o.CHAR_DATA_WIDTH_INDEX]<<22}getWidth(e){return this._data[3*e+0]>>22}hasWidth(e){return 12582912&this._data[3*e+0]}getFg(e){return this._data[3*e+1]}getBg(e){return this._data[3*e+2]}hasContent(e){return 4194303&this._data[3*e+0]}getCodePoint(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):2097151&t}isCombined(e){return 2097152&this._data[3*e+0]}getString(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e]:2097151&t?(0,n.stringFromCodePoint)(2097151&t):""}isProtected(e){return 536870912&this._data[3*e+2]}loadCell(e,i){return h=3*e,i.content=this._data[h+0],i.fg=this._data[h+1],i.bg=this._data[h+2],2097152&i.content?i.combinedData=this._combined[e]:i.combinedData="",268435456&i.bg?i.extended=this._extendedAttrs[e]:i.extended=t.DEFAULT_ATTR_DATA.extended.clone(),i}setCell(e,t){this._invalidateStringCache(),2097152&t.content&&(this._combined[e]=t.combinedData),268435456&t.bg&&(this._extendedAttrs[e]=t.extended),this._data[3*e+0]=t.content,this._data[3*e+1]=t.fg,this._data[3*e+2]=t.bg}setCellFromCodepoint(e,t,i,s){this._invalidateStringCache(),268435456&s.bg&&(this._extendedAttrs[e]=s.extended),this._data[3*e+0]=t|i<<22,this._data[3*e+1]=s.fg,this._data[3*e+2]=s.bg}addCodepointToCell(e,t,i){this._invalidateStringCache();let s=this._data[3*e+0];2097152&s?this._combined[e]+=(0,n.stringFromCodePoint)(t):2097151&s?(this._combined[e]=(0,n.stringFromCodePoint)(2097151&s)+(0,n.stringFromCodePoint)(t),s&=-2097152,s|=2097152):s=t|1<<22,i&&(s&=-12582913,s|=i<<22),this._data[3*e+0]=s}insertCells(e,t,i){if(this._invalidateStringCache(),(e%=this.length)&&2===this.getWidth(e-1)&&this.setCellFromCodepoint(e-1,0,1,i),t=0;--i)this.setCell(e+t+i,this.loadCell(e+i,l));for(let s=0;sthis.length){if(this._data.buffer.byteLength>=4*i)this._data=new Uint32Array(this._data.buffer,0,i);else{const e=new Uint32Array(i);e.set(this._data),this._data=e}for(let i=this.length;i=e&&delete this._combined[s]}const s=Object.keys(this._extendedAttrs);for(let t=0;t=e&&delete this._extendedAttrs[i]}}return this.length=e,4*i*2=0;--e)if(4194303&this._data[3*e+0])return e+(this._data[3*e+0]>>22);return 0}getNoBgTrimmedLength(){for(let e=this.length-1;e>=0;--e)if(4194303&this._data[3*e+0]||50331648&this._data[3*e+2])return e+(this._data[3*e+0]>>22);return 0}copyCellsFrom(e,t,i,s,r){this._invalidateStringCache();const o=e._data;if(r)for(let r=s-1;r>=0;r--){for(let e=0;e<3;e++)this._data[3*(i+r)+e]=o[3*(t+r)+e];this._copyCellMapsFrom(e,t+r,i+r)}else for(let r=0;r>22||1}s&&s.push(t);const h=c.toString();if(c.reset(),r){const t=this._getStringCacheEntry(!0);t.value=h,t.isTrimmed=!!e}return h}_getStringCacheEntry(e){const t=this._stringCacheEntryRef?.deref();if(t&&t.generation===this._stringCache.generation)return t;if(!e)return;const i=this._stringCache.allocateEntry();return this._stringCacheEntryRef=new WeakRef(i),i}_invalidateStringCache(){const e=this._getStringCacheEntry(!1);e&&(e.value=void 0,e.isTrimmed=!1)}_copyCellMapsFrom(e,t,i){const s=3*t;2097152&e._data[s+0]&&(this._combined[i]=e._combined[t]),268435456&e._data[s+2]&&(this._extendedAttrs[i]=e._extendedAttrs[t])}_copySparseMapsFrom(e){this._combined={},this._extendedAttrs={};for(let t=0;tthis.entries.clear()))}touch(){this._scheduleClear()}allocateEntry(){const e={value:void 0,isTrimmed:!1,generation:this.generation};return this.entries.add(e),this._scheduleClear(),e}clear(){this._clearTimeout.clear(),this._lastAccessTimestamp=0,this.generation++;for(const e of this.entries)e.value=void 0,e.isTrimmed=!1;this.entries.clear()}_scheduleClear(){this._lastAccessTimestamp=Date.now(),this._clearTimeout.value||this._scheduleClearTimeout(15e3)}_scheduleClearTimeout(e){this._clearTimeout.value=(0,s.disposableTimeout)(()=>{const e=Date.now()-this._lastAccessTimestamp;e>=15e3?this.clear():this._scheduleClearTimeout(15e3-e)},e)}}t.BufferLineStringCache=o},9384(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.getRangeLength=function(e,t){if(e.start.y>e.end.y)throw new Error(`Buffer range end (${e.end.x}, ${e.end.y}) cannot be before start (${e.start.x}, ${e.start.y})`);return t*(e.end.y-e.start.y)+(e.end.x-e.start.x+1)}},732(e,t){function i(e,t,i){if(t===e.length-1)return e[t].getTrimmedLength();const s=!e[t].hasContent(i-1)&&1===e[t].getWidth(i-1),r=2===e[t+1].getWidth(0);return s&&r?i-1:i}Object.defineProperty(t,"__esModule",{value:!0}),t.reflowLargerGetLinesToRemove=function(e,t,s,r,o,n){const a=[];for(let h=0;h=h&&r0&&(e>_||0===d[e].getTrimmedLength());e--)v++;v>0&&(a.push(h+d.length-v),a.push(v)),h+=d.length-1}return a},t.reflowLargerCreateNewLayout=function(e,t){const i=[];let s=0,r=t[s],o=0;for(let n=0;nl&&(n-=l,a++);const c=2===e[a].getWidth(n-1);c&&n--;const d=c?s-1:s;r.push(d),h+=d}return r},t.getWrappedLineTrimmedLength=i},4097(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferSet=void 0;const s=i(4812),r=i(1073),o=i(8636);class n extends s.Disposable{constructor(e,t,i){super(),this._optionsService=e,this._bufferService=t,this._logService=i,this._normalBuffer=this._register(new s.MutableDisposable),this._altBuffer=this._register(new s.MutableDisposable),this._onBufferActivate=this._register(new o.Emitter),this.onBufferActivate=this._onBufferActivate.event,this.reset(),this._register(this._optionsService.onSpecificOptionChange("scrollback",()=>this.resize(this._bufferService.cols,this._bufferService.rows))),this._register(this._optionsService.onSpecificOptionChange("tabStopWidth",()=>this.setupTabStops()))}reset(){this._normal=new r.Buffer(!0,this._optionsService,this._bufferService,this._logService),this._normalBuffer.value=this._normal,this._normal.fillViewportRows(),this._alt=new r.Buffer(!1,this._optionsService,this._bufferService,this._logService),this._altBuffer.value=this._alt,this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}}t.BufferSet=n},3055(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CellData=void 0;const s=i(726),r=i(8938),o=i(5451);class n extends o.AttributeData{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new o.ExtendedAttrs,this.combinedData=""}static fromCharData(e){const t=new n;return t.setFromCharData(e),t}isCombined(){return 2097152&this.content}getWidth(){return this.content>>22}getChars(){return 2097152&this.content?this.combinedData:2097151&this.content?(0,s.stringFromCodePoint)(2097151&this.content):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):2097151&this.content}setFromCharData(e){this.fg=e[r.CHAR_DATA_ATTR_INDEX],this.bg=0;let t=!1;if(e[r.CHAR_DATA_CHAR_INDEX].length>2)t=!0;else if(2===e[r.CHAR_DATA_CHAR_INDEX].length){const i=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0);if(55296<=i&&i<=56319){const s=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(1);56320<=s&&s<=57343?this.content=1024*(i-55296)+s-56320+65536|e[r.CHAR_DATA_WIDTH_INDEX]<<22:t=!0}else t=!0}else this.content=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|e[r.CHAR_DATA_WIDTH_INDEX]<<22;t&&(this.combinedData=e[r.CHAR_DATA_CHAR_INDEX],this.content=2097152|e[r.CHAR_DATA_WIDTH_INDEX]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}attributesEquals(e){if(this.getFgColorMode()!==e.getFgColorMode()||this.getFgColor()!==e.getFgColor())return!1;if(this.getBgColorMode()!==e.getBgColorMode()||this.getBgColor()!==e.getBgColor())return!1;if(this.isInverse()!==e.isInverse())return!1;if(this.isBold()!==e.isBold())return!1;if(this.isUnderline()!==e.isUnderline())return!1;if(this.isUnderline()){if(this.getUnderlineStyle()!==e.getUnderlineStyle())return!1;const t=this.isUnderlineColorDefault(),i=e.isUnderlineColorDefault();if(!t||!i){if(t!==i)return!1;if(this.getUnderlineColor()!==e.getUnderlineColor())return!1;if(this.getUnderlineColorMode()!==e.getUnderlineColorMode())return!1}}return this.isOverline()===e.isOverline()&&this.isBlink()===e.isBlink()&&this.isInvisible()===e.isInvisible()&&this.isItalic()===e.isItalic()&&this.isDim()===e.isDim()&&this.isStrikethrough()===e.isStrikethrough()}}t.CellData=n},8938(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.WHITESPACE_CELL_CODE=t.WHITESPACE_CELL_WIDTH=t.WHITESPACE_CELL_CHAR=t.NULL_CELL_CODE=t.NULL_CELL_WIDTH=t.NULL_CELL_CHAR=t.CHAR_DATA_CODE_INDEX=t.CHAR_DATA_WIDTH_INDEX=t.CHAR_DATA_CHAR_INDEX=t.CHAR_DATA_ATTR_INDEX=t.DEFAULT_EXT=t.DEFAULT_ATTR=t.DEFAULT_COLOR=void 0,t.DEFAULT_COLOR=0,t.DEFAULT_ATTR=t.DEFAULT_COLOR<<9|256,t.DEFAULT_EXT=0,t.CHAR_DATA_ATTR_INDEX=0,t.CHAR_DATA_CHAR_INDEX=1,t.CHAR_DATA_WIDTH_INDEX=2,t.CHAR_DATA_CODE_INDEX=3,t.NULL_CELL_CHAR="",t.NULL_CELL_WIDTH=1,t.NULL_CELL_CODE=0,t.WHITESPACE_CELL_CHAR=" ",t.WHITESPACE_CELL_WIDTH=1,t.WHITESPACE_CELL_CODE=32},8158(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Marker=void 0;const s=i(4812),r=i(8636);class o{get id(){return this._id}constructor(e){this.line=e,this.isDisposed=!1,this._disposables=[],this._id=o._nextId++,this._onDispose=this.register(new r.Emitter),this.onDispose=this._onDispose.event}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),(0,s.dispose)(this._disposables),this._disposables.length=0)}register(e){return this._disposables.push(e),e}}t.Marker=o,o._nextId=1},6760(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CHARSET=t.CHARSETS=void 0,t.CHARSETS={},t.DEFAULT_CHARSET=t.CHARSETS.B,t.CHARSETS[0]={"`":"◆",a:"▒",b:"␉",c:"␌",d:"␍",e:"␊",f:"°",g:"±",h:"␤",i:"␋",j:"┘",k:"┐",l:"┌",m:"└",n:"┼",o:"⎺",p:"⎻",q:"─",r:"⎼",s:"⎽",t:"├",u:"┤",v:"┴",w:"┬",x:"│",y:"≤",z:"≥","{":"π","|":"≠","}":"£","~":"·"},t.CHARSETS.A={"#":"£"},t.CHARSETS.B=void 0,t.CHARSETS[4]={"#":"£","@":"¾","[":"ij","\\":"½","]":"|","{":"¨","|":"f","}":"¼","~":"´"},t.CHARSETS.C=t.CHARSETS[5]={"[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS.R={"#":"£","@":"à","[":"°","\\":"ç","]":"§","{":"é","|":"ù","}":"è","~":"¨"},t.CHARSETS.Q={"@":"à","[":"â","\\":"ç","]":"ê","^":"î","`":"ô","{":"é","|":"ù","}":"è","~":"û"},t.CHARSETS.K={"@":"§","[":"Ä","\\":"Ö","]":"Ü","{":"ä","|":"ö","}":"ü","~":"ß"},t.CHARSETS.Y={"#":"£","@":"§","[":"°","\\":"ç","]":"é","`":"ù","{":"à","|":"ò","}":"è","~":"ì"},t.CHARSETS.E=t.CHARSETS[6]={"@":"Ä","[":"Æ","\\":"Ø","]":"Å","^":"Ü","`":"ä","{":"æ","|":"ø","}":"å","~":"ü"},t.CHARSETS.Z={"#":"£","@":"§","[":"¡","\\":"Ñ","]":"¿","{":"°","|":"ñ","}":"ç"},t.CHARSETS.H=t.CHARSETS[7]={"@":"É","[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS["="]={"#":"ù","@":"à","[":"é","\\":"ç","]":"ê","^":"î",_:"è","`":"ô","{":"ä","|":"ö","}":"ü","~":"û"}},706(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.evaluateKeyboardEvent=function(e,t,s,r){const o={type:0,cancel:!1,key:void 0},n=(e.shiftKey?1:0)|(e.altKey?2:0)|(e.ctrlKey?4:0)|(e.metaKey?8:0);switch(e.keyCode){case 0:"UIKeyInputUpArrow"===e.key?o.key=t?"OA":"":"UIKeyInputLeftArrow"===e.key?o.key=t?"OD":"":"UIKeyInputRightArrow"===e.key?o.key=t?"OC":"":"UIKeyInputDownArrow"===e.key&&(o.key=t?"OB":"");break;case 8:o.key=e.ctrlKey?"\b":"",e.altKey&&(o.key=""+o.key);break;case 9:if(e.shiftKey){o.key="";break}o.key="\t",o.cancel=!0;break;case 13:"c"===e.key&&e.ctrlKey?o.key="":o.key=e.altKey?"\r":"\r",o.cancel=!0;break;case 27:o.key="",e.altKey&&(o.key=""),o.cancel=!0;break;case 37:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"D":t?"OD":"";break;case 39:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"C":t?"OC":"";break;case 38:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"A":t?"OA":"";break;case 40:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"B":t?"OB":"";break;case 45:e.shiftKey||e.ctrlKey||(o.key="[2~");break;case 46:o.key=n?"[3;"+(n+1)+"~":"[3~";break;case 36:o.key=n?"[1;"+(n+1)+"H":t?"OH":"";break;case 35:o.key=n?"[1;"+(n+1)+"F":t?"OF":"";break;case 33:e.shiftKey?o.type=2:e.ctrlKey?o.key="[5;"+(n+1)+"~":o.key="[5~";break;case 34:e.shiftKey?o.type=3:e.ctrlKey?o.key="[6;"+(n+1)+"~":o.key="[6~";break;case 112:o.key=n?"[1;"+(n+1)+"P":"OP";break;case 113:o.key=n?"[1;"+(n+1)+"Q":"OQ";break;case 114:o.key=n?"[1;"+(n+1)+"R":"OR";break;case 115:o.key=n?"[1;"+(n+1)+"S":"OS";break;case 116:o.key=n?"[15;"+(n+1)+"~":"[15~";break;case 117:o.key=n?"[17;"+(n+1)+"~":"[17~";break;case 118:o.key=n?"[18;"+(n+1)+"~":"[18~";break;case 119:o.key=n?"[19;"+(n+1)+"~":"[19~";break;case 120:o.key=n?"[20;"+(n+1)+"~":"[20~";break;case 121:o.key=n?"[21;"+(n+1)+"~":"[21~";break;case 122:o.key=n?"[23;"+(n+1)+"~":"[23~";break;case 123:o.key=n?"[24;"+(n+1)+"~":"[24~";break;default:if(!e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)if(s&&!r||!e.altKey||e.metaKey)if(!s||e.altKey||e.ctrlKey||e.shiftKey||!e.metaKey){if(e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.keyCode>=48&&1===e.key.length)o.key=e.key;else if(e.key&&e.ctrlKey&&e.shiftKey)switch(e.code){case"Minus":o.key="";break;case"Digit2":o.key="\0";break;case"Digit6":o.key=""}}else 65===e.keyCode&&(o.type=1);else{const t=i[e.keyCode],s=t?.[e.shiftKey?1:0];if(s)o.key=""+s;else if(e.keyCode>=65&&e.keyCode<=90){const t=e.ctrlKey?e.keyCode-64:e.keyCode+32;let i=String.fromCharCode(t);e.shiftKey&&(i=i.toUpperCase()),o.key=""+i}else if(32===e.keyCode)o.key=""+(e.ctrlKey?"\0":" ");else if("Dead"===e.key&&e.code.startsWith("Key")){let t=e.code.slice(3,4);e.shiftKey||(t=t.toLowerCase()),o.key=""+t,o.cancel=!0}}else e.keyCode>=65&&e.keyCode<=90?o.key=String.fromCharCode(e.keyCode-64):32===e.keyCode?o.key="\0":e.keyCode>=51&&e.keyCode<=55?o.key=String.fromCharCode(e.keyCode-51+27):56===e.keyCode?o.key="":"/"===e.key?o.key="":219===e.keyCode?o.key="":220===e.keyCode?o.key="":221===e.keyCode&&(o.key="")}return o};const i={48:["0",")"],49:["1","!"],50:["2","@"],51:["3","#"],52:["4","$"],53:["5","%"],54:["6","^"],55:["7","&"],56:["8","*"],57:["9","("],186:[";",":"],187:["=","+"],188:[",","<"],189:["-","_"],190:[".",">"],191:["/","?"],192:["`","~"],219:["[","{"],220:["\\","|"],221:["]","}"],222:["'",'"']}},7241(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.KittyKeyboard=void 0,t.KittyKeyboard=class{constructor(){this._functionalKeyCodes={Escape:27,Enter:13,Tab:9,Backspace:127,CapsLock:57358,ScrollLock:57359,NumLock:57360,PrintScreen:57361,Pause:57362,ContextMenu:57363,F13:57376,F14:57377,F15:57378,F16:57379,F17:57380,F18:57381,F19:57382,F20:57383,F21:57384,F22:57385,F23:57386,F24:57387,F25:57388,KP_0:57399,KP_1:57400,KP_2:57401,KP_3:57402,KP_4:57403,KP_5:57404,KP_6:57405,KP_7:57406,KP_8:57407,KP_9:57408,KP_Decimal:57409,KP_Divide:57410,KP_Multiply:57411,KP_Subtract:57412,KP_Add:57413,KP_Enter:57414,KP_Equal:57415,ShiftLeft:57441,ShiftRight:57447,ControlLeft:57442,ControlRight:57448,AltLeft:57443,AltRight:57449,MetaLeft:57444,MetaRight:57450,MediaPlayPause:57430,MediaStop:57432,MediaTrackNext:57435,MediaTrackPrevious:57436,AudioVolumeDown:57438,AudioVolumeUp:57439,AudioVolumeMute:57440},this._csiTildeKeys={Insert:2,Delete:3,PageUp:5,PageDown:6,F5:15,F6:17,F7:18,F8:19,F9:20,F10:21,F11:23,F12:24},this._csiLetterKeys={ArrowUp:"A",ArrowDown:"B",ArrowRight:"C",ArrowLeft:"D",Home:"H",End:"F"},this._ss3FunctionKeys={F1:"P",F2:"Q",F3:"R",F4:"S"}}_getNumpadKeyCode(e){if(e.code.startsWith("Numpad")){const t=e.code.slice(6);if(t>="0"&&t<="9")return 57399+parseInt(t,10);switch(t){case"Decimal":return 57409;case"Divide":return 57410;case"Multiply":return 57411;case"Subtract":return 57412;case"Add":return 57413;case"Enter":return 57414;case"Equal":return 57415}}}_getModifierKeyCode(e){switch(e.code){case"ShiftLeft":return 57441;case"ShiftRight":return 57447;case"ControlLeft":return 57442;case"ControlRight":return 57448;case"AltLeft":return 57443;case"AltRight":return 57449;case"MetaLeft":return 57444;case"MetaRight":return 57450}}_encodeModifiers(e){let t=0;return e.shiftKey&&(t|=1),e.altKey&&(t|=2),e.ctrlKey&&(t|=4),e.metaKey&&(t|=8),t>0?t+1:0}_getKeyCode(e,t){const i=this._getNumpadKeyCode(e);if(void 0!==i)return i;const s=this._getModifierKeyCode(e);if(void 0!==s)return s;const r=this._functionalKeyCodes[e.key];if(void 0!==r)return r;if((e.shiftKey||t&&e.altKey)&&e.code){if(e.code.startsWith("Digit")&&6===e.code.length){const t=e.code.charAt(5);if(t>="0"&&t<="9")return t.charCodeAt(0)}if(e.code.startsWith("Key")&&4===e.code.length)return e.code.charAt(3).toLowerCase().charCodeAt(0)}if(1===e.key.length){const t=e.key.codePointAt(0);return t>=65&&t<=90?t+32:t}}_isModifierKey(e){return"Shift"===e.key||"Control"===e.key||"Alt"===e.key||"Meta"===e.key}_isLockKey(e){return"CapsLock"===e.key||"NumLock"===e.key||"ScrollLock"===e.key}_buildCsiLetterSequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"["+e}_buildSs3Sequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"O"+e}_buildCsiTildeSequence(e,t,i,s){const r=s&&1!==i;let o="["+e;return(t>0||r)&&(o+=";"+(t>0?t:"1"),r&&(o+=":"+i)),o+="~",o}_buildCsiUSequence(e,t,i,s,r,o,n){const a=!!(2&r);let h,l="["+t;4&r&&e.shiftKey&&1===e.key.length&&!o&&!n&&(h=e.key.codePointAt(0),l+=":"+h);const c=16&r&&3!==s&&1===e.key.length&&!o&&!n&&!e.ctrlKey?e.key.codePointAt(0):void 0,d=a&&1!==s&&(3===s||void 0===c);return(i>0||d||void 0!==c)&&(l+=";",i>0?l+=i:d&&(l+="1"),d&&(l+=":"+s)),void 0!==c&&(l+=";"+c),l+="u",l}evaluate(e,t,i=1,s=!1){const r={type:0,cancel:!1,key:void 0},o=this._encodeModifiers(e),n=this._isModifierKey(e),a=!!(2&t);if(!a&&3===i)return r;if(n&&!(8&t))return r;if(this._isLockKey(e)&&!(8&t))return r;const h=this._csiLetterKeys[e.key];if(h)return r.key=this._buildCsiLetterSequence(h,o,i,a),r.cancel=!0,r;const l=this._ss3FunctionKeys[e.key];if(l)return r.key=this._buildSs3Sequence(l,o,i,a),r.cancel=!0,r;const c=this._csiTildeKeys[e.key];if(void 0!==c)return r.key=this._buildCsiTildeSequence(c,o,i,a),r.cancel=!0,r;const d=this._getKeyCode(e,s);if(void 0===d)return r;const _=13===d||9===d||127===d;if(_&&3===i&&!(8&t))return r;const u=void 0!==this._functionalKeyCodes[e.key]||void 0!==this._getNumpadKeyCode(e);if(8&t||a&&3===i||(1&t||a)&&(u&&!_||o>0&&1!==e.key.length||o-1>1))r.key=this._buildCsiUSequence(e,d,o,i,t,u,n),r.cancel=!0;else{const t=13===d?"\r":9===d?"\t":127===d?"":void 0;t?r.key=t:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||(r.key=e.key)}return r}static shouldUseProtocol(e){return e>0}}},726(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Utf8ToUtf32=t.StringToUtf32=void 0,t.stringFromCodePoint=function(e){return e>65535?(e-=65536,String.fromCharCode(55296+(e>>10))+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)},t.utf32ToString=function(e,t=0,i=e.length){let s="";for(let r=t;r65535?(t-=65536,s+=String.fromCharCode(55296+(t>>10))+String.fromCharCode(t%1024+56320)):s+=String.fromCharCode(t)}return s},t.StringToUtf32=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){const i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){const i=e.charCodeAt(r++);56320<=i&&i<=57343?t[s++]=1024*(this._interim-55296)+i-56320+65536:(t[s++]=this._interim,t[s++]=i),this._interim=0}for(let o=r;o=i)return this._interim=r,s;const n=e.charCodeAt(o);56320<=n&&n<=57343?t[s++]=1024*(r-55296)+n-56320+65536:(t[s++]=r,t[s++]=n);continue}65279!==r&&(t[s++]=r)}return s}},t.Utf8ToUtf32=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){const i=e.length;if(!i)return 0;let s,r,o,n,a,h=0,l=0;if(this.interim[0]){let s=!1,r=this.interim[0];r&=192==(224&r)?31:224==(240&r)?15:7;let o,n=0;for(;(o=this.interim[++n])&&n<4;)r<<=6,r|=63&o;const a=192==(224&this.interim[0])?2:224==(240&this.interim[0])?3:4,c=a-n;for(;l=i)return 0;if(o=e[l++],128!=(192&o)){l--,s=!0;break}this.interim[n++]=o,r<<=6,r|=63&o}s||(2===a?r<128?l--:t[h++]=r:3===a?r<2048||r>=55296&&r<=57343||65279===r||(t[h++]=r):r<65536||r>1114111||(t[h++]=r)),this.interim.fill(0)}const c=i-4;let d=l;for(;d=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(a=(31&s)<<6|63&r,a<128){d--;continue}t[h++]=a}else if(224==(240&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(a=(15&s)<<12|(63&r)<<6|63&o,a<2048||a>=55296&&a<=57343||65279===a)continue;t[h++]=a}else if(240==(248&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,this.interim[2]=o,h;if(n=e[d++],128!=(192&n)){d--;continue}if(a=(7&s)<<18|(63&r)<<12|(63&o)<<6|63&n,a<65536||a>1114111)continue;t[h++]=a}}return h}}},7428(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeV6=void 0;const s=i(6415),r=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],o=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]];let n;t.UnicodeV6=class{constructor(){if(this.version="6",!n){n=new Uint8Array(65536),n.fill(1),n[0]=0,n.fill(0,1,32),n.fill(0,127,160),n.fill(2,4352,4448),n[9001]=2,n[9002]=2,n.fill(2,11904,42192),n[12351]=1,n.fill(2,44032,55204),n.fill(2,63744,64256),n.fill(2,65040,65050),n.fill(2,65072,65136),n.fill(2,65280,65377),n.fill(2,65504,65511);for(let e=0;et[r][1])return!1;for(;r>=s;)if(i=s+r>>1,e>t[i][1])s=i+1;else{if(!(e=131072&&e<=196605||e>=196608&&e<=262141?2:1}charProperties(e,t){let i=this.wcwidth(e),r=0===i&&0!==t;if(r){const e=s.UnicodeService.extractWidth(t);0===e?r=!1:e>i&&(i=e)}return s.UnicodeService.createPropertyValue(0,i,r)}}},9249(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Win32InputMode=void 0,t.Win32InputMode=class{constructor(){this._codeToVk={KeyA:65,KeyB:66,KeyC:67,KeyD:68,KeyE:69,KeyF:70,KeyG:71,KeyH:72,KeyI:73,KeyJ:74,KeyK:75,KeyL:76,KeyM:77,KeyN:78,KeyO:79,KeyP:80,KeyQ:81,KeyR:82,KeyS:83,KeyT:84,KeyU:85,KeyV:86,KeyW:87,KeyX:88,KeyY:89,KeyZ:90,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,F16:127,F17:128,F18:129,F19:130,F20:131,F21:132,F22:133,F23:134,F24:135,Numpad0:96,Numpad1:97,Numpad2:98,Numpad3:99,Numpad4:100,Numpad5:101,Numpad6:102,Numpad7:103,Numpad8:104,Numpad9:105,NumpadMultiply:106,NumpadAdd:107,NumpadSeparator:108,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,NumLock:144,ArrowUp:38,ArrowDown:40,ArrowLeft:37,ArrowRight:39,Home:36,End:35,PageUp:33,PageDown:34,Insert:45,Delete:46,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,CapsLock:20,ScrollLock:145,Escape:27,Enter:13,Tab:9,Space:32,Backspace:8,Pause:19,ContextMenu:93,PrintScreen:44,Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,IntlBackslash:226},this._codeToScancode={KeyQ:16,KeyW:17,KeyE:18,KeyR:19,KeyT:20,KeyY:21,KeyU:22,KeyI:23,KeyO:24,KeyP:25,KeyA:30,KeyS:31,KeyD:32,KeyF:33,KeyG:34,KeyH:35,KeyJ:36,KeyK:37,KeyL:38,KeyZ:44,KeyX:45,KeyC:46,KeyV:47,KeyB:48,KeyN:49,KeyM:50,Digit1:2,Digit2:3,Digit3:4,Digit4:5,Digit5:6,Digit6:7,Digit7:8,Digit8:9,Digit9:10,Digit0:11,F1:59,F2:60,F3:61,F4:62,F5:63,F6:64,F7:65,F8:66,F9:67,F10:68,F11:87,F12:88,Numpad0:82,Numpad1:79,Numpad2:80,Numpad3:81,Numpad4:75,Numpad5:76,Numpad6:77,Numpad7:71,Numpad8:72,Numpad9:73,NumpadMultiply:55,NumpadAdd:78,NumpadSubtract:74,NumpadDecimal:83,NumpadDivide:53,NumpadEnter:28,NumLock:69,ArrowUp:72,ArrowDown:80,ArrowLeft:75,ArrowRight:77,Home:71,End:79,PageUp:73,PageDown:81,Insert:82,Delete:83,ShiftLeft:42,ShiftRight:54,ControlLeft:29,ControlRight:29,AltLeft:56,AltRight:56,CapsLock:58,ScrollLock:70,Escape:1,Enter:28,Tab:15,Space:57,Backspace:14,Pause:69,Semicolon:39,Equal:13,Comma:51,Minus:12,Period:52,Slash:53,Backquote:41,BracketLeft:26,Backslash:43,BracketRight:27,Quote:40},this._enhancedKeyCodes=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Insert","Delete","NumpadEnter","NumpadDivide","ControlRight","AltRight","PrintScreen","Pause","ContextMenu","MetaLeft","MetaRight"]),this._keyToControlChar={Enter:13,Backspace:8,Tab:9,Escape:27}}_getVirtualKeyCode(e){const t=this._codeToVk[e.code];return void 0!==t?t:e.keyCode||0}_getScanCode(e){return this._codeToScancode[e.code]||0}_getUnicodeChar(e){if(e.ctrlKey&&!e.altKey&&!e.metaKey){if("Enter"===e.key)return 10;if("Backspace"===e.key)return 127}const t=this._keyToControlChar[e.key];if(void 0!==t)return t;if(1===e.key.length){const t=e.key.codePointAt(0)||0;if(e.ctrlKey&&!e.altKey&&!e.metaKey){if(t>=65&&t<=90)return t-64;if(t>=97&&t<=122)return t-96}return t}return 0}_getControlKeyState(e){let t=0;return e.shiftKey&&(t|=16),e.ctrlKey&&("ControlRight"===e.code?t|=4:t|=8),e.altKey&&("AltRight"===e.code?t|=1:t|=2),this._enhancedKeyCodes.has(e.code)&&(t|=256),t}evaluateKeyboardEvent(e,t){return{type:0,cancel:!0,key:`[${this._getVirtualKeyCode(e)};${this._getScanCode(e)};${this._getUnicodeChar(e)};${t?1:0};${this._getControlKeyState(e)};1_`}}}},3562(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WriteBuffer=void 0;const s=i(3132),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._action=e,this._writeBuffer=[],this._callbacks=[],this._pendingData=0,this._bufferOffset=0,this._isSyncWriting=!1,this._syncCalls=0,this._didUserInput=!1,this._innerWriteTimer=this._register(new s.TimeoutTimer),this._onWriteParsed=this._register(new o.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._register((0,r.toDisposable)(()=>{this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0}))}handleUserInput(){this._didUserInput=!0}flushSync(){if(this._store.isDisposed)return;if(this._isSyncWriting)return;let e;this._isSyncWriting=!0;let t=!1;for(;e=this._writeBuffer.shift();){t=!0,this._action(e);const i=this._callbacks.shift();i&&i()}this._pendingData=0,this._bufferOffset=2147483647,this._writeBuffer.length=0,this._callbacks.length=0,this._isSyncWriting=!1,t&&this._onWriteParsed.fire()}writeSync(e,t){if(this._store.isDisposed)return;if(void 0!==t&&this._syncCalls>t)return void(this._syncCalls=0);if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;let i;for(this._isSyncWriting=!0;i=this._writeBuffer.shift();){this._action(i);const e=this._callbacks.shift();e&&e()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(!this._store.isDisposed){if(this._pendingData>5e7)throw new Error("write data discarded, use flow control to avoid losing data");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput)return this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),void this._innerWrite();this._scheduleInnerWrite()}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}}_scheduleInnerWrite(e=0,t=!0){this._store.isDisposed||this._innerWriteTimer.cancelAndSet(()=>this._innerWrite(e,t),0)}_innerWrite(e=0,t=!0){if(this._store.isDisposed)return;const i=e||performance.now();for(;this._writeBuffer.length>this._bufferOffset;){const e=this._writeBuffer[this._bufferOffset],s=this._action(e,t);if(s){const e=e=>{this._store.isDisposed||(performance.now()-i>=12?this._scheduleInnerWrite(0,e):this._innerWrite(i,e))};return void s.catch(e=>(queueMicrotask(()=>{throw e}),Promise.resolve(!1))).then(e)}const r=this._callbacks[this._bufferOffset];if(r&&r(),this._bufferOffset++,this._pendingData-=e.length,performance.now()-i>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),this._scheduleInnerWrite()):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}}t.WriteBuffer=n},8693(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.parseColor=function(e){if(!e)return;let t=e.toLowerCase();if(t.startsWith("rgb:")){t=t.slice(4);const e=i.exec(t);if(e){const t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(t.startsWith("#")&&(t=t.slice(1),s.exec(t)&&[3,6,9,12].includes(t.length))){const e=t.length/3,i=[0,0,0];for(let s=0;s<3;++s){const r=parseInt(t.slice(e*s,e*s+e),16);i[s]=1===e?r<<4:2===e?r:3===e?r>>4:r>>8}return i}},t.toRgbString=function(e,t=16){const[i,s,o]=e;return`rgb:${r(i,t)}/${r(s,t)}/${r(o,t)}`};const i=/^([\da-f])\/([\da-f])\/([\da-f])$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/,s=/^[\da-f]+$/;function r(e,t){const i=e.toString(16),s=i.length<2?"0"+i:i;switch(t){case 4:return i[0];case 8:return s;case 12:return(s+s).slice(0,3);default:return s+s}}},2607(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.ApcHandler=t.ApcParser=void 0;const s=i(726),r=i(4220),o=[];t.ApcParser=class{constructor(){this._handlers=Object.create(null),this._active=o,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._ident=0}start(e){if(this.reset(),this._ident=e,this._active=this._handlers[e]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._ident,"START")}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}end(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"END",e);this._active=o,this._ident=0}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.ApcHandler=n,n._payloadLimit=1e7},9823(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DcsHandler=t.DcsParser=void 0;const s=i(726),r=i(7262),o=i(4220),n=[];t.DcsParser=class{constructor(){this._handlers=Object.create(null),this._active=n,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=n}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].unhook(!1);this._stack.paused=!1,this._active=n,this._ident=0}hook(e,t){if(this.reset(),this._ident=e,this._active=this._handlers[e]||n,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].hook(t);else this._handlerFb(this._ident,"HOOK",t)}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}unhook(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].unhook(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].unhook(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"UNHOOK",e);this._active=n,this._ident=0}};const a=new r.Params;a.addParam(0);class h{constructor(e){this._handler=e,this._data=new o.LimitedStringBuilder(h._payloadLimit),this._params=a,this._hitLimit=!1}hook(e){this._params=e.length>1||e.params[0]?e.clone():a,this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}unhook(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString(),this._params),t instanceof Promise))return t.then(e=>(this._params=a,this._data.reset(),this._hitLimit=!1,e));return this._params=a,this._data.reset(),this._hitLimit=!1,t}}t.DcsHandler=h,h._payloadLimit=1e7},6717(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EscapeSequenceParser=t.VT500_TRANSITION_TABLE=t.TransitionTable=void 0;const s=i(4812),r=i(7262),o=i(1346),n=i(9823),a=i(2607);class h{constructor(e){this.table=new Uint16Array(e)}setDefault(e,t){this.table.fill(e<<8|t)}add(e,t,i,s){this.table[t<<8|e]=i<<8|s}addMany(e,t,i,s){for(let r=0;rt),i=(e,i)=>t.slice(e,i),s=i(32,127),r=i(0,24);r.push(25),r.push.apply(r,i(28,32));const o=i(0,17);e.setDefault(1,0),e.addMany(s,0,2,0);for(const t of o)e.addMany([24,26,153,154],t,3,0),e.addMany(i(128,144),t,3,0),e.addMany(i(144,152),t,3,0),e.add(156,t,0,0),e.add(27,t,11,1),e.add(157,t,4,8),e.addMany([152,158],t,0,7),e.add(159,t,11,14),e.add(155,t,11,3),e.add(144,t,11,9);return e.addMany(r,0,3,0),e.addMany(r,1,3,1),e.add(127,1,0,1),e.addMany(r,8,0,8),e.addMany(r,3,3,3),e.add(127,3,0,3),e.addMany(r,4,3,4),e.add(127,4,0,4),e.addMany(r,6,3,6),e.addMany(r,5,3,5),e.add(127,5,0,5),e.addMany(r,2,3,2),e.add(127,2,0,2),e.add(93,1,4,8),e.addMany(s,8,5,8),e.add(127,8,5,8),e.addMany([156,27,24,26,7],8,6,0),e.addMany(i(28,32),8,0,8),e.addMany([88,94],1,0,7),e.addMany(s,7,0,7),e.addMany(r,7,0,7),e.add(156,7,0,0),e.add(127,7,0,7),e.add(95,1,11,14),e.addMany(r,14,0,14),e.add(127,14,0,14),e.addMany(i(32,48),14,9,15),e.addMany(i(48,127),14,15,16),e.addMany(i(48,127),15,15,16),e.addMany(r,15,0,15),e.addMany(i(32,48),15,9,15),e.add(127,15,0,15),e.addMany(s,16,16,16),e.addMany(r,16,0,16),e.addMany(i(8,14),16,16,16),e.add(127,16,0,16),e.addMany([27,156,24,26],16,17,0),e.add(91,1,11,3),e.addMany(i(64,127),3,7,0),e.addMany(i(48,60),3,8,4),e.addMany([60,61,62,63],3,9,4),e.addMany(i(48,60),4,8,4),e.addMany(i(64,127),4,7,0),e.addMany([60,61,62,63],4,0,6),e.addMany(i(32,64),6,0,6),e.add(127,6,0,6),e.addMany(i(64,127),6,0,0),e.addMany(i(32,48),3,9,5),e.addMany(i(32,48),5,9,5),e.addMany(i(48,64),5,0,6),e.addMany(i(64,127),5,7,0),e.addMany(i(32,48),4,9,5),e.addMany(i(32,48),1,9,2),e.addMany(i(32,48),2,9,2),e.addMany(i(48,127),2,10,0),e.addMany(i(48,80),1,10,0),e.addMany(i(81,88),1,10,0),e.addMany([89,90,92],1,10,0),e.addMany(i(96,127),1,10,0),e.add(80,1,11,9),e.addMany(r,9,0,9),e.add(127,9,0,9),e.addMany(i(32,48),9,9,12),e.addMany(i(48,60),9,8,10),e.addMany([60,61,62,63],9,9,10),e.addMany(r,11,0,11),e.addMany(i(32,128),11,0,11),e.addMany(r,10,0,10),e.add(127,10,0,10),e.addMany(i(48,60),10,8,10),e.addMany([60,61,62,63],10,0,11),e.addMany(i(32,48),10,9,12),e.addMany(r,12,0,12),e.add(127,12,0,12),e.addMany(i(32,48),12,9,12),e.addMany(i(48,64),12,0,11),e.addMany(i(64,127),12,12,13),e.addMany(i(64,127),10,12,13),e.addMany(i(64,127),9,12,13),e.addMany(r,13,13,13),e.addMany(s,13,13,13),e.add(127,13,0,13),e.addMany([27,156,24,26],13,14,0),e.add(l,0,2,0),e.add(l,8,5,8),e.add(l,6,0,6),e.add(l,11,0,11),e.add(l,13,13,13),e.add(l,16,16,16),e}();class c extends s.Disposable{constructor(e=t.VT500_TRANSITION_TABLE){super(),this._transitions=e,this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0},this.initialState=0,this.currentState=this.initialState,this._params=new r.Params,this._params.addParam(0),this._collect=0,this.precedingJoinState=0,this._printHandlerFb=(e,t,i)=>{},this._executeHandlerFb=e=>{},this._csiHandlerFb=(e,t)=>{},this._escHandlerFb=e=>{},this._errorHandlerFb=e=>e,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this._register((0,s.toDisposable)(()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._escHandlers=Object.create(null)})),this._oscParser=this._register(new o.OscParser),this._dcsParser=this._register(new n.DcsParser),this._apcParser=this._register(new a.ApcParser),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:"\\"},()=>!0)}_identifier(e,t=[64,126]){let i=0;if(e.prefix){if(e.prefix.length>1)throw new Error("only one byte as prefix supported");if(i=e.prefix.charCodeAt(0),i<60||i>63)throw new Error("prefix must be in range 0x3c .. 0x3f")}if(e.intermediates){if(e.intermediates.length>2)throw new Error("only two bytes as intermediates are supported");for(let t=0;ts||s>47)throw new Error("intermediate must be in range 0x20 .. 0x2f");i<<=8,i|=s}}if(1!==e.final.length)throw new Error("final must be a single byte");const s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return i<<=8,i|=s,i}identToString(e){const t=[];for(;e;)t.push(String.fromCharCode(255&e)),e>>=8;return t.reverse().join("")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){const i=this._identifier(e,[48,126]);this._escHandlers[i]??=[];const s=this._escHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){const i=e.charCodeAt(0);this._executeHandlers[i]=t,i<24&&(this._executeHandlersArr[i]=t)}clearExecuteHandler(e){const t=e.charCodeAt(0);this._executeHandlers[t]&&delete this._executeHandlers[t],t<24&&(this._executeHandlersArr[t]=void 0)}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){const i=this._identifier(e);this._csiHandlers[i]??=[];const s=this._csiHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}registerApcHandler(e,t){return e.prefix=void 0,this._apcParser.registerHandler(this._identifier(e,[48,126]),t)}clearApcHandler(e){e.prefix=void 0,this._apcParser.clearHandler(this._identifier(e,[48,126]))}setApcHandlerFallback(e){this._apcParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._apcParser.reset(),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0,0!==this._parseStack.state&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,i,s,r){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=i,this._parseStack.transition=s,this._parseStack.chunkPos=r}parse(e,t,i){let s,r,o,n=0;if(this._parseStack.state)if(2===this._parseStack.state)this._parseStack.state=0,n=this._parseStack.chunkPos+1;else{if(void 0===i||1===this._parseStack.state)throw this._parseStack.state=1,new Error("improper continuation due to previous async handler, giving up parsing");const t=this._parseStack.handlers;let r=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](this._params),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 4:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 6:if(s=e[this._parseStack.chunkPos],o=this._dcsParser.unhook(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 5:if(s=e[this._parseStack.chunkPos],o=this._oscParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 7:if(s=e[this._parseStack.chunkPos],o=this._apcParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0}this._parseStack.state=0,n=this._parseStack.chunkPos+1,this.precedingJoinState=0,this.currentState=255&this._parseStack.transition}for(let i=n;i=60&&n<=63&&(this._collect=n,s++);let a=!1;for(;s=48&&n<=57)this._params.addDigit(n-48);else if(59===n)this._params.addParam(0);else{if(58!==n){if(n>=64&&n<=126){const e=this._csiHandlers[this._collect<<8|n];let t=e?e.length-1:-1;for(;t>=0&&(o=e[t](this._params),!0!==o);t--)if(o instanceof Promise)return r=1792,this._preserveStack(3,e,t,r,s),o;t<0&&this._csiHandlerFb(this._collect<<8|n,this._params),this.precedingJoinState=0,i=s,this.currentState=0,a=!0;break}break}this._params.addSubParam(-1)}a||(i=s-1,this.currentState=4);continue}switch(r=this._transitions.table[this.currentState<<8|(s>8){case 2:let n=i;const a=t-4;for(;n=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l););if(n>=a)for(;n=32&&(e[n]<=126||e[n]>=l);)n++;this._printHandler(e,i,n),i=n-1;break;case 3:this._executeHandlers[s]?this._executeHandlers[s]():this._executeHandlerFb(s),this.precedingJoinState=0;break;case 0:break;case 1:if(this._errorHandler({position:i,code:s,currentState:this.currentState,collect:this._collect,params:this._params,abort:!1}).abort)return;break;case 7:const h=this._csiHandlers[this._collect<<8|s];let c=h?h.length-1:-1;for(;c>=0&&(o=h[c](this._params),!0!==o);c--)if(o instanceof Promise)return this._preserveStack(3,h,c,r,i),o;c<0&&this._csiHandlerFb(this._collect<<8|s,this._params),this.precedingJoinState=0;break;case 8:do{switch(s){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(s-48)}}while(++i47&&s<60);i--;break;case 9:this._collect<<=8,this._collect|=s;break;case 10:const d=this._escHandlers[this._collect<<8|s];let _=d?d.length-1:-1;for(;_>=0&&(o=d[_](),!0!==o);_--)if(o instanceof Promise)return this._preserveStack(4,d,_,r,i),o;_<0&&this._escHandlerFb(this._collect<<8|s),this.precedingJoinState=0;break;case 11:this._params.resetZdm(),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|s,this._params);break;case 13:for(let r=i+1;;++r)if(r>=t||24===(s=e[r])||26===s||27===s||s>127&&s=t||(s=e[r])<32||s>127&&s=32&&e[s]<127||e[s]>=8&&e[s]<14||e[s]>=l))){this._apcParser.put(e,i,s),i=s-1;break}break;case 17:if(o=this._apcParser.end(24!==s&&26!==s),o)return this._preserveStack(7,[],0,r,i),o;27===s&&(r|=1),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0}this.currentState=255&r}}}t.EscapeSequenceParser=c},1346(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OscHandler=t.OscParser=void 0;const s=i(726),r=i(4220),o=[];t.OscParser=class{constructor(){this._state=0,this._active=o,this._id=-1,this._handlers=Object.create(null),this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(2===this._state)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._id,"START")}_put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._id,"PUT",(0,s.utf32ToString)(e,t,i))}start(){this.reset(),this._state=1}put(e,t,i){if(3!==this._state){if(1===this._state)for(;t0&&this._put(e,t,i)}}end(e,t=!0){if(0!==this._state){if(3!==this._state)if(1===this._state&&this._start(),this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._id,"END",e);this._active=o,this._id=-1,this._state=0}}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.OscHandler=n,n._payloadLimit=1e7},7262(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Params=void 0;class i{static fromArray(e){const t=new i;if(!e.length)return t;for(let i=Array.isArray(e[0])?1:0;i256)throw new Error("maxSubParamsLength must not be greater than 256");this.params=new Int32Array(e),this.length=0,this._subParams=new Int32Array(t),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(e),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}clone(){const e=new i(this.maxLength,this.maxSubParamsLength);return e.params.set(this.params),e.length=this.length,e._subParams.set(this._subParams),e._subParamsLength=this._subParamsLength,e._subParamsIdx.set(this._subParamsIdx),e._rejectDigits=this._rejectDigits,e._rejectSubDigits=this._rejectSubDigits,e._digitIsSub=this._digitIsSub,e}toArray(){const e=[];for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&e.push(Array.prototype.slice.call(this._subParams,i,s))}return e}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}resetZdm(){this.length=1,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1,this._subParamsIdx[0]=0,this.params[0]=0}addParam(e){if(this._digitIsSub=!1,this.length>=this.maxLength)this._rejectDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=e>2147483647?2147483647:e}}addSubParam(e){if(this._digitIsSub=!0,this.length)if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength)this._rejectSubDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParams[this._subParamsLength++]=e>2147483647?2147483647:e,this._subParamsIdx[this.length-1]++}}hasSubParams(e){return(255&this._subParamsIdx[e])-(this._subParamsIdx[e]>>8)>0}getSubParams(e){const t=this._subParamsIdx[e]>>8,i=255&this._subParamsIdx[e];return i-t>0?this._subParams.subarray(t,i):null}getSubParamsAll(){const e={};for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&(e[t]=this._subParams.slice(i,s))}return e}addDigit(e){let t;if(this._rejectDigits||!(t=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;const i=this._digitIsSub?this._subParams:this.params,s=i[t-1];i[t-1]=~s?Math.min(10*s+e,2147483647):e}}t.Params=i},3027(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.AddonManager=void 0,t.AddonManager=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){const i={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(i),t.dispose=()=>this._wrappedAddonDispose(i),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let i=0;i=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new s.CellData)}translateToString(e,t,i){return this._line.translateToString(e,t,i)}}},5101(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferNamespaceApi=void 0;const s=i(3235),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._core=e,this._onBufferChange=this._register(new o.Emitter),this.onBufferChange=this._onBufferChange.event,this._normal=new s.BufferApiView(this._core.buffers.normal,"normal"),this._alternate=new s.BufferApiView(this._core.buffers.alt,"alternate"),this._register(this._core.buffers.onBufferActivate(()=>this._onBufferChange.fire(this.active)))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw new Error("Active buffer is neither normal nor alternate")}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}}t.BufferNamespaceApi=n},6097(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ParserApi=void 0,t.ParserApi=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,e=>t(e.toArray()))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,(e,i)=>t(e,i.toArray()))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}registerApcHandler(e,t){return this._core.registerApcHandler(e,t)}}},4335(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeApi=void 0,t.UnicodeApi=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}}},9640(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferService=void 0;const o=i(4812),n=i(4097),a=i(6501),h=i(8636);let l=class extends o.Disposable{get buffer(){return this.buffers.active}constructor(e,t){super(),this.isUserScrolling=!1,this._onResize=this._register(new h.Emitter),this.onResize=this._onResize.event,this._onScroll=this._register(new h.Emitter),this.onScroll=this._onScroll.event,this.cols=Math.max(e.rawOptions.cols||0,2),this.rows=Math.max(e.rawOptions.rows||0,1),this.buffers=this._register(new n.BufferSet(e,this,t)),this._register(this.buffers.onBufferActivate(e=>{this._onScroll.fire(e.activeBuffer.ydisp)}))}resize(e,t){const i=this.cols!==e,s=this.rows!==t;this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t,colsChanged:i,rowsChanged:s})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){const i=this.buffer;let s;s=this._cachedBlankLine,s&&s.length===this.cols&&s.getFg(0)===e.fg&&s.getBg(0)===e.bg||(s=i.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;const r=i.ybase+i.scrollTop,o=i.ybase+i.scrollBottom;if(0===i.scrollTop){const e=i.lines.isFull;o===i.lines.length-1?e?i.lines.recycle().copyFrom(s):i.lines.push(s.clone()):i.lines.splice(o+1,0,s.clone()),e?this.isUserScrolling&&(i.ydisp=Math.max(i.ydisp-1,0)):(i.ybase++,this.isUserScrolling||i.ydisp++)}else{const e=o-r+1;i.lines.shiftElements(r+1,e-1,-1),i.lines.set(o,s.clone())}this.isUserScrolling||(i.ydisp=i.ybase),this._onScroll.fire(i.ydisp)}scrollLines(e,t){const i=this.buffer;if(e<0){if(0===i.ydisp)return;this.isUserScrolling=!0}else e+i.ydisp>=i.ybase&&(this.isUserScrolling=!1);const s=i.ydisp;i.ydisp=Math.max(Math.min(i.ydisp+e,i.ybase),0),s!==i.ydisp&&(t||this._onScroll.fire(i.ydisp))}};t.BufferService=l,t.BufferService=l=s([r(0,a.IOptionsService),r(1,a.ILogService)],l)},5746(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.CharsetService=void 0,t.CharsetService=class{constructor(){this.glevel=0,this._charsets=[]}get charsets(){return this._charsets}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(e){this.glevel=e,this.charset=this._charsets[e]}setgCharset(e,t){this._charsets[e]=t,this.glevel===e&&(this.charset=t)}}},4071(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CoreService=void 0;const o=i(4812),n=i(6501),a=i(8636),h=Object.freeze({insertMode:!1}),l=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,colorSchemeUpdates:!1,cursorBlink:void 0,cursorStyle:void 0,origin:!1,reverseWraparound:!1,sendFocus:!1,synchronizedOutput:!1,win32InputMode:!1,wraparound:!0});let c=class extends o.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._logService=t,this._optionsService=i,this.isCursorHidden=!1,this._onData=this._register(new a.Emitter),this.onData=this._onData.event,this._onUserInput=this._register(new a.Emitter),this.onUserInput=this._onUserInput.event,this._onBinary=this._register(new a.Emitter),this.onBinary=this._onBinary.event,this._onRequestScrollToBottom=this._register(new a.Emitter),this.onRequestScrollToBottom=this._onRequestScrollToBottom.event,this.isCursorInitialized=i.rawOptions.showCursorImmediately??!1,this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}reset(){this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;const i=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&i.ybase!==i.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data "${e}"`),this._logService.trace("sending data (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary "${e}"`),this._logService.trace("sending binary (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onBinary.fire(e))}};t.CoreService=c,t.CoreService=c=s([r(0,n.IBufferService),r(1,n.ILogService),r(2,n.IOptionsService)],c)},4720(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationLineCache=t.DecorationService=void 0;const o=i(3132),n=i(4103),a=i(4812),h=i(6501),l=i(3087),c=i(8636);let d=0,_=0,u=class extends a.Disposable{get decorations(){return this._decorations.values()}constructor(e,t){super(),this._logService=e,this._bufferService=t,this._lineCache=this._register(new f),this._onDecorationRegistered=this._register(new c.Emitter),this.onDecorationRegistered=this._onDecorationRegistered.event,this._onDecorationRemoved=this._register(new c.Emitter),this.onDecorationRemoved=this._onDecorationRemoved.event,this._decorations=new l.SortedList(e=>e?.marker.line,this._logService),this._register((0,a.toDisposable)(()=>this.reset())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)})),this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)}registerDecoration(e){if(e.marker.isDisposed)return;const t=new p(e);if(t){const e=t.marker.onDispose(()=>t.dispose()),i=t.onDispose(()=>{i.dispose(),t&&(this._decorations.delete(t)&&(this._lineCache.remove(t),this._onDecorationRemoved.fire(t)),e.dispose())});this._decorations.insert(t),this._lineCache.add(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(const e of this._decorations.values())e.dispose();this._decorations.clear(),this._lineCache.clear()}*getDecorationsAtCell(e,t,i){const s=this._lineCache.getDecorationsOnLine(t);if(s)for(const t of s)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&(yield t)}forEachDecorationAtCell(e,t,i,s){const r=this._lineCache.getDecorationsOnLine(t);if(r)for(const t of r)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&s(t)}};t.DecorationService=u,t.DecorationService=u=s([r(0,h.ILogService),r(1,h.IBufferService)],u);class f extends a.Disposable{constructor(){super(...arguments),this._decorationsByLine=new Map,this._decorations=new Set,this._bufferLineListeners=this._register(new a.MutableDisposable),this._lineIndexSyncTimer=this._register(new o.MicrotaskTimer),this._lineIndexSyncCallbacks=[]}clear(){this._lineIndexSyncCallbacks.length=0,this._lineIndexSyncTimer.cancel(),this._decorationsByLine.clear(),this._decorations.clear()}add(e){this._decorations.add(e),this._addToLineBuckets(e)}remove(e){this._decorations.delete(e),this._removeFromLineBuckets(e)}getDecorationsOnLine(e){return this._decorationsByLine.get(e)}attachToBufferLines(e){const t=new a.DisposableStore;this._bufferLineListeners.value=t,t.add(e.onTrim(e=>this._handleBufferLinesTrim(e))),t.add(e.onInsert(e=>this._handleBufferLinesInsert(e))),t.add(e.onDelete(e=>this._handleBufferLinesDelete(e)))}_getDecorationHeight(e){return e.options.height??1}_addToLineBuckets(e){const t=e.marker.line;if(t<0)return;e._indexedStartLine=t;const i=this._getDecorationHeight(e);for(let s=t;s=0&&this._addToLineBuckets(e)}_scheduleLineIndexSync(e){this._lineIndexSyncCallbacks.push(e),this._lineIndexSyncTimer.set(()=>{const e=this._lineIndexSyncCallbacks;this._lineIndexSyncCallbacks=[];for(const t of e)t()})}_handleBufferLinesTrim(e){if(e<=0)return;const t=new Map;for(const[i,s]of this._decorationsByLine){const r=i-e;r<0||this._mergeLineBucket(t,r,s)}this._decorationsByLine.clear();for(const[e,i]of t)this._decorationsByLine.set(e,i);for(const t of this._decorations)t.marker.isDisposed||(t._indexedStartLine-=e)}_handleBufferLinesInsert(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesInsert(e))}_handleBufferLinesDelete(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesDelete(e))}_mergeLineBucket(e,t,i){const s=e.get(t);if(s)for(let e=0,t=i.length;et&&(s.push(e),this._removeFromLineBuckets(e))}const r=new Map;for(const[e,s]of this._decorationsByLine){const o=e>=t?e+i:e;this._mergeLineBucket(r,o,s)}this._decorationsByLine.clear();for(const[e,t]of r)this._decorationsByLine.set(e,t);for(const e of this._decorations)e.marker.isDisposed||e._indexedStartLine>=t&&(e._indexedStartLine=e.marker.line);for(const e of s)this._addToLineBuckets(e)}_applyBufferLinesDelete(e){const t=e.index+e.amount,i=new Map;for(const[s,r]of this._decorationsByLine){if(s>=e.index&&s=t?s-e.amount:s;this._mergeLineBucket(i,o,r)}this._decorationsByLine.clear();for(const[e,t]of i)this._decorationsByLine.set(e,t);const s=[];for(const i of this._decorations){if(i.marker.isDisposed)continue;const r=i._indexedStartLine,o=this._getDecorationHeight(i);r>=t?i._indexedStartLine=i.marker.line:rt&&s.push(i)}for(const e of s)this._reindexDecoration(e)}}t.DecorationLineCache=f;class p extends a.DisposableStore{get backgroundColorRGB(){return null===this._cachedBg&&(this.options.backgroundColor?this._cachedBg=n.css.toColor(this.options.backgroundColor):this._cachedBg=void 0),this._cachedBg}get foregroundColorRGB(){return null===this._cachedFg&&(this.options.foregroundColor?this._cachedFg=n.css.toColor(this.options.foregroundColor):this._cachedFg=void 0),this._cachedFg}constructor(e){super(),this.options=e,this.onRenderEmitter=this.add(new c.Emitter),this.onRender=this.onRenderEmitter.event,this._onDispose=this.add(new c.Emitter),this.onDispose=this._onDispose.event,this._cachedBg=null,this._cachedFg=null,this.marker=e.marker,this._indexedStartLine=e.marker.line,this.options.overviewRulerOptions&&!this.options.overviewRulerOptions.position&&(this.options.overviewRulerOptions.position="full")}dispose(){this._onDispose.fire(),super.dispose()}}},6025(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.InstantiationService=t.ServiceCollection=void 0;const s=i(6501),r=i(6201);class o{constructor(...e){this._entries=new Map;for(const[t,i]of e)this.set(t,i)}set(e,t){const i=this._entries.get(e);return this._entries.set(e,t),i}forEach(e){for(const[t,i]of this._entries.entries())e(t,i)}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)}}t.ServiceCollection=o,t.InstantiationService=class{constructor(){this._services=new o,this._services.set(s.IInstantiationService,this)}setService(e,t){this._services.set(e,t)}getService(e){return this._services.get(e)}createInstance(e,...t){const i=(0,r.getServiceDependencies)(e).sort((e,t)=>e.index-t.index),s=[];for(const t of i){const i=this._services.get(t.id);if(!i)throw new Error(`[createInstance] ${e.name} depends on UNKNOWN service ${t.id._id}.`);s.push(i)}const o=i.length>0?i[0].index:t.length;if(t.length!==o)throw new Error(`[createInstance] First service dependency of ${e.name} at position ${o+1} conflicts with ${t.length} static arguments`);return new e(...[...t,...s])}}},7276(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.LogService=void 0;const o=i(4812),n=i(6501),a={trace:n.LogLevelEnum.TRACE,debug:n.LogLevelEnum.DEBUG,info:n.LogLevelEnum.INFO,warn:n.LogLevelEnum.WARN,error:n.LogLevelEnum.ERROR,off:n.LogLevelEnum.OFF};let h=class extends o.Disposable{get logLevel(){return this._logLevel}constructor(e){super(),this._optionsService=e,this._logLevel=n.LogLevelEnum.OFF,this._updateLogLevel(),this._register(this._optionsService.onSpecificOptionChange("logLevel",()=>this._updateLogLevel()))}_updateLogLevel(){this._logLevel=a[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;t!1},X10:{events:1,restrict:e=>4!==e.button&&1===e.action&&(e.ctrl=!1,e.alt=!1,e.shift=!1,!0)},VT200:{events:19,restrict:e=>32!==e.action},DRAG:{events:23,restrict:e=>32!==e.action||3!==e.button},ANY:{events:31,restrict:e=>!0}};function n(e,t){let i=(e.ctrl?16:0)|(e.shift?4:0)|(e.alt?8:0);return 4===e.button?(i|=64,i|=e.action):(i|=3&e.button,4&e.button&&(i|=64),8&e.button&&(i|=128),32===e.action?i|=32:0!==e.action||t||(i|=3)),i}const a=String.fromCharCode,h={DEFAULT:e=>{const t=[n(e,!1)+32,e.col+32,e.row+32];return t[0]>255||t[1]>255||t[2]>255?"":`${a(t[0])}${a(t[1])}${a(t[2])}`},SGR:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.col};${e.row}${t}`},SGR_PIXELS:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.x};${e.y}${t}`}};class l extends s.Disposable{constructor(){super(),this._protocols={},this._encodings={},this._activeProtocol="",this._activeEncoding="",this._onProtocolChange=this._register(new r.Emitter),this.onProtocolChange=this._onProtocolChange.event;for(const e of Object.keys(o))this.addProtocol(e,o[e]);for(const e of Object.keys(h))this.addEncoding(e,h[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return 0!==this._protocols[this._activeProtocol].events}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol "${e}"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding "${e}"`);this._activeEncoding=e}reset(){this.activeProtocol="NONE",this.activeEncoding="DEFAULT"}setCustomWheelEventHandler(e){this._customWheelEventHandler=e}allowCustomWheelEvent(e){return!this._customWheelEventHandler||!1!==this._customWheelEventHandler(e)}restrictMouseEvent(e){return this._protocols[this._activeProtocol].restrict(e)}encodeMouseEvent(e){return this._encodings[this._activeEncoding](e)}get isDefaultEncoding(){return"DEFAULT"===this._activeEncoding}get isPixelEncoding(){return"SGR_PIXELS"===this._activeEncoding}}t.MouseStateService=l},56(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OptionsService=t.DEFAULT_OPTIONS=void 0;const s=i(4812),r=i(701),o=i(8636);t.DEFAULT_OPTIONS={cols:80,rows:24,showCursorImmediately:!1,cursorBlink:!1,blinkIntervalDuration:0,cursorStyle:"block",cursorWidth:1,cursorInactiveStyle:"outline",drawBoldTextInBrightColors:!0,documentOverride:null,fastScrollSensitivity:5,fontFamily:"monospace",fontSize:15,fontWeight:"normal",fontWeightBold:"bold",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:"info",logger:null,scrollback:1e3,scrollbar:{showScrollbar:!0},scrollOnEraseInDisplay:!1,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,mouseEventsRequireAlt:!1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},reflowCursorLine:!1,rescaleOverlappingGlyphs:!1,rightClickSelectsWord:r.isMac,windowOptions:{},windowsPty:{},wordSeparator:" ()[]{}',\"`",altClickMovesCursor:!0,convertEol:!1,termName:"xterm",quirks:{},vtExtensions:{}};const n=["normal","bold","100","200","300","400","500","600","700","800","900"];class a extends s.Disposable{constructor(e){super(),this._onOptionChange=this._register(new o.Emitter),this.onOptionChange=this._onOptionChange.event;const i={...t.DEFAULT_OPTIONS};for(const t in e)if(t in i)try{const s=e[t];i[t]=this._sanitizeAndValidateOption(t,s)}catch(e){console.error(e)}this.rawOptions=i,this.options={...i},this._setupOptions(),this._register((0,s.toDisposable)(()=>{this.rawOptions.linkHandler=null,this.rawOptions.documentOverride=null}))}onSpecificOptionChange(e,t){return this.onOptionChange(i=>{i===e&&t(this.rawOptions[e])})}onMultipleOptionChange(e,t){return this.onOptionChange(i=>{-1!==e.indexOf(i)&&t()})}_setupOptions(){const e=e=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);return this.rawOptions[e]},i=(e,i)=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);i=this._sanitizeAndValidateOption(e,i),this.rawOptions[e]!==i&&(this.rawOptions[e]=i,this._onOptionChange.fire(e))};for(const t in this.rawOptions){const s={get:e.bind(this,t),set:i.bind(this,t)};Object.defineProperty(this.options,t,s)}}_sanitizeAndValidateOption(e,i){switch(e){case"cursorStyle":if(i||(i=t.DEFAULT_OPTIONS[e]),!function(e){return"block"===e||"underline"===e||"bar"===e}(i))throw new Error(`"${i}" is not a valid value for ${e}`);break;case"wordSeparator":i||(i=t.DEFAULT_OPTIONS[e]);break;case"fontWeight":case"fontWeightBold":if("number"==typeof i&&1<=i&&i<=1e3)break;i=n.includes(i)?i:t.DEFAULT_OPTIONS[e];break;case"blinkIntervalDuration":if((i=Math.floor(i))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"cursorWidth":i=Math.floor(i);case"lineHeight":case"tabStopWidth":if(i<1)throw new Error(`${e} cannot be less than 1, value: ${i}`);break;case"minimumContrastRatio":i=Math.max(1,Math.min(21,Math.round(10*i)/10));break;case"scrollback":if((i=Math.min(i,4294967295))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"fastScrollSensitivity":case"scrollSensitivity":if(i<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${i}`);break;case"rows":case"cols":if(!i&&0!==i)throw new Error(`${e} must be numeric, value: ${i}`);break;case"windowsPty":i=i??{}}return i}}t.OptionsService=a},8811(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkService=void 0;const o=i(6501);let n=class{constructor(e){this._bufferService=e,this._nextId=1,this._entriesWithId=new Map,this._dataByLinkId=new Map}registerLink(e){const t=this._bufferService.buffer;if(void 0===e.id){const i=t.addMarker(t.ybase+t.y),s={data:e,id:this._nextId++,lines:[i]};return i.onDispose(()=>this._removeMarkerFromLink(s,i)),this._dataByLinkId.set(s.id,s),s.id}const i=e,s=this._getEntryIdKey(i),r=this._entriesWithId.get(s);if(r)return this.addLineToLink(r.id,t.ybase+t.y),r.id;const o=t.addMarker(t.ybase+t.y),n={id:this._nextId++,key:this._getEntryIdKey(i),data:i,lines:[o]};return o.onDispose(()=>this._removeMarkerFromLink(n,o)),this._entriesWithId.set(n.key,n),this._dataByLinkId.set(n.id,n),n.id}addLineToLink(e,t){const i=this._dataByLinkId.get(e);if(i&&i.lines.every(e=>e.line!==t)){const e=this._bufferService.buffer.addMarker(t);i.lines.push(e),e.onDispose(()=>this._removeMarkerFromLink(i,e))}}getLinkData(e){return this._dataByLinkId.get(e)?.data}_getEntryIdKey(e){return`${e.id};;${e.uri}`}_removeMarkerFromLink(e,t){const i=e.lines.indexOf(t);-1!==i&&(e.lines.splice(i,1),0===e.lines.length&&(void 0!==e.data.id&&this._entriesWithId.delete(e.key),this._dataByLinkId.delete(e.id)))}};t.OscLinkService=n,t.OscLinkService=n=s([r(0,o.IBufferService)],n)},6201(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.serviceRegistry=void 0,t.getServiceDependencies=function(e){return e.di$dependencies||[]},t.createDecorator=function(e){if(t.serviceRegistry.has(e))return t.serviceRegistry.get(e);const i=function(e,t,s){if(3!==arguments.length)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");!function(e,t,i){t.di$target===t?t.di$dependencies.push({id:e,index:i}):(t.di$dependencies=[{id:e,index:i}],t.di$target=t)}(i,e,s)};return i._id=e,t.serviceRegistry.set(e,i),i},t.serviceRegistry=new Map},6501(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IDecorationService=t.IUnicodeService=t.IOscLinkService=t.IOptionsService=t.ILogService=t.LogLevelEnum=t.IInstantiationService=t.ICharsetService=t.ICoreService=t.IMouseStateService=t.IBufferService=void 0;const s=i(6201);var r;t.IBufferService=(0,s.createDecorator)("BufferService"),t.IMouseStateService=(0,s.createDecorator)("MouseStateService"),t.ICoreService=(0,s.createDecorator)("CoreService"),t.ICharsetService=(0,s.createDecorator)("CharsetService"),t.IInstantiationService=(0,s.createDecorator)("InstantiationService"),function(e){e[e.TRACE=0]="TRACE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.OFF=5]="OFF"}(r||(t.LogLevelEnum=r={})),t.ILogService=(0,s.createDecorator)("LogService"),t.IOptionsService=(0,s.createDecorator)("OptionsService"),t.IOscLinkService=(0,s.createDecorator)("OscLinkService"),t.IUnicodeService=(0,s.createDecorator)("UnicodeService"),t.IDecorationService=(0,s.createDecorator)("DecorationService")},6415(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeService=void 0;const s=i(8636);class r{constructor(){this._providers=Object.create(null),this._active="",this._onChange=new s.Emitter,this.onChange=this._onChange.event}static extractShouldJoin(e){return!!(1&e)}static extractWidth(e){return e>>1&3}static extractCharKind(e){return e>>3}static createPropertyValue(e,t,i=!1){return(16777215&e)<<3|(3&t)<<1|(i?1:0)}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(e){if(!this._providers[e])throw new Error(`unknown Unicode version "${e}"`);this._active=e,this._activeProvider=this._providers[e],this._onChange.fire(e)}register(e){this._providers[e.version]=e,this._active||(this.activeVersion=e.version)}wcwidth(e){return this._activeProvider.wcwidth(e)}getStringCellWidth(e){let t=0,i=0;const s=e.length;for(let o=0;o=s)return t+this.wcwidth(n);const i=e.charCodeAt(o);56320<=i&&i<=57343?n=1024*(n-55296)+i-56320+65536:t+=this.wcwidth(i)}const a=this.charProperties(n,i);let h=r.extractWidth(a);r.extractShouldJoin(a)&&(h-=r.extractWidth(i)),t+=h,i=a}return t}charProperties(e,t){return this._activeProvider.charProperties(e,t)}}t.UnicodeService=r}},t={};return function i(s){var r=t[s];if(void 0!==r)return r.exports;var o=t[s]={exports:{}};return e[s].call(o.exports,o,o.exports,i),o.exports}(6081)})()); ++!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(globalThis,()=>(()=>{"use strict";var e={2840(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=r.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this._register(new c.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this._register(this._terminal.onResize(e=>this._handleResize(e.rows))),this._register(this._terminal.onRender(e=>this._refreshRows(e.start,e.end))),this._register(this._terminal.onScroll(()=>this._refreshRows())),this._register(this._terminal.onA11yChar(e=>this._handleChar(e))),this._register(this._terminal.onLineFeed(()=>this._handleChar("\n"))),this._register(this._terminal.onA11yTab(e=>this._handleTab(e))),this._register(this._terminal.onKey(e=>this._handleKey(e.key))),this._register(this._terminal.onBlur(()=>this._clearLiveRegion())),this._register(this._renderService.onDimensionsChange(()=>this._refreshRowsDimensions())),this._register((0,f.addDisposableListener)(r,"selectionchange",()=>this._handleSelectionChange())),this._register(this._coreBrowserService.onDprChange(()=>this._refreshRowsDimensions())),this._refreshRowsDimensions(),this._refreshRows(),this._register((0,d.toDisposable)(()=>{this._accessibilityContainer.remove(),this._rowElements.length=0}))}_handleTab(e){for(let t=0;t0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,"\n"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent=l.tooMuchOutput.get())))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.lines.get(i.ydisp+r),t=[],o=e?.translateToString(!0,void 0,void 0,t)||"",n=(i.ydisp+r+1).toString(),a=this._rowElements[r];a&&(0===o.length?(a.textContent=" ",this._rowColumns.set(a,[0,1])):(a.textContent=o,this._rowColumns.set(a,t)),a.setAttribute("aria-posinset",n),a.setAttribute("aria-setsize",s),this._alignRowWidth(a))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent===l.tooMuchOutput.get()&&this._clearLiveRegion(),this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute("aria-posinset")===(0===t?"1":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,o;if(0===t?(r=i,o=this._rowElements.pop(),this._rowContainer.removeChild(o)):(r=this._rowElements.shift(),o=i,this._rowContainer.removeChild(r)),r.removeEventListener("focus",this._topBoundaryFocusListener),o.removeEventListener("focus",this._bottomBoundaryFocusListener),0===t){const e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement("afterbegin",e)}else{const e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._terminal.scrollLines(0===t?-1:1),this._rowElements[0===t?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleSelectionChange(){if(0===this._rowElements.length)return;const e=this._coreBrowserService.mainDocument.getSelection();if(!e)return;if(e.isCollapsed)return void(this._rowContainer.contains(e.anchorNode)&&this._terminal.clearSelection());if(!e.anchorNode||!e.focusNode)return void console.error("anchorNode and/or focusNode are null");let t={node:e.anchorNode,offset:e.anchorOffset},i={node:e.focusNode,offset:e.focusOffset};if((t.node.compareDocumentPosition(i.node)&Node.DOCUMENT_POSITION_PRECEDING||t.node===i.node&&t.offset>i.offset)&&([t,i]=[i,t]),t.node.compareDocumentPosition(this._rowElements[0])&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_FOLLOWING)&&(t={node:this._rowElements[0].childNodes[0],offset:0}),!this._rowContainer.contains(t.node))return;const s=this._rowElements.slice(-1)[0];if(i.node.compareDocumentPosition(s)&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_PRECEDING)&&(i={node:s,offset:s.textContent?.length??0}),!this._rowContainer.contains(i.node))return;const r=({node:e,offset:t})=>{const i=e instanceof Text?e.parentNode:e;let s=parseInt(i?.getAttribute("aria-posinset"),10)-1;if(isNaN(s))return console.warn("row is invalid. Race condition?"),null;const r=this._rowColumns.get(i);if(!r)return console.warn("columns is null. Race condition?"),null;let o=t=this._terminal.cols&&(++s,o=0),{row:s,column:o}},o=r(t),n=r(i);if(o&&n){if(o.row>n.row||o.row===n.row&&o.column>=n.column)throw new Error("invalid range");this._terminal.select(o.column,o.row,(n.row-o.row)*this._terminal.cols-o.column+n.column)}}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener("focus",this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;ee;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const e=this._coreBrowserService.mainDocument.createElement("div");return e.setAttribute("role","listitem"),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){Object.assign(this._accessibilityContainer.style,{width:`${this._renderService.dimensions.css.canvas.width}px`,fontSize:`${this._terminal.options.fontSize}px`}),this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;ethis._onBell.fire())),this._register(this._inputHandler.onRequestRefreshRows(e=>this.refresh(e?.start??0,e?.end??this.rows-1))),this._register(this._inputHandler.onRequestSendFocus(()=>this._reportFocus())),this._register(this._inputHandler.onRequestReset(()=>this.reset())),this._register(this._inputHandler.onRequestWindowsOptionsReport(e=>this._reportWindowsOptions(e))),this._register(this._inputHandler.onColor(e=>this._handleColorEvent(e))),this._register(I.EventUtils.forward(this._inputHandler.onCursorMove,this._onCursorMove)),this._register(I.EventUtils.forward(this._inputHandler.onTitleChange,this._onTitleChange)),this._register(I.EventUtils.forward(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this._register(I.EventUtils.forward(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this._register(this._bufferService.onResize(e=>this._afterResize(e.cols,e.rows))),this._register((0,N.toDisposable)(()=>{this._customKeyEventHandler=void 0,this.element?.parentNode?.removeChild(this.element)}))}_handleColorEvent(e){if(this._themeService)for(const t of e){let e,i;switch(t.index){case 256:e="foreground",i="10";break;case 257:e="background",i="11";break;case 258:e="cursor",i="12";break;default:e="ansi",i="4;"+t.index}switch(t.type){case 0:const s=E.color.toColorRGB("ansi"===e?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`]${i};${(0,R.toRgbString)(s)}\\`);break;case 1:if("ansi"===e)this._themeService.modifyColors(e=>e.ansi[t.index]=E.channels.toColor(...t.color));else{const i=e;this._themeService.modifyColors(e=>e[i]=E.channels.toColor(...t.color))}break;case 2:this._themeService.restoreColor(t.index)}}}_reportColorScheme(){if(!this._themeService)return;const e=E.rgb.relativeLuminance(this._themeService.colors.background.rgba>>8)>8)?1:2;this.coreService.triggerDataEvent(`[?997;${e}n`)}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(A.AccessibilityManager,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.add("focus"),this._showCursor(),this._onFocus.fire()}blur(){return this.textarea?.blur()}_handleTextAreaBlur(){this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.blur(),this.textarea.value="",this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(""),this.element.classList.remove("focus"),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;const e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;const i=Math.min(this.buffer.x,this.cols-1),s=this._renderService.dimensions.css.cell.height,r=t.getWidth(i),o=this._renderService.dimensions.css.cell.width*r,n=this.buffer.y*this._renderService.dimensions.css.cell.height,a=i*this._renderService.dimensions.css.cell.width;this.textarea.style.left=a+"px",this.textarea.style.top=n+"px",this.textarea.style.width=o+"px",this.textarea.style.height=s+"px",this.textarea.style.lineHeight=s+"px",this.textarea.style.zIndex="-5"}_initGlobal(){this._bindKeys(),this._register((0,H.addDisposableListener)(this.element,"copy",e=>{this.hasSelection()&&(0,a.copyHandler)(e,this._selectionService)}));const e=e=>(0,a.handlePasteEvent)(e,this.textarea,this.coreService,this.optionsService);this._register((0,H.addDisposableListener)(this.textarea,"paste",e)),this._register((0,H.addDisposableListener)(this.element,"paste",e)),L.isFirefox?this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>{2===e.button&&(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})):this._register((0,H.addDisposableListener)(this.element,"contextmenu",e=>{(0,a.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})),L.isLinux&&this._register((0,H.addDisposableListener)(this.element,"auxclick",e=>{1===e.button&&(0,a.moveTextAreaUnderMouseCursor)(e,this.textarea,this.screenElement)}))}_bindKeys(){this._register((0,H.addDisposableListener)(this.textarea,"keyup",e=>this._keyUp(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keydown",e=>this._keyDown(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"keypress",e=>this._keyPress(e),!0)),this._register((0,H.addDisposableListener)(this.textarea,"compositionstart",()=>{this._syncTextArea(),this._compositionHelper.compositionstart(),this._compositionHelper.updateCompositionElements()})),this._register((0,H.addDisposableListener)(this.textarea,"compositionupdate",e=>this._compositionHelper.compositionupdate(e))),this._register((0,H.addDisposableListener)(this.textarea,"compositionend",e=>{this._compositionHelper instanceof u.CompositionHelper?this._compositionHelper.compositionend(e)&&this.textarea.dispatchEvent(new CustomEvent("xterm-composition-transaction-accepted",{bubbles:!0})):this._compositionHelper.compositionend()})),this._register((0,H.addDisposableListener)(this.textarea,"input",e=>this._inputEvent(e),!0)),this._register(this.onRender(()=>this._compositionHelper.updateCompositionElements()))}open(e){if(!e)throw new Error("Terminal requires a parent element.");if(e.isConnected||this._logService.debug("Terminal.open was called on an element that was not attached to the DOM"),this.element?.ownerDocument.defaultView&&this._coreBrowserService)return void(this.element.ownerDocument.defaultView!==this._coreBrowserService.window&&(this._coreBrowserService.window=this.element.ownerDocument.defaultView));this._document=e.ownerDocument,this.options.documentOverride&&this.options.documentOverride instanceof Document&&(this._document=this.optionsService.rawOptions.documentOverride),this.element=this._document.createElement("div"),this.element.dir="ltr",this.element.classList.add("terminal"),this.element.classList.add("xterm"),this.element.classList.toggle("allow-transparency",this.options.allowTransparency),this._register(this.optionsService.onSpecificOptionChange("allowTransparency",e=>this.element.classList.toggle("allow-transparency",e))),e.appendChild(this.element);const t=this._document.createDocumentFragment();this._viewportElement=this._document.createElement("div"),this._viewportElement.classList.add("xterm-viewport"),t.appendChild(this._viewportElement),this.screenElement=this._document.createElement("div"),this.screenElement.classList.add("xterm-screen"),this._register((0,H.addDisposableListener)(this.screenElement,"mousemove",e=>this.updateCursorStyle(e))),this._helperContainer=this._document.createElement("div"),this._helperContainer.classList.add("xterm-helpers"),this.screenElement.appendChild(this._helperContainer),t.appendChild(this.screenElement);const i=this.textarea=this._document.createElement("textarea");this.textarea.classList.add("xterm-helper-textarea"),this.textarea.setAttribute("aria-label",h.promptLabel.get()),L.isChromeOS||this.textarea.setAttribute("aria-multiline","false"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.tabIndex=0,this._register(this.optionsService.onSpecificOptionChange("disableStdin",()=>i.readOnly=this.optionsService.rawOptions.disableStdin)),this.textarea.readOnly=this.optionsService.rawOptions.disableStdin,this._coreBrowserService=this._register(this._instantiationService.createInstance(g.CoreBrowserService,this.textarea,e.ownerDocument.defaultView??window,this._document??("undefined"!=typeof window?window.document:null))),this._instantiationService.setService(C.ICoreBrowserService,this._coreBrowserService),this._register((0,H.addDisposableListener)(this.textarea,"focus",e=>this._handleTextAreaFocus(e))),this._register((0,H.addDisposableListener)(this.textarea,"blur",()=>this._handleTextAreaBlur())),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(p.CharSizeService,this._document,this._helperContainer),this._instantiationService.setService(C.ICharSizeService,this._charSizeService),this._themeService=this._instantiationService.createInstance(k.ThemeService),this._instantiationService.setService(C.IThemeService,this._themeService),this._register(this._inputHandler.onRequestColorSchemeQuery(()=>this._reportColorScheme())),this._register(this._themeService.onChangeColors(()=>{this.coreService.decPrivateModes.colorSchemeUpdates&&this._reportColorScheme()})),this._characterJoinerService=this._instantiationService.createInstance(v.CharacterJoinerService),this._instantiationService.setService(C.ICharacterJoinerService,this._characterJoinerService),this._renderService=this._register(this._instantiationService.createInstance(y.RenderService,this.rows,this.screenElement)),this._instantiationService.setService(C.IRenderService,this._renderService),this._register(this._renderService.onRenderedViewportChange(e=>this._onRender.fire(e))),this._register(this._renderService.onDimensionsChange(e=>this._onDimensionsChange.fire({css:{canvas:{...e.css.canvas},cell:{...e.css.cell}},device:{canvas:{...e.device.canvas},cell:{...e.device.cell},char:{...e.device.char}}}))),this.onResize(e=>this._renderService.resize(e.cols,e.rows)),this._compositionView=this._document.createElement("div"),this._compositionView.classList.add("composition-view"),this._compositionHelper=this._instantiationService.createInstance(u.CompositionHelper,this.textarea,this._compositionView),this._register((0,N.toDisposable)(()=>{this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.dispose()})),this._helperContainer.appendChild(this._compositionView),this._mouseCoordsService=this._instantiationService.createInstance(S.MouseCoordsService),this._instantiationService.setService(C.IMouseCoordsService,this._mouseCoordsService);const s=this._linkifier.value=this._register(this._instantiationService.createInstance(O.Linkifier,this.screenElement));this.element.appendChild(t);try{this._onWillOpen.fire(this.element)}catch(e){this._logService.error("onWillOpen handler threw an exception",e)}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._register(this.onCursorMove(()=>{this._renderService.handleCursorMove(),this._syncTextArea()})),this._register(this.onResize(()=>{this._renderService.handleResize(this.cols,this.rows),this._syncTextArea()})),this._register(this.onBlur(()=>this._renderService.handleBlur())),this._register(this.onFocus(()=>this._renderService.handleFocus())),this._viewport=this._register(this._instantiationService.createInstance(c.Viewport,this.element,this.screenElement)),this._register(this._viewport.onRequestScrollLines(e=>{super.scrollLines(e,!1),this.refresh(0,this.rows-1)})),this._selectionService=this._register(this._instantiationService.createInstance(w.SelectionService,this.element,this.screenElement,s)),this._instantiationService.setService(C.ISelectionService,this._selectionService),this._mouseService=this._instantiationService.createInstance(b.MouseService),this._instantiationService.setService(C.IMouseService,this._mouseService),this._register(this._selectionService.onRequestScrollLines(e=>this.scrollLines(e.amount,e.suppressScrollEvent))),this._register(this._selectionService.onSelectionChange(()=>this._onSelectionChange.fire())),this._register(this._selectionService.onRequestRedraw(e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode))),this._register(this._selectionService.onLinuxMouseSelection(e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()})),this._register(I.EventUtils.any(this._onScroll.event,this._inputHandler.onScroll)(()=>{this._selectionService.refresh(),this._viewport?.queueSync()})),this._register(this._instantiationService.createInstance(d.BufferDecorationRenderer,this.screenElement)),this._register((0,H.addDisposableListener)(this.element,"mousedown",e=>this._selectionService.handleMouseDown(e))),this.mouseStateService.areMouseEventsActive&&!this.options.mouseEventsRequireAlt?(this._selectionService.disable(),this.element.classList.add("enable-mouse-events")):(this._selectionService.enable(),this.element.classList.remove("enable-mouse-events")),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(A.AccessibilityManager,this)),this._register(this.optionsService.onSpecificOptionChange("screenReaderMode",e=>this._handleScreenReaderModeOptionChange(e)));const r=this.options.scrollbar?.showScrollbar??!0,o=this.options.scrollbar?.width;r&&o&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange("scrollbar",e=>{const t=(e?.showScrollbar??!0)&&!!e?.width;!this._overviewRulerRenderer&&t&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(_.OverviewRulerRenderer,this._viewportElement,this.screenElement)))}),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this._mouseService.bindMouse({element:this.element,screenElement:this.screenElement,document:this._document,handleTouchScroll:e=>this._viewport?.handleTouchScroll(e)},e=>this._register(e),()=>this.focus())}_createRenderer(){return this._instantiationService.createInstance(f.DomRenderer,this,this._document,this.element,this.screenElement,this._viewportElement,this._helperContainer,this.linkifier)}refresh(e,t,i=!1){this._renderService?.refreshRows(e,t,i)}updateCursorStyle(e){this._selectionService?.shouldColumnSelect(e)?this.element.classList.add("column-select"):this.element.classList.remove("column-select")}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t){this._viewport?this._viewport.scrollLines(e):super.scrollLines(e,t),this.refresh(0,this.rows-1)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){e&&this._viewport?this._viewport.scrollToLine(this.buffer.ybase,!0):this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}paste(e){(0,a.paste)(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}attachCustomWheelEventHandler(e){this.mouseStateService.setCustomWheelEventHandler(e)}registerLinkProvider(e){return this._linkProviderService.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");const t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return!!this._selectionService&&this._selectionService.hasSelection}select(e,t,i){this._selectionService.setSelection(e,t,i)}getSelection(){return this._selectionService?this._selectionService.selectionText:""}getSelectionPosition(){if(this._selectionService&&this._selectionService.hasSelection)return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){this._selectionService?.clearSelection()}selectAll(){this._selectionService?.selectAll()}selectLines(e,t){this._selectionService?.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;const t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(!0),!1;t||"Dead"!==e.key&&"AltGraph"!==e.key||(this._unprocessedDeadKey=!0);const i=this._keyboardService.evaluateKeyDown(e);if(this.updateCursorStyle(e),3===i.type||2===i.type){const t=this.rows-1;return this.scrollLines(2===i.type?-t:t),e.preventDefault(),e.stopPropagation(),!1}if(1===i.type&&this.selectAll(),this._isThirdLevelShift(this.browser,e))return!0;if(i.cancel&&(e.preventDefault(),e.stopPropagation()),!i.key)return!0;if(!this._keyboardService.useKitty&&!this._keyboardService.useWin32InputMode&&e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&1===e.key.length&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)return!0;if(this._unprocessedDeadKey)return this._unprocessedDeadKey=!1,!0;""!==i.key&&"\r"!==i.key||(this.textarea.value="");const s=this._keyboardService.useWin32InputMode&&W(e);if(this._onKey.fire({key:i.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(i.key,!s),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey)return e.preventDefault(),e.stopPropagation(),!1;this._keyDownHandled=!0}_isThirdLevelShift(e,t){const i=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState("AltGraph");return"keypress"===t.type?i:i&&(!t.keyCode||t.keyCode>47)}_keyUp(e){if(this._keyDownSeen=!1,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return;W(e)||this.focus();const t=this._keyboardService.evaluateKeyUp(e);if(t?.key){const i=this._keyboardService.useWin32InputMode&&W(e);this.coreService.triggerDataEvent(t.key,!i)}this.updateCursorStyle(e),this._keyPressHandled=!1}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled)return!1;if(this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;if(e.charCode)t=e.charCode;else if(null===e.which||void 0===e.which)t=e.keyCode;else{if(0===e.which||0===e.charCode)return!1;t=e.which}return!(!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)||(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this._compositionHelper.keypress?.(t)||this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,0))}_inputEvent(e){if(e.data&&"insertText"===e.inputType&&!this.optionsService.rawOptions.screenReaderMode&&this._compositionHelper instanceof u.CompositionHelper&&this._compositionHelper.input(e.data))return!0;if(e.data&&"insertText"===e.inputType&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;const t=e.data;return this.coreService.triggerDataEvent(t,!0),!0}return!1}resize(e,t){e!==this.cols||t!==this.rows?super.resize(e,t):this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure()}_afterResize(e,t){this._charSizeService?.measure()}clear(){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;efunction(e){const t=l(e);for(t.animFrameRequested=!1,t.current=t.next,t.next=[],t.inAnimationFrameRunner=!0;t.current.length>0;)t.current.sort(a.sort),t.current.shift().execute();t.inAnimationFrameRunner=!1}(e))),r};const s=i(3132);function r(e){const t=e;if(t?.ownerDocument?.defaultView)return t.ownerDocument.defaultView;const i=e;return i?.view?i.view:window}class o{constructor(e,t,i,s){this._node=e,this._type=t,this._handler=i,this._options=s,e.addEventListener(t,i,s)}dispose(){this._node&&this._handler&&(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}}function n(e,t,i,s){return new o(e,t,i,s)}t.eventType={CLICK:"click",MOUSE_DOWN:"mousedown",MOUSE_OVER:"mouseover",MOUSE_LEAVE:"mouseleave",KEY_DOWN:"keydown",KEY_UP:"keyup",INPUT:"input",BLUR:"blur",FOCUS:"focus",CHANGE:"change",POINTER_DOWN:"pointerdown",POINTER_MOVE:"pointermove",POINTER_UP:"pointerup",MOUSE_WHEEL:"wheel",WHEEL:"wheel"};class a{constructor(e,t){this._runner=e,this.priority=t,this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(e){console.error(e)}}static sort(e,t){return t.priority-e.priority}}const h=new Map;function l(e){let t=h.get(e);return t||(t={next:[],current:[],animFrameRequested:!1,inAnimationFrameRunner:!1},h.set(e,t)),t}class c extends s.IntervalTimer{constructor(e){super(),this._defaultTarget=e?r(e):void 0}cancelAndSet(e,t,i){super.cancelAndSet(e,t,i??this._defaultTarget??window)}}t.WindowIntervalTimer=c},8906(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Linkifier=void 0;const o=i(4812),n=i(6501),a=i(7098),h=i(8636),l=i(4159);let c=class extends o.Disposable{get currentLink(){return this._currentLink}constructor(e,t,i,s,r){super(),this._element=e,this._mouseCoordsService=t,this._renderService=i,this._bufferService=s,this._linkProviderService=r,this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this._register(new h.Emitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this._register(new h.Emitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this._register((0,o.toDisposable)(()=>{(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0,this._lastMouseEvent=void 0,this._activeProviderReplies?.clear()})),this._register(this._bufferService.onResize(()=>{this._clearCurrentLink(),this._wasResized=!0})),this._register((0,l.addDisposableListener)(this._element,"mouseleave",()=>{this._isMouseOut=!0,this._clearCurrentLink()})),this._register((0,l.addDisposableListener)(this._element,"mousemove",this._handleMouseMove.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mousedown",this._handleMouseDown.bind(this))),this._register((0,l.addDisposableListener)(this._element,"mouseup",this._handleMouseUp.bind(this)))}_handleMouseMove(e){this._lastMouseEvent=e;const t=this._positionFromMouseEvent(e,this._element);if(!t)return;this._isMouseOut=!1;const i=e.composedPath();for(let e=0;e{e?.forEach(e=>{e.link.dispose&&e.link.dispose()})}),this._activeProviderReplies=new Map,this._activeLine=e.y);let i=!1;for(const[s,r]of this._linkProviderService.linkProviders.entries())if(t){const t=this._activeProviderReplies?.get(s);t&&(i=this._checkLinkProviderResult(s,e,i))}else r.provideLinks(e.y,t=>{if(this._isMouseOut)return;const r=t?.map(e=>({link:e}));this._activeProviderReplies?.set(s,r),i=this._checkLinkProviderResult(s,e,i),this._activeProviderReplies?.size===this._linkProviderService.linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)})}_removeIntersectingLinks(e,t){const i=new Set;for(let s=0;se?this._bufferService.cols:s.link.range.end.x;for(let e=o;e<=n;e++){if(i.has(e)){r.splice(t--,1);break}i.add(e)}}}}_checkLinkProviderResult(e,t,i){if(!this._activeProviderReplies)return i;const s=this._activeProviderReplies.get(e);let r=!1;for(let t=0;tthis._linkAtPosition(e.link,t));e&&(i=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviderService.linkProviders.length&&!i)for(let e=0;ethis._linkAtPosition(e.link,t));if(s){i=!0,this._handleNewLink(s);break}}return i}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._currentLink)return;const t=this._positionFromMouseEvent(e,this._element);var i,s;t&&this._mouseDownLink&&(i=this._mouseDownLink.link,s=this._currentLink.link,i.text===s.text&&i.range.start.x===s.range.start.x&&i.range.start.y===s.range.start.y&&i.range.end.x===s.range.end.x&&i.range.end.y===s.range.end.y)&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){this._currentLink&&this._lastMouseEvent&&(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,o.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0)}_handleNewLink(e){if(!this._lastMouseEvent)return;const t=this._positionFromMouseEvent(this._lastMouseEvent,this._element);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:void 0===e.link.decorations||e.link.decorations.underline,pointerCursor:void 0===e.link.decorations||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>this._currentLink?.state?.decorations.pointerCursor,set:e=>{this._currentLink?.state&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&this._element.classList.toggle("xterm-cursor-pointer",e))}},underline:{get:()=>this._currentLink?.state?.decorations.underline,set:t=>{this._currentLink?.state&&this._currentLink?.state?.decorations.underline!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e=>{if(!this._currentLink)return;const t=0===e.start?0:e.start+1+this._bufferService.buffer.ydisp,i=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=i&&(this._clearCurrentLink(t,i),this._lastMouseEvent)){const e=this._positionFromMouseEvent(this._lastMouseEvent,this._element);e&&this._askForLink(e,!1)}})))}_linkHover(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add("xterm-cursor-pointer")),t.hover&&t.hover(i,t.text)}_fireUnderlineEvent(e,t){const i=e.range,s=this._bufferService.buffer.ydisp,r=this._createLinkUnderlineEvent(i.start.x-1,i.start.y-s-1,i.end.x,i.end.y-s-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(r)}_linkLeave(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove("xterm-cursor-pointer")),t.leave&&t.leave(i,t.text)}_linkAtPosition(e,t){const i=e.range.start.y*this._bufferService.cols+e.range.start.x,s=e.range.end.y*this._bufferService.cols+e.range.end.x,r=t.y*this._bufferService.cols+t.x;return i<=r&&r<=s}_positionFromMouseEvent(e,t){const i=this._mouseCoordsService.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(i)return{x:i[0],y:i[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,i,s,r){return{x1:e,y1:t,x2:i,y2:s,cols:this._bufferService.cols,fg:r}}};t.Linkifier=c,t.Linkifier=c=s([r(1,a.IMouseCoordsService),r(2,a.IRenderService),r(3,n.IBufferService),r(4,a.ILinkProviderService)],c)},7721(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.tooMuchOutput=t.promptLabel=void 0;let i="Terminal input";const s={get:()=>i,set:e=>i=e};t.promptLabel=s;let r="Too much output to announce, navigate to rows manually to read";const o={get:()=>r,set:e=>r=e};t.tooMuchOutput=o},3285(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkProvider=void 0;const o=i(3055),n=i(6501);let a=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i,this._workCell=new o.CellData}provideLinks(e,t){const i=this._bufferService.buffer.lines.get(e-1);if(!i)return void t(void 0);const s=[],r=this._optionsService.rawOptions.linkHandler,o=this._workCell,n=i.getTrimmedLength();let a=-1,l=-1,c=!1;for(let t=0;tr?r.activate(e,t,d):h(0,t),hover:(e,t)=>r?.hover?.(e,t,d),leave:(e,t)=>r?.leave?.(e,t,d)})}c=!1,o.hasExtendedAttrs()&&o.extended.urlId?(l=t,a=o.extended.urlId):(l=-1,a=-1)}}t(s)}_getRangeWithLineWrap(e,t,i,s){let r=e,o=t,n=e,a=i;for(;0===o;){const e=this._bufferService.buffer.lines.get(r-1);if(!e?.isWrapped)break;const t=this._bufferService.buffer.lines.get(r-2);if(!t)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,i-1,s))break;let n=i-1;for(;n>0&&this._hasUrlId(t,n-1,s);)n--;r--,o=n}for(;;){const e=this._bufferService.buffer.lines.get(n-1);if(!e)break;if(a!==e.getTrimmedLength())break;const t=this._bufferService.buffer.lines.get(n);if(!t?.isWrapped)break;const i=t.getTrimmedLength();if(0===i||!this._hasUrlId(t,0,s))break;let r=1;for(;rthis._innerRefresh()),this._animationFrame}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return void this._runRefreshCallbacks();const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(const e of this._refreshCallbacks)e(0);this._refreshCallbacks=[]}}},4292(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.TimeBasedDebouncer=void 0,t.TimeBasedDebouncer=class{constructor(e,t=1e3){this._renderCallback=e,this._debounceThresholdMS=t,this._lastRefreshMs=0,this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0),this._additionalRefreshRequested=!1}refresh(e,t,i){this._rowCount=i,e=e??0,t=t??this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t;const s=performance.now();if(s-this._lastRefreshMs>=this._debounceThresholdMS)void 0!==this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0,this._additionalRefreshRequested=!1),this._lastRefreshMs=s,this._innerRefresh();else if(!this._additionalRefreshRequested){const e=s-this._lastRefreshMs,t=this._debounceThresholdMS-e;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout(()=>{this._lastRefreshMs=performance.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0},t)}}_innerRefresh(){if(void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return;const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t)}}},9302(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_ANSI_COLORS=void 0;const s=i(4103);t.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const e=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],t=[0,95,135,175,215,255];for(let i=0;i<216;i++){const r=t[i/36%6|0],o=t[i/6%6|0],n=t[i%6];e.push({css:s.channels.toCss(r,o,n),rgba:s.channels.toRgba(r,o,n)})}for(let t=0;t<24;t++){const i=8+10*t;e.push({css:s.channels.toCss(i,i,i),rgba:s.channels.toRgba(i,i,i)})}return e})())},4017(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Viewport=void 0;const o=i(7098),n=i(4812),a=i(6501),h=i(4159),l=i(8566),c=i(8636),d=i(7880);let _=class extends n.Disposable{constructor(e,t,i,s,r,o,a,_,u){super(),this._bufferService=i,this._coreService=r,this._optionsService=_,this._renderService=u,this._onRequestScrollLines=this._register(new c.Emitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._isSyncing=!1,this._isHandlingScroll=!1,this._suppressOnScrollHandler=!1,this._needsSyncOnRender=!1;const f=this._register(new d.Scrollable({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:e=>(0,h.scheduleAtNextAnimationFrame)(s.window,e)}));this._register(this._optionsService.onSpecificOptionChange("smoothScrollDuration",()=>{f.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)})),this._scrollableElement=this._register(new l.SmoothScrollableElement(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,verticalHasArrows:this._optionsService.rawOptions.scrollbar?.showArrows??!1,...this._getChangeOptions()},f)),this._register(this._optionsService.onMultipleOptionChange(["scrollSensitivity","fastScrollSensitivity","scrollbar"],()=>this._scrollableElement.updateOptions(this._getChangeOptions()))),this._register(o.onProtocolChange(e=>{this._scrollableElement.updateOptions({handleMouseWheel:!(16&e)})})),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{e.style.backgroundColor=a.colors.background.css,this._scrollableElement.getDomNode().style.backgroundColor=a.colors.background.css})),e.appendChild(this._scrollableElement.getDomNode()),this._register((0,n.toDisposable)(()=>this._scrollableElement.getDomNode().remove())),this._styleElement=s.mainDocument.createElement("style"),t.appendChild(this._styleElement),this._register((0,n.toDisposable)(()=>this._styleElement.remove())),this._register(c.EventUtils.runAndSubscribe(a.onChangeColors,()=>{this._styleElement.textContent=[".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {",` background: ${a.colors.scrollbarSliderBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {",` background: ${a.colors.scrollbarSliderHoverBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {",` background: ${a.colors.scrollbarSliderActiveBackground.css};`,"}"].join("\n")})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(e=>this._handleScroll(e)))}scrollLines(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){const e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,i=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:i,verticalHasArrows:t}}queueSync(e){void 0!==e&&(this._latestYDisp=e),void 0===this._queuedAnimationFrame&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){this._renderService&&!this._isSyncing&&(this._coreService.decPrivateModes.synchronizedOutput?this._needsSyncOnRender=!0:(this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1))}_handleScroll(e){if(!this._renderService)return;if(this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;const t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),i=t-this._bufferService.buffer.ydisp;0!==i&&(this._latestYDisp=t,this._onRequestScrollLines.fire(i)),this._isHandlingScroll=!1}handleTouchScroll(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};t.Viewport=_,t.Viewport=_=s([r(2,a.IBufferService),r(3,o.ICoreBrowserService),r(4,a.ICoreService),r(5,a.IMouseStateService),r(6,o.IThemeService),r(7,a.IOptionsService),r(8,o.IRenderService)],_)},4196(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferDecorationRenderer=void 0;const o=i(7098),n=i(4812),a=i(6501);let h=class extends n.Disposable{constructor(e,t,i,s,r){super(),this._screenElement=e,this._bufferService=t,this._coreBrowserService=i,this._decorationService=s,this._renderService=r,this._decorationElements=new Map,this._altBufferIsActive=!1,this._dimensionsChanged=!1,this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(e=>this._removeDecoration(e))),this._register((0,n.toDisposable)(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){void 0===this._animationFrame&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(const e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){const t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer","top"===e?.options?.layer),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",t.style.top=(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height+"px",t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;const i=e.options.x??0;return i&&i>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){const t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let i=this._decorationElements.get(e);i||(i=this._createElement(e),e.element=i,this._decorationElements.set(e,i),this._container.appendChild(i),e.onDispose(()=>{this._decorationElements.delete(e),i.remove()})),i.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(i.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,i.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",i.style.top=t*this._renderService.dimensions.css.cell.height+"px",i.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(i)}}_refreshXPosition(e,t=e.element){if(!t)return;const i=e.options.x??0;"right"===(e.options.anchor||"left")?t.style.right=i?i*this._renderService.dimensions.css.cell.width+"px":"":t.style.left=i?i*this._renderService.dimensions.css.cell.width+"px":""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};t.BufferDecorationRenderer=h,t.BufferDecorationRenderer=h=s([r(1,a.IBufferService),r(2,o.ICoreBrowserService),r(3,a.IDecorationService),r(4,o.IRenderService)],h)},957(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ColorZoneStore=void 0,t.ColorZoneStore=class{constructor(){this._zones=[],this._zonePool=[],this._zonePoolIndex=0,this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(e){if(e.options.overviewRulerOptions){for(const t of this._zones)if(t.color===e.options.overviewRulerOptions.color&&t.position===e.options.overviewRulerOptions.position){if(this._lineIntersectsZone(t,e.marker.line))return;if(this._lineAdjacentToZone(t,e.marker.line,e.options.overviewRulerOptions.position))return void this._addLineToZone(t,e.marker.line)}if(this._zonePoolIndex=e.startBufferLine&&t<=e.endBufferLine}_lineAdjacentToZone(e,t,i){return t>=e.startBufferLine-this._linePadding[i||"full"]&&t<=e.endBufferLine+this._linePadding[i||"full"]}_addLineToZone(e,t){e.startBufferLine=Math.min(e.startBufferLine,t),e.endBufferLine=Math.max(e.endBufferLine,t)}}},9925(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OverviewRulerRenderer=void 0;const o=i(957),n=i(7098),a=i(4812),h=i(6501),l={full:0,left:0,center:0,right:0},c={full:0,left:0,center:0,right:0},d={full:0,left:0,center:0,right:0};let _=class extends a.Disposable{get _width(){const e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??1?e?.width??0:0}constructor(e,t,i,s,r,n,h,l){super(),this._viewportElement=e,this._screenElement=t,this._bufferService=i,this._decorationService=s,this._renderService=r,this._optionsService=n,this._themeService=h,this._coreBrowserService=l,this._colorZoneStore=new o.ColorZoneStore,this._shouldUpdateDimensions=!0,this._shouldUpdateAnchor=!0,this._lastKnownBufferLength=0,this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register((0,a.toDisposable)(()=>this._canvas?.remove()));const c=this._canvas.getContext("2d");if(!c)throw new Error("Ctx cannot be null");this._ctx=c,this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register((0,a.toDisposable)(()=>{void 0!==this._animationFrame&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}_refreshDrawConstants(){const e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);c.full=this._canvas.width,c.left=e,c.center=t,c.right=e,this._refreshDrawHeightConstants(),d.full=1,d.left=1,d.center=1+c.left,d.right=1+c.left+c.center}_refreshDrawHeightConstants(){l.full=Math.round(2*this._coreBrowserService.dpr);const e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);l.left=t,l.center=t,l.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;const e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(const e of this._decorationService.decorations)this._colorZoneStore.addDecoration(e);this._ctx.lineWidth=1,this._renderRulerOutline();const e=this._colorZoneStore.zones;for(const t of e)"full"!==t.position&&this._renderColorZone(t);for(const t of e)"full"===t.position&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect(d[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-l[e.position||"full"]/2),c[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+l[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};t.OverviewRulerRenderer=_,t.OverviewRulerRenderer=_=s([r(2,h.IBufferService),r(3,h.IDecorationService),r(4,n.IRenderService),r(5,h.IOptionsService),r(6,n.IThemeService),r(7,n.ICoreBrowserService)],_)},3618(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CompositionHelper=void 0;const o=i(7098),n=i(6501),a="xterm-composition-session-end";let h=class{get isComposing(){return this._isComposing}get hasPendingCompositionFinalization(){return void 0!==this._pendingComposition}get _isSendingComposition(){return this.hasPendingCompositionFinalization}get _pendingKeypressData(){return this._pendingComposition?.keypressData??""}constructor(e,t,i,s,r,o){this._textarea=e,this._compositionView=t,this._bufferService=i,this._optionsService=s,this._coreService=r,this._renderService=o,this._isComposing=!1,this._isAwaitingCompositionEnd=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionStartValue="",this._compositionStartSelection={start:0,end:0},this._compositionHasObservedProgress=!1,this._compositionTransactionId=0,this._compositionTimers=new Set}compositionstart(){this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=void 0,this._cancelDeferredTimer(this._compositionViewTimer),this._compositionViewTimer=void 0,this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,void 0!==this._textareaChangeTimer&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);const e=this._textarea.selectionStart??this._textarea.value.length,t=this._textarea.selectionEnd??e;this._compositionPosition.start=Math.min(e,t),this._compositionPosition.end=Math.max(e,t),this._compositionStartValue=this._textarea.value,this._compositionStartSelection={start:e,end:t},this._compositionHasObservedProgress=!1,this._pendingComposition&&(this._pendingComposition.nextCompositionStart=this._compositionPosition.start),this._compositionTransactionId++,this._isComposing=!0,this._isAwaitingCompositionEnd=!0,this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionView.classList.add("active"),this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-session-start",{bubbles:!0,detail:{id:this._compositionTransactionId}}))}compositionupdate(e){this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._compositionHasObservedProgress||=this._hasCompositionProgress(),e.data?.length>0&&(this._lastCompositionData=e.data),this._compositionView.textContent=`‎${e.data??""}‎`,this.updateCompositionElements();const t=this._compositionTransactionId;this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=this._defer(()=>{if(this._isComposing&&this._compositionTransactionId===t){this._compositionHasObservedProgress||=this._hasCompositionProgress();const e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)}})}compositionend(e){if(!this._isAwaitingCompositionEnd)return!1;if(!this._isComposing){const t=this._pendingComposition;return t?.transactionId===this._compositionTransactionId&&(t.endData=e?.data??"",this._updatePostCompositionInputExpectation(t)),!1}const t=e?.data??"";if(this._compositionHasObservedProgress||=this._hasCompositionProgress(),!this._compositionEndBelongsToCurrentTransaction(t)){const e=this._pendingComposition;return e&&e.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(e),this._deferCompositionEnd(t),!1}return this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._finalizeComposition(!0,t),!0}blur(){if(this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._isComposing){const e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)}(this._isComposing||this.hasPendingCompositionFinalization)&&this._finalizeComposition(!1)}dispose(){void 0!==this._textareaChangeTimer&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);for(const e of this._compositionTimers)clearTimeout(e);this._compositionTimers.clear(),this._compositionPositionTimer=void 0,this._compositionViewTimer=void 0,this._compositionEndTimer=void 0,this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionTransactionId++}keydown(e){if(this._canceledKey?.code===e.code&&this._canceledKey.timeStamp===e.timeStamp)return this._canceledKey=void 0,!1;if("Escape"===e.key&&(this._isComposing||this.hasPendingCompositionFinalization))return this._canceledKey={code:e.code,timeStamp:e.timeStamp},this._cancelComposition(),!1;if(this._isComposing||this.hasPendingCompositionFinalization){if(20===e.keyCode||229===e.keyCode)return!1;if(16===e.keyCode||17===e.keyCode||18===e.keyCode)return!1;this._finalizeComposition(!1)}return 229!==e.keyCode||(this._handleAnyTextareaChanges(),!1)}keypress(e){const t=this._pendingComposition;return!(!t||(t.keypressMayOverlapComposition?(t.keypressData+=e,0):t.expectsPostCompositionInput&&0===t.keypressData.length?(t.keypressData=e,0):(this._sendPendingComposition(t),1)))}input(e){if(this._isComposing)return this._compositionHasObservedProgress||=this._hasCompositionProgress(),this._compositionInputData+=e,!0;const t=this._pendingComposition;if(!t)return!1;if(t.expectsPostCompositionInput)return t.inputData+=e,t.expectsPostCompositionInput=!1,this._sendPendingComposition(t),!0;const i=e.length>0&&this._getPendingTextareaInput(t)===e&&this._getPendingTextareaInput(t,!0)===e;return this._sendPendingComposition(t),i||this._coreService.triggerDataEvent(e,!0),!0}_finalizeComposition(e,t=""){const i=this._isComposing;if(this._compositionView.classList.remove("active"),this._isComposing=!1,!e||i)if(e){this._pendingComposition&&this._sendPendingComposition(this._pendingComposition);const e={transactionId:this._compositionTransactionId,lifecycleSettled:!1,sessionEnded:!1,position:{start:this._compositionPosition.start,end:this._compositionPosition.end},suffix:this._compositionSuffix,dataAlreadySent:this._dataAlreadySent,compositionData:this._lastCompositionData,endData:t,inputData:this._compositionInputData,keypressData:"",keypressMayOverlapComposition:0===this._lastCompositionData.length&&0===t.length,expectsPostCompositionInput:!1};this._updatePostCompositionInputExpectation(e),this._pendingComposition=e,e.finalizerTimer=this._defer(()=>{e.finalizerTimer=void 0,this._compositionTransactionId===e.transactionId&&(this._isAwaitingCompositionEnd=!1),this._pendingComposition===e&&this._sendPendingComposition(e,!0)})}else if(this._pendingComposition&&this._sendPendingComposition(this._pendingComposition,!0),i){const e=this._getCompositionInput(this._compositionPosition.start+this._dataAlreadySent.length,this._compositionSuffix);this._sendCompositionInput(this._compositionTransactionId,e)}}_sendPendingComposition(e,t=!1){this._cancelPendingFinalizer(e),this._pendingComposition===e&&(this._pendingComposition=void 0);const i=this._getPendingTextareaInput(e,t),s=this._removeAlreadySentData(e.inputData||e.keypressData,e.dataAlreadySent),r=this._mergeTextObservations(i||e.endData||(s?e.compositionData:""),s,e.keypressMayOverlapComposition);this._sendCompositionInput(e.transactionId,r,!e.sessionEnded),this._settlePendingComposition(e)}_cancelPendingFinalizer(e){void 0!==e.finalizerTimer&&(clearTimeout(e.finalizerTimer),this._compositionTimers.delete(e.finalizerTimer),e.finalizerTimer=void 0)}_settlePendingComposition(e){e.lifecycleSettled||(e.lifecycleSettled=!0,this._dispatchCompositionTransactionSettled())}_mergeTextObservations(e,t,i){if(!t||e.includes(t))return e;if(!e||t.includes(e))return t;if(i){let i=Math.min(e.length,t.length);for(;i>0&&!e.endsWith(t.substring(0,i));)i--;let s=Math.min(e.length,t.length);for(;s>0&&!t.endsWith(e.substring(0,s));)s--;return i>s?e+t.substring(i):t+e.substring(s)}let s=Math.min(e.length,t.length);for(;s>0&&!e.endsWith(t.substring(0,s));)s--;return e+t.substring(s)}_updatePostCompositionInputExpectation(e){e.expectsPostCompositionInput=(e.endData.length>0||e.compositionData.length>0)&&0===e.inputData.length&&0===this._getPendingTextareaInput(e).length}_getPendingTextareaInput(e,t=!1){const i=this._textarea.value,s=e.position.start+e.dataAlreadySent.length;if(void 0!==e.nextCompositionStart)return i.substring(s,Math.max(s,e.nextCompositionStart));const r=e.suffix.length>0&&i.endsWith(e.suffix)?i.length-e.suffix.length:i.length,o=(e.endData||e.compositionData).length,n=t?r:Math.max(e.position.end,s+o);return i.substring(s,Math.max(s,Math.min(r,n)))}_getCompositionInput(e,t){const i=this._textarea.value,s=t.length>0&&i.endsWith(t)?i.length-t.length:i.length;return i.substring(e,Math.max(e,s))}_removeAlreadySentData(e,t){return 0===t.length?e:e.startsWith(t)?e.substring(t.length):t.includes(e)?"":e}_cancelComposition(){const e=this._pendingComposition;e&&this._isComposing&&e.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(e);const t=this._isComposing?this._compositionTransactionId:this._pendingComposition?.transactionId??0,i=void 0!==e&&this._pendingComposition===e;this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionView.classList.remove("active"),this._textarea.value=this._textarea.value.substring(0,this._compositionPosition.start)+this._compositionSuffix,this._sendCompositionInput(t,""),i&&e&&this._settlePendingComposition(e)}_sendCompositionInput(e,t,i=!0){let s=!1;if(i){const i=new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:{id:e,data:t}});this._dispatchCompositionSessionEvent(i),s=i.defaultPrevented}t.length>0&&!s&&this._coreService.triggerDataEvent(t,!0)}_endPendingCompositionSession(e){if(e.sessionEnded)return;e.sessionEnded=!0;const t=this._getPendingTextareaInput(e)||e.endData||e.compositionData;this._dispatchCompositionSessionEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:{id:e.transactionId,data:t,dataPendingReconciliation:!0}}))}_dispatchCompositionSessionEvent(e){"function"==typeof this._textarea.dispatchEvent&&this._textarea.dispatchEvent(e)}_dispatchCompositionTransactionSettled(){this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-settled",{bubbles:!0}))}_deferCompositionEnd(e){this._cancelDeferredTimer(this._compositionEndTimer);const t=this._compositionTransactionId,i=this._defer(()=>{if(this._compositionEndTimer!==i||!this._isComposing||this._compositionTransactionId!==t||!this._compositionEndBelongsToCurrentTransaction(e))return;this._compositionEndTimer=void 0,this._finalizeComposition(!0,e),this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-accepted",{bubbles:!0}));const s=this._pendingComposition;s?.transactionId===t&&this._sendPendingComposition(s,!0)});this._compositionEndTimer=i}_hasCompositionProgress(){const e=this._textarea.selectionStart??this._textarea.value.length,t=this._textarea.selectionEnd??e;return this._compositionHasObservedProgress||this._textarea.value!==this._compositionStartValue||e!==this._compositionStartSelection.start||t!==this._compositionStartSelection.end}_compositionEndBelongsToCurrentTransaction(e){return this._hasCompositionProgress()||e.length>0&&e===this._lastCompositionData}_defer(e){const t=setTimeout(()=>{this._compositionTimers.delete(t),e()},0);return this._compositionTimers.add(t),t}_cancelDeferredTimer(e){void 0!==e&&(clearTimeout(e),this._compositionTimers.delete(e))}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;const e=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){const t=this._textarea.value,i=t.replace(e,"");this._dataAlreadySent=i,t.length>e.length?this._coreService.triggerDataEvent(i,!0):t.lengththis.updateCompositionElements(!0)))}}};t.CompositionHelper=h,t.CompositionHelper=h=s([r(2,n.IBufferService),r(3,n.IOptionsService),r(4,n.ICoreService),r(5,o.IRenderService)],h)},5251(e,t){function i(e,t,i){const s=i.getBoundingClientRect(),r=e.getComputedStyle(i),o=parseInt(r.getPropertyValue("padding-left"),10),n=parseInt(r.getPropertyValue("padding-top"),10);return[t.clientX-s.left-o,t.clientY-s.top-n]}Object.defineProperty(t,"__esModule",{value:!0}),t.getCoordsRelativeToElement=i,t.getCoords=function(e,t,s,r,o,n,a,h,l){if(!n)return;const c=i(e,t,s);return c[0]=Math.ceil((c[0]+(l?a/2:0))/a),c[1]=Math.ceil(c[1]/h),c[0]=Math.min(Math.max(c[0],1),r+(l?1:0)),c[1]=Math.min(Math.max(c[1],1),o),c}},9686(e,t){function i(e,t,i,o){const h=e-s(e,i),l=t-s(t,i),c=Math.abs(h-l)-function(e,t,i){let o=0;const n=e-s(e,i),a=t-s(t,i);for(let s=0;s=0&&et?"A":"B"}function o(e,t,i,s,r,o){let n=e,a=t,h="";for(;(n!==i||a!==s)&&a>=0&&ao.cols-1?(h+=o.buffer.translateBufferLineToString(a,!1,e,n),n=0,e=0,a++):!r&&n<0&&(h+=o.buffer.translateBufferLineToString(a,!1,0,e+1),n=o.cols-1,e=n,a--);return h+o.buffer.translateBufferLineToString(a,!1,e,n)}function n(e,t){return""+(t?"O":"[")+e}function a(e,t){e=Math.floor(e);let i="";for(let s=0;s0?h-s(h,l):t;const _=h,u=function(e,t,r,o,n,a){let h;return h=i(t,o,n,a).length>0?o-s(o,n):t,e=r&&he?"D":"C",a(Math.abs(l-e),n(d,h));d=c>t?"D":"C";const _=Math.abs(c-t);return a(function(e,t){return t.cols-e}(c>t?e:l,r)+(_-1)*r.cols+1+((c>t?l:e)-1),n(d,h))}},6081(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._core.options[e],i=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(const e in this._core.options){const s={get:t.bind(this,e),set:i.bind(this,e)};Object.defineProperty(this._publicOptions,e,s)}}_checkReadonlyOptions(e){if(f.includes(e))throw new Error(`Option "${e}" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw new Error("You must set the allowProposedApi option to true to use proposed API")}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get onDimensionsChange(){return this._core.onDimensionsChange}get element(){return this._core.element}get screenElement(){return this._core.screenElement}get parser(){return this._parser??=new _.ParserApi(this._core)}get unicode(){return this._checkProposedApi(),new u.UnicodeApi(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer??=this._register(new d.BufferNamespaceApi(this._core))}get markers(){return this._core.markers}get modes(){const e=this._core.coreService.decPrivateModes;let t="none";switch(this._core.mouseStateService.activeProtocol){case"X10":t="x10";break;case"VT200":t="vt200";break;case"DRAG":t="drag";break;case"ANY":t="any"}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,showCursor:!this._core.coreService.isCursorHidden,synchronizedOutputMode:e.synchronizedOutput,win32InputMode:e.win32InputMode,wraparoundMode:e.wraparound}}get dimensions(){return this._core.dimensions}get options(){return this._publicOptions}set options(e){for(const t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}input(e,t=!0){this._core.input(e,t)}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}attachCustomWheelEventHandler(e){this._core.attachCustomWheelEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){return this._verifyPositiveIntegers(e.x??0,e.width??0,e.height??0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,i){this._verifyIntegers(e,t,i),this._core.select(e,t,i)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write("\r\n",t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return{get promptLabel(){return a.promptLabel.get()},set promptLabel(e){a.promptLabel.set(e)},get tooMuchOutput(){return a.tooMuchOutput.get()},set tooMuchOutput(e){a.tooMuchOutput.set(e)}}}_verifyIntegers(...e){for(p of e)if(p===1/0||isNaN(p)||p%1!=0)throw new Error("This API only accepts integers")}_verifyPositiveIntegers(...e){for(p of e)if(p&&(p===1/0||isNaN(p)||p%1!=0||p<0))throw new Error("This API only accepts positive integers")}}t.Terminal=v},3955(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRenderer=void 0;const o=i(1433),n=i(2744),a=i(9176),h=i(6181),l=i(2274),c=i(654),d=i(7098),_=i(4103),u=i(4812),f=i(6501),p=i(8636),v=i(4159);let g=1,m=class extends u.Disposable{constructor(e,t,i,s,r,a,d,_,f,m,b,y,w,C){super(),this._terminal=e,this._document=t,this._element=i,this._screenElement=s,this._viewportElement=r,this._helperContainer=a,this._linkifier2=d,this._charSizeService=f,this._optionsService=m,this._bufferService=b,this._coreService=y,this._coreBrowserService=w,this._themeService=C,this._terminalClass=g++,this._rowElements=[],this._selectionRenderModel=(0,l.createSelectionRenderModel)(),this._lastSelectionColumnMode=!1,this._rowHasBlinkingCells=[],this._rowHasBlinkingCellsCount=0,this._onRequestRedraw=this._register(new p.Emitter),this.onRequestRedraw=this._onRequestRedraw.event,this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=(0,h.createRenderDimensions)(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(e=>this._injectCss(e))),this._injectCss(this._themeService.colors),this._rowFactory=_.createInstance(o.DomRendererRowFactory,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(e=>this._handleLinkHover(e))),this._register(this._linkifier2.onHideLinkUnderline(e=>this._handleLinkLeave(e))),this._cursorBlinkStateManager=new S(this._rowContainer,this._coreBrowserService),this._register((0,v.addDisposableListener)(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register((0,u.toDisposable)(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new c.TextBlinkStateManager(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register((0,u.toDisposable)(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new n.WidthCache,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){const e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(const e of this._rowElements)e.style.width=`${this.dimensions.css.canvas.width}px`,e.style.height=`${this.dimensions.css.cell.height}px`,e.style.lineHeight=`${this.dimensions.css.cell.height}px`,e.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));const t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${_.color.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;const i=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,r=`blink_block_${this._terminalClass}`;t+=`@keyframes ${i} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${r} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${i} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(const[i,s]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${i} { color: ${s.css}; }${this._terminalSelector} .xterm-fg-${i}.xterm-dim { color: ${_.color.multiplyOpacity(s,.5).css}; }${this._terminalSelector} .xterm-bg-${i} { background-color: ${s.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR} { color: ${_.color.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${a.INVERTED_DEFAULT_COLOR}.xterm-dim { color: ${_.color.multiplyOpacity(_.color.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${a.INVERTED_DEFAULT_COLOR} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){const e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let e=this._rowElements.length;e<=t;e++){const e=this._document.createElement("div");this._rowContainer.appendChild(e),this._rowElements.push(e),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,i){const s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,i);let r=0,o=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(r=this._selectionRenderModel.viewportCappedStartRow,o=this._selectionRenderModel.viewportCappedEndRow));let n=0,a=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,i),this._selectionRenderModel.hasSelection){const s=this._selectionRenderModel.viewportStartRow,r=this._selectionRenderModel.viewportEndRow,o=this._selectionRenderModel.viewportCappedStartRow,h=this._selectionRenderModel.viewportCappedEndRow;n=o,a=h;const l=this._document.createDocumentFragment();if(i){const i=e[0]>t[0];l.appendChild(this._createSelectionElement(o,i?t[0]:e[0],i?e[0]:t[0],h-o+1))}else{const i=s===o?e[0]:0,n=o===r?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(o,i,n));const a=h-o-1;if(l.appendChild(this._createSelectionElement(o+1,0,this._bufferService.cols,a)),o!==h){const e=r===h?t[0]:this._bufferService.cols;l.appendChild(this._createSelectionElement(h,0,e))}}this._selectionContainer.appendChild(l)}let h=Math.min(r,n),l=Math.max(o,a);if(l>=0){h=Math.max(h,0),l=Math.min(l,s-1);const e=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&e>=0&&ethis.dimensions.css.canvas.width&&(n=this.dimensions.css.canvas.width-o),r.style.height=s*this.dimensions.css.cell.height+"px",r.style.top=e*this.dimensions.css.cell.height+"px",r.style.left=`${o}px`,r.style.width=`${n}px`,r}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(const e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){const i=this._bufferService.buffer,s=i.ybase+i.y,r=Math.min(i.x,this._bufferService.cols-1),o=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,n=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,a=this._optionsService.rawOptions.cursorInactiveStyle,h={hasBlinkingCells:!1};for(let l=e;l<=t;l++){const e=l+i.ydisp,t=this._rowElements[l];if(!t)continue;const c=i.lines.get(e);c?(t.replaceChildren(...this._rowFactory.createRow(c,e,e===s,n,a,r,o,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,h)),this._setRowBlinkState(l,h.hasBlinkingCells)):(t.replaceChildren(),this._setRowBlinkState(l,!1))}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,i,s,r,o){i<0&&(e=0),s<0&&(t=0);const n=this._bufferService.rows-1;i=Math.max(Math.min(i,n),0),s=Math.max(Math.min(s,n),0),r=Math.min(r,this._bufferService.cols);const a=this._bufferService.buffer,h=a.ybase+a.y,l=Math.min(a.x,r-1),c=this._optionsService.rawOptions.cursorBlink,d=this._optionsService.rawOptions.cursorStyle,_=this._optionsService.rawOptions.cursorInactiveStyle,u={hasBlinkingCells:!1};for(let n=i;n<=s;++n){const f=n+a.ydisp,p=this._rowElements[n];if(!p)continue;const v=a.lines.get(f);v?(p.replaceChildren(...this._rowFactory.createRow(v,f,f===h,d,_,l,c,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,o?n===i?e:0:-1,o?(n===s?t:r)-1:-1,u)),this._setRowBlinkState(n,u.hasBlinkingCells)):(p.replaceChildren(),this._setRowBlinkState(n,!1))}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};t.DomRenderer=m,t.DomRenderer=m=s([r(7,f.IInstantiationService),r(8,d.ICharSizeService),r(9,f.IOptionsService),r(10,f.IBufferService),r(11,f.ICoreService),r(12,d.ICoreBrowserService),r(13,d.IThemeService)],m);class S{constructor(e,t){this._rowContainer=e,this._coreBrowserService=t,this._isIdlePaused=!1,this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){void 0!==this._idleTimeout&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}}},1433(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRendererRowFactory=void 0;const o=i(9176),n=i(8938),a=i(3055),h=i(6501),l=i(4103),c=i(7098),d=i(945),_=i(6181),u=i(5451);let f=class{constructor(e,t,i,s,r,o,n){this._document=e,this._characterJoinerService=t,this._optionsService=i,this._coreBrowserService=s,this._coreService=r,this._decorationService=o,this._themeService=n,this._workCell=new a.CellData,this._columnSelectMode=!1,this.defaultSpacing=0}handleSelectionChanged(e,t,i){this._selectionStart=e,this._selectionEnd=t,this._columnSelectMode=i}createRow(e,t,i,s,r,a,h,c,_,f,p,v,g){const m=[];g&&(g.hasBlinkingCells=!1);const S=this._characterJoinerService.getJoinedCharacters(t),b=this._themeService.colors;let y,w=e.getNoBgTrimmedLength();i&&w=B,F=I,W=this._workCell;if(S.length>0&&I===S[0][0]&&N){const s=S.shift(),r=this._isCellInSelection(s[0],t);for(C=s[0]+1;C=s[1],N?(H=!0,W=new d.JoinedCellData(this._workCell,e.translateToString(!0,s[0],s[1]),s[1]-s[0]),F=s[1]-1,w=W.getWidth()):B=s[1]}const z=this._isCellInSelection(I,t),K=i&&I===a,U=O&&I>=p&&I<=v;g&&W.isBlink()&&(g.hasBlinkingCells=!0),!c&&W.isBlink()&&A.push("xterm-blink-hidden");let j=!1;this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{j=!0});let $=W.getChars()||n.WHITESPACE_CELL_CHAR;if(" "===$&&(W.isUnderline()||W.isOverline())&&($=" "),k=w*_-f.get($,W.isBold(),W.isItalic()),y){if(D&&(z&&P||!z&&!P&&W.bg===x)&&(z&&P&&b.selectionForeground||W.fg===L)&&W.extended.ext===T&&U===R&&k===M&&!K&&!H&&!j&&N){W.isInvisible()?E+=n.WHITESPACE_CELL_CHAR:E+=$,D++;continue}D&&(y.textContent=E),y=this._document.createElement("span"),D=0,E=""}else y=this._document.createElement("span");if(x=W.bg,L=W.fg,T=W.extended.ext,R=U,M=k,P=z,H&&a>=I&&a<=F&&(a=I),!this._coreService.isCursorHidden&&K&&this._coreService.isCursorInitialized)if(A.push("xterm-cursor"),this._coreBrowserService.isFocused)h&&A.push("xterm-cursor-blink"),A.push("bar"===s?"xterm-cursor-bar":"underline"===s?"xterm-cursor-underline":"xterm-cursor-block");else if(r)switch(r){case"outline":A.push("xterm-cursor-outline");break;case"block":A.push("xterm-cursor-block");break;case"bar":A.push("xterm-cursor-bar");break;case"underline":A.push("xterm-cursor-underline")}if(W.isBold()&&A.push("xterm-bold"),W.isItalic()&&A.push("xterm-italic"),W.isDim()&&A.push("xterm-dim"),E=W.isInvisible()?n.WHITESPACE_CELL_CHAR:W.getChars()||n.WHITESPACE_CELL_CHAR,W.isUnderline()&&(A.push(`xterm-underline-${W.extended.underlineStyle}`)," "===E&&(E=" "),!W.isUnderlineColorDefault()))if(W.isUnderlineColorRGB())y.style.textDecorationColor=`rgb(${u.AttributeData.toColorRGB(W.getUnderlineColor()).join(",")})`;else{let e=W.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&W.isBold()&&e<8&&(e+=8),y.style.textDecorationColor=b.ansi[e].css}W.isOverline()&&(A.push("xterm-overline")," "===E&&(E=" ")),W.isStrikethrough()&&A.push("xterm-strikethrough"),U&&(y.style.textDecoration="underline");let V=W.getFgColor(),q=W.getFgColorMode(),X=W.getBgColor(),Y=W.getBgColorMode();const G=!!W.isInverse();if(G){const e=V;V=X,X=e;const t=q;q=Y,Y=t}let J,Z,Q,ee=!1;switch(this._decorationService.forEachDecorationAtCell(I,t,void 0,e=>{"top"!==e.options.layer&&ee||(e.backgroundColorRGB&&(Y=50331648,X=e.backgroundColorRGB.rgba>>8&16777215,J=e.backgroundColorRGB),e.foregroundColorRGB&&(q=50331648,V=e.foregroundColorRGB.rgba>>8&16777215,Z=e.foregroundColorRGB),ee="top"===e.options.layer)}),!ee&&z&&(J=this._coreBrowserService.isFocused?b.selectionBackgroundOpaque:b.selectionInactiveBackgroundOpaque,X=J.rgba>>8&16777215,Y=50331648,ee=!0,b.selectionForeground&&(q=50331648,V=b.selectionForeground.rgba>>8&16777215,Z=b.selectionForeground)),ee&&A.push("xterm-decoration-top"),Y){case 16777216:case 33554432:Q=b.ansi[X],A.push(`xterm-bg-${X}`);break;case 50331648:Q=l.channels.toColor(X>>16,X>>8&255,255&X),this._addStyle(y,`background-color:#${(X>>>0).toString(16).padStart(6,"0")}`);break;default:G?(Q=b.foreground,A.push(`xterm-bg-${o.INVERTED_DEFAULT_COLOR}`)):Q=b.background}switch(J||W.isDim()&&(J=l.color.multiplyOpacity(Q,.5)),q){case 16777216:case 33554432:W.isBold()&&V<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(V+=8),this._applyMinimumContrast(y,Q,b.ansi[V],W,J,void 0)||A.push(`xterm-fg-${V}`);break;case 50331648:const e=l.channels.toColor(V>>16&255,V>>8&255,255&V);this._applyMinimumContrast(y,Q,e,W,J,Z)||this._addStyle(y,`color:#${V.toString(16).padStart(6,"0")}`);break;default:this._applyMinimumContrast(y,Q,b.foreground,W,J,Z)||G&&A.push(`xterm-fg-${o.INVERTED_DEFAULT_COLOR}`)}A.length&&(y.className=A.join(" "),A.length=0),K||H||j||!N?y.textContent=E:D++,k!==this.defaultSpacing&&(y.style.letterSpacing=`${k}px`),m.push(y),I=F}return y&&D&&(y.textContent=E),m}_applyMinimumContrast(e,t,i,s,r,o){if(1===this._optionsService.rawOptions.minimumContrastRatio||(0,_.treatGlyphAsBackgroundColor)(s.getCode()))return!1;const n=this._getContrastCache(s);let a;if(r||o||(a=n.getColor(t.rgba,i.rgba)),void 0===a){const e=this._optionsService.rawOptions.minimumContrastRatio/(s.isDim()?2:1);a=l.color.ensureContrastRatio(r??t,o??i,e),n.setColor((r??t).rgba,(o??i).rgba,a??null)}return!!a&&(this._addStyle(e,`color:${a.css}`),!0)}_getContrastCache(e){return e.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(e,t){e.setAttribute("style",`${e.getAttribute("style")||""}${t};`)}_isCellInSelection(e,t){const i=this._selectionStart,s=this._selectionEnd;return!(!i||!s)&&(this._columnSelectMode?i[0]<=s[0]?e>=i[0]&&t>=i[1]&&e=i[1]&&e>=s[0]&&t<=s[1]:t>i[1]&&t=i[0]&&e=i[0])}};t.DomRendererRowFactory=f,t.DomRendererRowFactory=f=s([r(1,c.ICharacterJoinerService),r(2,h.IOptionsService),r(3,c.ICoreBrowserService),r(4,h.ICoreService),r(5,h.IDecorationService),r(6,c.IThemeService)],f)},2744(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WidthCache=void 0;const s=i(6181);t.WidthCache=class{constructor(e=()=>new r){this._flat=new Float32Array(256),this._font="",this._fontSize=0,this._weight="normal",this._weightBold="bold",this._canvasElements=[],this._canvasElements=[e(),e(),e(),e()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(e,t,i,s){e===this._font&&t===this._fontSize&&i===this._weight&&s===this._weightBold||(this._font=e,this._fontSize=t,this._weight=i,this._weightBold=s,this._canvasElements[0].setFont(e,t,i,!1),this._canvasElements[1].setFont(e,t,s,!1),this._canvasElements[2].setFont(e,t,i,!0),this._canvasElements[3].setFont(e,t,s,!0),this.clear())}get(e,t,i){let s;if(!t&&!i&&1===e.length&&(s=e.charCodeAt(0))<256){if(-9999!==this._flat[s])return this._flat[s];const t=this._measure(e,0);return t>0&&(this._flat[s]=t),t}let r=e;t&&(r+="B"),i&&(r+="I");let o=this._holey.get(r);if(void 0===o){let s=0;t&&(s|=1),i&&(s|=2),o=this._measure(e,s),o>0&&this._holey.set(r,o)}return o}_measure(e,t){return this._canvasElements[t].measure(e)}};class r{constructor(){"undefined"!=typeof OffscreenCanvas?(this._canvas=new OffscreenCanvas(1,1),this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=(0,s.throwIfFalsy)(this._canvas.getContext("2d")))}setFont(e,t,i,s){const r=s?"italic":"";this._ctx.font=`${r} ${i} ${t}px ${e}`.trim()}measure(e){return this._ctx.measureText(e).width}}},9176(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.INVERTED_DEFAULT_COLOR=void 0,t.INVERTED_DEFAULT_COLOR=257},6181(e,t){function i(e){return 57508<=e&&e<=57558}function s(e){return e>=128512&&e<=128591||e>=127744&&e<=128511||e>=128640&&e<=128767||e>=9728&&e<=9983||e>=9984&&e<=10175||e>=65024&&e<=65039||e>=129280&&e<=129535||e>=127462&&e<=127487}Object.defineProperty(t,"__esModule",{value:!0}),t.throwIfFalsy=function(e){if(!e)throw new Error("value must not be falsy");return e},t.isPowerlineGlyph=i,t.isRestrictedPowerlineGlyph=function(e){return 57520<=e&&e<=57527},t.isEmoji=s,t.allowRescaling=function(e,t,r,o){return 1===t&&r>Math.ceil(1.5*o)&&void 0!==e&&e>255&&!s(e)&&!i(e)&&!function(e){return 57344<=e&&e<=63743}(e)},t.treatGlyphAsBackgroundColor=function(e){return i(e)||function(e){return 9472<=e&&e<=9631}(e)},t.createRenderDimensions=function(){return{css:{canvas:{width:0,height:0},cell:{width:0,height:0}},device:{canvas:{width:0,height:0},cell:{width:0,height:0},char:{width:0,height:0,left:0,top:0}}}},t.computeNextVariantOffset=function(e,t,i=0){return(e-(2*Math.round(t)-i))%(2*Math.round(t))}},2274(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.createSelectionRenderModel=function(){return new i};class i{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(e,t,i,s=!1){if(this.selectionStart=t,this.selectionEnd=i,!t||!i||t[0]===i[0]&&t[1]===i[1])return void this.clear();const r=e.buffers.active.ydisp,o=t[1]-r,n=i[1]-r,a=Math.max(o,0),h=Math.min(n,e.rows-1);a>=e.rows||h<0?this.clear():(this.hasSelection=!0,this.columnSelectMode=s,this.viewportStartRow=o,this.viewportEndRow=n,this.viewportCappedStartRow=a,this.viewportCappedEndRow=h,this.startCol=t[0],this.endCol=i[0])}isCellSelected(e,t,i){return!!this.hasSelection&&(i-=e.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?t>=this.startCol&&i>=this.viewportCappedStartRow&&t=this.viewportCappedStartRow&&t>=this.endCol&&i<=this.viewportCappedEndRow:i>this.viewportStartRow&&i=this.startCol&&t=this.startCol)}}},654(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TextBlinkStateManager=void 0;const s=i(4812);class r extends s.Disposable{constructor(e,t,i){super(),this._renderCallback=e,this._coreBrowserService=t,this._optionsService=i,this._intervalDuration=0,this._blinkOn=!0,this._needsBlinkInViewport=!1,this._isViewportVisible=!0,this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",e=>{this.setIntervalDuration(e)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register((0,s.toDisposable)(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(void 0!==this._interval)return;const e=this._blinkOn;return this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),void(e||this._renderCallback())}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){void 0!==this._interval&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}}t.TextBlinkStateManager=r},8501(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._domNodePointerDown(e)))}_createArrow(e){const t=this._register(new c.ScrollbarArrow(e));return this.domNode.domNode.appendChild(t.bgDomNode),this.domNode.domNode.appendChild(t.domNode),t}_createSlider(e,t,i,s){this.slider=new h.FastDomNode(document.createElement("div")),this.slider.setClassName("xterm-slider"),this.slider.setPosition("absolute"),this.slider.setTop(e),this.slider.setLeft(t),"number"==typeof i&&this.slider.setWidth(i),"number"==typeof s&&this.slider.setHeight(s),this.slider.setLayerHinting(!0),this.slider.setContain("strict"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(a.addDisposableListener(this.slider.domNode,a.eventType.POINTER_DOWN,e=>{0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))})),this._onclick(this.slider.domNode,e=>{e.leftButton&&e.stopPropagation()})}_handleElementSize(e){return this._scrollbarState.setVisibleSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollSize(e){return this._scrollbarState.setScrollSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollPosition(e){return this._scrollbarState.setScrollPosition(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(e){e.target===this.domNode.domNode&&this._handlePointerDown(e)}delegatePointerDown(e){const t=this.domNode.domNode.getClientRects()[0].top,i=t+this._scrollbarState.getSliderPosition(),s=t+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),r=this._sliderPointerPosition(e);i<=r&&r<=s?0===e.button&&(e.preventDefault(),this._sliderPointerDown(e)):this._handlePointerDown(e)}_handlePointerDown(e){let t,i;if(e.target===this.domNode.domNode&&"number"==typeof e.offsetX&&"number"==typeof e.offsetY)t=e.offsetX,i=e.offsetY;else{const s=a.getDomNodePagePosition(this.domNode.domNode);t=e.pageX-s.left,i=e.pageY-s.top}const s=this._pointerDownRelativePosition(t,i);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(s):this._scrollbarState.getDesiredScrollPositionFromOffset(s)),0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))}_sliderPointerDown(e){if(!(e.target&&e.target instanceof Element))return;const t=this._sliderPointerPosition(e),i=this._sliderOrthogonalPointerPosition(e),s=this._scrollbarState.clone();this.slider.toggleClassName("xterm-active",!0),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{const r=this._sliderOrthogonalPointerPosition(e),o=Math.abs(r-i);if(u.isWindows&&o>140)return void this._setDesiredScrollPositionNow(s.getScrollPosition());const n=this._sliderPointerPosition(e)-t;this._setDesiredScrollPositionNow(s.getDesiredScrollPositionFromDelta(n))},()=>{this.slider.toggleClassName("xterm-active",!1),this._host.handleDragEnd()}),this._host.handleDragStart()}_setDesiredScrollPositionNow(e){const t={};this.writeScrollPosition(t,e),this._scrollable.setScrollPositionNow(t)}updateScrollbarSize(e){this._updateScrollbarSize(e),this._scrollbarState.setScrollbarSize(e),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}}t.AbstractScrollbar=f},1203(e,t){function i(e){return"number"==typeof e?`${e}px`:e}Object.defineProperty(t,"__esModule",{value:!0}),t.FastDomNode=void 0,t.FastDomNode=class{constructor(e){this.domNode=e,this._width="",this._height="",this._top="",this._left="",this._bottom="",this._right="",this._className="",this._position="",this._layerHint=!1,this._contain="none"}setWidth(e){const t=i(e);this._width!==t&&(this._width=t,this.domNode.style.width=this._width)}setHeight(e){const t=i(e);this._height!==t&&(this._height=t,this.domNode.style.height=this._height)}setTop(e){const t=i(e);this._top!==t&&(this._top=t,this.domNode.style.top=this._top)}setLeft(e){const t=i(e);this._left!==t&&(this._left=t,this.domNode.style.left=this._left)}setBottom(e){const t=i(e);this._bottom!==t&&(this._bottom=t,this.domNode.style.bottom=this._bottom)}setRight(e){const t=i(e);this._right!==t&&(this._right=t,this.domNode.style.right=this._right)}setClassName(e){this._className!==e&&(this._className=e,this.domNode.className=this._className)}toggleClassName(e,t){this.domNode.classList.toggle(e,t),this._className=this.domNode.className}setPosition(e){this._position!==e&&(this._position=e,this.domNode.style.position=this._position)}setLayerHinting(e){this._layerHint!==e&&(this._layerHint=e,this.domNode.style.transform=e?"translate3d(0px, 0px, 0px)":"")}setContain(e){this._contain!==e&&(this._contain=e,this.domNode.style.contain=this._contain)}setAttribute(e,t){this.domNode.setAttribute(e,t)}}},928(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{try{e.releasePointerCapture(t)}catch{}}))}catch{o=a.getWindow(e)}this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_MOVE,e=>{e.buttons===i?(e.preventDefault(),this._pointerMoveCallback(e)):this.stopMonitoring(!0)})),this._hooks.add(a.addDisposableListener(o,a.eventType.POINTER_UP,e=>this.stopMonitoring(!0)))}}},9699(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.HorizontalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition();if(super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(t.horizontalHasArrows?t.horizontalScrollbarSize:0,2===t.horizontal?0:t.horizontalScrollbarSize,2===t.vertical?0:t.verticalScrollbarSize,s.width,s.scrollWidth,o.scrollLeft),visibility:t.horizontal,extraScrollbarClassName:"xterm-horizontal",scrollable:e,scrollByPage:t.scrollByPage}),t.horizontalHasArrows)throw new Error("horizontalHasArrows is not supported in xterm.js");this._createSlider(Math.floor((t.horizontalScrollbarSize-t.horizontalSliderSize)/2),0,void 0,t.horizontalSliderSize)}_updateSlider(e,t){this.slider.setWidth(e),this.slider.setLeft(t)}_renderDomNode(e,t){this.domNode.setWidth(e),this.domNode.setHeight(t),this.domNode.setLeft(0),this.domNode.setBottom(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollWidth)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollLeft)||this._shouldRender,this._shouldRender=this._handleElementSize(e.width)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return e}_sliderPointerPosition(e){return e.pageX}_sliderOrthogonalPointerPosition(e){return e.pageY}_updateScrollbarSize(e){this.slider.setHeight(e)}writeScrollPosition(e,t){e.scrollLeft=t}updateOptions(e){this.updateScrollbarSize(2===e.horizontal?0:e.horizontalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._visibilityController.setVisibility(e.horizontal),this._scrollByPage=e.scrollByPage}}t.HorizontalScrollbar=o},3988(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;ni&&(s=i-t),s<0&&(s=0),r<0&&(r=0),n+r>o&&(n=o-r),n<0&&(n=0),this.width=t,this.scrollWidth=i,this.scrollLeft=s,this.height=r,this.scrollHeight=o,this.scrollTop=n}equals(e){return this.rawScrollLeft===e.rawScrollLeft&&this.rawScrollTop===e.rawScrollTop&&this.width===e.width&&this.scrollWidth===e.scrollWidth&&this.scrollLeft===e.scrollLeft&&this.height===e.height&&this.scrollHeight===e.scrollHeight&&this.scrollTop===e.scrollTop}withScrollDimensions(e,t){return new o(this._forceIntegerValues,void 0!==e.width?e.width:this.width,void 0!==e.scrollWidth?e.scrollWidth:this.scrollWidth,t?this.rawScrollLeft:this.scrollLeft,void 0!==e.height?e.height:this.height,void 0!==e.scrollHeight?e.scrollHeight:this.scrollHeight,t?this.rawScrollTop:this.scrollTop)}withScrollPosition(e){return new o(this._forceIntegerValues,this.width,this.scrollWidth,void 0!==e.scrollLeft?e.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,void 0!==e.scrollTop?e.scrollTop:this.rawScrollTop)}createScrollEvent(e,t){const i=this.width!==e.width,s=this.scrollWidth!==e.scrollWidth,r=this.scrollLeft!==e.scrollLeft,o=this.height!==e.height,n=this.scrollHeight!==e.scrollHeight,a=this.scrollTop!==e.scrollTop;return{inSmoothScrolling:t,oldWidth:e.width,oldScrollWidth:e.scrollWidth,oldScrollLeft:e.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:e.height,oldScrollHeight:e.scrollHeight,oldScrollTop:e.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:i,scrollWidthChanged:s,scrollLeftChanged:r,heightChanged:o,scrollHeightChanged:n,scrollTopChanged:a}}}t.ScrollState=o;class n extends r.Disposable{constructor(e){super(),this._scrollableBrand=void 0,this._onScroll=this._register(new s.Emitter),this.onScroll=this._onScroll.event,this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new o(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){const i=this._state.withScrollDimensions(e,t);this._setState(i,Boolean(this._smoothScrolling)),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){const t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(0!==this._smoothScrollDuration){if(this._smoothScrolling){e={scrollLeft:void 0===e.scrollLeft?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:void 0===e.scrollTop?this._smoothScrolling.to.scrollTop:e.scrollTop};const i=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===i.scrollLeft&&this._smoothScrolling.to.scrollTop===i.scrollTop)return;let s;s=t?new l(this._smoothScrolling.from,i,this._smoothScrolling.startTime,this._smoothScrolling.duration):l.start(this._state,i,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{const t=this._state.withScrollPosition(e);this._smoothScrolling=l.start(this._state,t,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}else this.setScrollPositionNow(e)}hasPendingScrollAnimation(){return Boolean(this._smoothScrolling)}_performSmoothScrolling(){if(!this._smoothScrolling)return;const e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);return this._setState(t,!0),this._smoothScrolling?e.isDone?(this._smoothScrolling.dispose(),void(this._smoothScrolling=null)):void(this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})):void 0}_setState(e,t){const i=this._state;i.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(i,t)))}}t.Scrollable=n;class a{constructor(e,t,i){this.scrollLeft=e,this.scrollTop=t,this.isDone=i}}function h(e,t){const i=t-e;return function(t){return e+i*(1-(s=1-t,Math.pow(s,3)));var s}}class l{constructor(e,t,i,s){this.from=e,this.to=t,this.duration=s,this.startTime=i,this.animationFrameDisposable=null,this._initAnimations()}_initAnimations(){this._scrollLeft=this._initAnimation(this.from.scrollLeft,this.to.scrollLeft,this.to.width),this._scrollTop=this._initAnimation(this.from.scrollTop,this.to.scrollTop,this.to.height)}_initAnimation(e,t,i){if(Math.abs(e-t)>2.5*i){let n,a;return e0&&Math.abs(e.deltaY)>0)return 1;let i=.5;if(this._isAlmostInt(e.deltaX)&&this._isAlmostInt(e.deltaY)||(i+=.25),t){const s=Math.abs(e.deltaX),r=Math.abs(e.deltaY),o=Math.abs(t.deltaX),n=Math.abs(t.deltaY),a=Math.max(Math.min(s,o),1),h=Math.max(Math.min(r,n),1),l=Math.max(s,o),c=Math.max(r,n);l%a===0&&c%h===0&&(i-=.5)}return Math.min(Math.max(i,0),1)}_isAlmostInt(e){return Math.abs(Math.round(e)-e)<.01}}S.INSTANCE=new S;class b extends _.Widget{get options(){return this._options}constructor(e,t,i){let s;super(),this._onScroll=this._register(new f.Emitter),this.onScroll=this._onScroll.event,t=t??{};const r=!i;i?s=i:(t.mouseWheelSmoothScroll=!1,s=new g.Scrollable({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:t=>a.scheduleAtNextAnimationFrame(a.getWindow(e),t)})),this._options=function(e){const t={lazyRender:void 0!==e.lazyRender&&e.lazyRender,className:void 0!==e.className?e.className:"",useShadows:void 0===e.useShadows||e.useShadows,handleMouseWheel:void 0===e.handleMouseWheel||e.handleMouseWheel,flipAxes:void 0!==e.flipAxes&&e.flipAxes,consumeMouseWheelIfScrollbarIsNeeded:void 0!==e.consumeMouseWheelIfScrollbarIsNeeded&&e.consumeMouseWheelIfScrollbarIsNeeded,alwaysConsumeMouseWheel:void 0!==e.alwaysConsumeMouseWheel&&e.alwaysConsumeMouseWheel,scrollYToX:void 0!==e.scrollYToX&&e.scrollYToX,mouseWheelScrollSensitivity:void 0!==e.mouseWheelScrollSensitivity?e.mouseWheelScrollSensitivity:1,fastScrollSensitivity:void 0!==e.fastScrollSensitivity?e.fastScrollSensitivity:5,scrollPredominantAxis:void 0===e.scrollPredominantAxis||e.scrollPredominantAxis,mouseWheelSmoothScroll:void 0===e.mouseWheelSmoothScroll||e.mouseWheelSmoothScroll,listenOnDomNode:void 0!==e.listenOnDomNode?e.listenOnDomNode:null,horizontal:void 0!==e.horizontal?e.horizontal:1,horizontalScrollbarSize:void 0!==e.horizontalScrollbarSize?e.horizontalScrollbarSize:10,horizontalSliderSize:void 0!==e.horizontalSliderSize?e.horizontalSliderSize:0,horizontalHasArrows:void 0!==e.horizontalHasArrows&&e.horizontalHasArrows,vertical:void 0!==e.vertical?e.vertical:1,verticalScrollbarSize:void 0!==e.verticalScrollbarSize?e.verticalScrollbarSize:10,verticalHasArrows:void 0!==e.verticalHasArrows&&e.verticalHasArrows,verticalSliderSize:void 0!==e.verticalSliderSize?e.verticalSliderSize:0,scrollByPage:void 0!==e.scrollByPage&&e.scrollByPage};return t.horizontalSliderSize=void 0!==e.horizontalSliderSize?e.horizontalSliderSize:t.horizontalScrollbarSize,t.verticalSliderSize=void 0!==e.verticalSliderSize?e.verticalSliderSize:t.verticalScrollbarSize,v.isMac&&(t.className+=" xterm-mac"),t}(t),this._scrollable=s,this._register(this._scrollable.onScroll(e=>{this._handleScroll(e),this._onScroll.fire(e)})),r&&this._register(this._scrollable);const o={handleMouseWheel:e=>this._handleMouseWheel(e),handleDragStart:()=>this._handleDragStart(),handleDragEnd:()=>this._handleDragEnd()};this._verticalScrollbar=this._register(new d.VerticalScrollbar(this._scrollable,this._options,o)),this._horizontalScrollbar=this._register(new c.HorizontalScrollbar(this._scrollable,this._options,o)),this._domNode=document.createElement("div"),this._domNode.className="xterm-scrollable-element "+this._options.className,this._domNode.setAttribute("role","presentation"),this._domNode.style.position="relative",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._leftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=new h.FastDomNode(document.createElement("div")),this._topLeftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode??this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this._onmouseover(this._listenOnDomNode,e=>this._handleMouseOver(e)),this._onmouseleave(this._listenOnDomNode,e=>this._handleMouseLeave(e)),this._hideTimeout=this._register(new u.TimeoutTimer),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}dispose(){this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}updateClassName(e){this._options.className=e,v.isMac&&(this._options.className+=" xterm-mac"),this._domNode.className="xterm-scrollable-element "+this._options.className}updateOptions(e){void 0!==e.handleMouseWheel&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),void 0!==e.mouseWheelScrollSensitivity&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),void 0!==e.fastScrollSensitivity&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),void 0!==e.scrollPredominantAxis&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),void 0!==e.horizontal&&(this._options.horizontal=e.horizontal),void 0!==e.vertical&&(this._options.vertical=e.vertical),void 0!==e.horizontalHasArrows&&(this._options.horizontalHasArrows=e.horizontalHasArrows),void 0!==e.verticalHasArrows&&(this._options.verticalHasArrows=e.verticalHasArrows),void 0!==e.horizontalScrollbarSize&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),void 0!==e.verticalScrollbarSize&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),void 0!==e.scrollByPage&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}delegateScrollFromMouseWheelEvent(e){this._handleMouseWheel(new l.StandardWheelEvent(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),e)){const e=e=>{this._handleMouseWheel(new l.StandardWheelEvent(e))};this._mouseWheelToDispose.push(a.addDisposableListener(this._listenOnDomNode,a.eventType.MOUSE_WHEEL,e,{passive:!1}))}}_handleMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;const t=S.INSTANCE;t.acceptStandardWheelEvent(e);let i=!1;if(e.deltaY||e.deltaX){let s=e.deltaY*this._options.mouseWheelScrollSensitivity,r=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&r+s===0?r=s=0:Math.abs(s)>=Math.abs(r)?r=0:s=0),this._options.flipAxes&&([s,r]=[r,s]);const o=!v.isMac&&e.browserEvent&&e.browserEvent.shiftKey;!this._options.scrollYToX&&!o||r||(r=s,s=0),e.browserEvent&&e.browserEvent.altKey&&(r*=this._options.fastScrollSensitivity,s*=this._options.fastScrollSensitivity);const n=this._scrollable.getFutureScrollPosition();let a={};if(s){const e=50*s,t=n.scrollTop-(e<0?Math.floor(e):Math.ceil(e));this._verticalScrollbar.writeScrollPosition(a,t)}if(r){const e=50*r,t=n.scrollLeft-(e<0?Math.floor(e):Math.ceil(e));this._horizontalScrollbar.writeScrollPosition(a,t)}a=this._scrollable.validateScrollPosition(a),(n.scrollLeft!==a.scrollLeft||n.scrollTop!==a.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(a):this._scrollable.setScrollPositionNow(a),i=!0)}let s=i;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_handleScroll(e){this._shouldRender=this._horizontalScrollbar.handleScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.handleScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error("Please use `lazyRender` together with `renderNow`!");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){const e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,i=e.scrollLeft>0,s=i?" xterm-shadow-left":"",r=t?" xterm-shadow-top":"",o=i||t?" xterm-shadow-top-left-corner":"";this._leftShadowDomNode.setClassName(`xterm-shadow${s}`),this._topShadowDomNode.setClassName(`xterm-shadow${r}`),this._topLeftShadowDomNode.setClassName(`xterm-shadow${o}${r}${s}`)}}_handleDragStart(){this._isDragging=!0,this._reveal()}_handleDragEnd(){this._isDragging=!1,this._hide()}_handleMouseLeave(e){this._mouseIsOver=!1,this._hide()}_handleMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){this._mouseIsOver||this._isDragging||(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){this._mouseIsOver||this._isDragging||this._hideTimeout.cancelAndSet(()=>this._hide(),500)}}t.SmoothScrollableElement=b},9594(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._arrowPointerDown(e))),this._register(c.addStandardDisposableListener(this.domNode,c.eventType.POINTER_DOWN,e=>this._arrowPointerDown(e))),this._pointerdownRepeatTimer=this._register(new c.WindowIntervalTimer),this._pointerdownScheduleRepeatTimer=this._register(new l.TimeoutTimer)}_arrowPointerDown(e){e.target&&e.target instanceof Element&&(this._handleActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet(()=>{this._pointerdownRepeatTimer.cancelAndSet(()=>this._handleActivate(),1e3/24,c.getWindow(e))},200),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,e=>{},()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()}),e.preventDefault())}}t.ScrollbarArrow=d},1270(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ScrollbarState=void 0;class i{constructor(e,t,i,s,r,o){this._scrollbarSize=Math.round(t),this._oppositeScrollbarSize=Math.round(i),this._arrowSize=Math.round(e),this._visibleSize=s,this._scrollSize=r,this._scrollPosition=o,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new i(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(e){const t=Math.round(e);return this._visibleSize!==t&&(this._visibleSize=t,this._refreshComputedValues(),!0)}setScrollSize(e){const t=Math.round(e);return this._scrollSize!==t&&(this._scrollSize=t,this._refreshComputedValues(),!0)}setScrollPosition(e){const t=Math.round(e);return this._scrollPosition!==t&&(this._scrollPosition=t,this._refreshComputedValues(),!0)}setScrollbarSize(e){this._scrollbarSize=Math.round(e)}setArrowSize(e){const t=Math.round(e);this._arrowSize!==t&&(this._arrowSize=t,this._refreshComputedValues())}setOppositeScrollbarSize(e){this._oppositeScrollbarSize=Math.round(e)}static _computeValues(e,t,i,s,r){const o=Math.max(0,i-e),n=Math.max(0,o-2*t),a=s>0&&s>i;if(!a)return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(n),computedSliderRatio:0,computedSliderPosition:0};const h=Math.round(Math.max(20,Math.floor(i*n/s))),l=(n-h)/(s-i),c=r*l;return{computedAvailableSize:Math.round(o),computedIsNeeded:a,computedSliderSize:Math.round(h),computedSliderRatio:l,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){const e=i._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=e.computedAvailableSize,this._computedIsNeeded=e.computedIsNeeded,this._computedSliderSize=e.computedSliderSize,this._computedSliderRatio=e.computedSliderRatio,this._computedSliderPosition=e.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize-this._computedSliderSize/2;return Math.round(t/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize;let i=this._scrollPosition;return t{this._domNode?.setClassName(this._visibleClassName)},0))}_hide(e){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(e?" xterm-fade":"")))}}t.ScrollbarVisibilityController=o},2650(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;n{s||(s=!0,this._remove(i))}}_remove(e){if(e.prev!==_.Undefined&&e.next!==_.Undefined){const t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===_.Undefined&&e.next===_.Undefined?(this._first=_.Undefined,this._last=_.Undefined):e.next===_.Undefined?(this._last=this._last.prev,this._last.next=_.Undefined):e.prev===_.Undefined&&(this._first=this._first.next,this._first.prev=_.Undefined)}*[Symbol.iterator](){let e=this._first;for(;e!==_.Undefined;)yield e.element,e=e.next}}var f;!function(e){e.TAP="-xterm-gesturetap",e.CHANGE="-xterm-gesturechange",e.START="-xterm-gesturestart",e.END="-xterm-gesturesend",e.CONTEXT_MENU="-xterm-gesturecontextmenu"}(f||(t.EventType=f={}));class p extends l.Disposable{constructor(){super(),this._dispatched=!1,this._targets=new u,this._ignoreTargets=new u,this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;const e=c;this._register(h.addDisposableListener(e.document,"touchstart",e=>this._handleTouchStart(e),{passive:!1})),this._register(h.addDisposableListener(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(h.addDisposableListener(e.document,"touchmove",e=>this._handleTouchMove(e),{passive:!1}))}static addTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._targets.push(e);return(0,l.toDisposable)(t)}static ignoreTarget(e){if(!p.isTouchDevice())return l.Disposable.None;p._instance||(p._instance=new p);const t=p._instance._ignoreTargets.push(e);return(0,l.toDisposable)(t)}static isTouchDevice(){return"ontouchstart"in c||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){const t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let i=0,s=e.targetTouches.length;i=p._holdDelay&&Math.abs(n.initialPageX-d(n.rollingPageX))<30&&Math.abs(n.initialPageY-d(n.rollingPageY))<30){const e=this._newGestureEvent(f.CONTEXT_MENU,n.initialTarget);e.pageX=d(n.rollingPageX),e.pageY=d(n.rollingPageY),this._dispatchEvent(e)}else if(1===s){const t=d(n.rollingPageX),s=d(n.rollingPageY),r=d(n.rollingTimestamps)-n.rollingTimestamps[0],o=t-n.rollingPageX[0],a=s-n.rollingPageY[0],h=[...this._targets].filter(e=>n.initialTarget instanceof Node&&e.contains(n.initialTarget));this._inertia(e,h,i,Math.abs(o)/r,o>0?1:-1,t,Math.abs(a)/r,a>0?1:-1,s)}this._dispatchEvent(this._newGestureEvent(f.END,n.initialTarget)),delete this._activeTouches[o.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){const i=document.createEvent("CustomEvent");return i.initEvent(e,!1,!0),i.initialTarget=t,i.tapCount=0,i}_dispatchEvent(e){if(e.type===f.TAP){const t=(new Date).getTime();let i;i=t-this._lastSetTapCountTime>p._clearTapCountTime?1:2,this._lastSetTapCountTime=t,e.tapCount=i}else e.type!==f.CHANGE&&e.type!==f.CONTEXT_MENU||(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(const t of this._ignoreTargets)if(t.contains(e.initialTarget))return;const t=[];for(const i of this._targets)if(i.contains(e.initialTarget)){let s=0,r=e.initialTarget;for(;r&&r!==i;)s++,r=r.parentElement;t.push([s,i])}t.sort((e,t)=>e[0]-t[0]);for(const[,i]of t)i.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,i,s,r,o,n,a,l){this._handle=h.scheduleAtNextAnimationFrame(e,()=>{const h=Date.now(),c=h-i;let d=0,_=0,u=!0;s+=p._scrollFriction*c,n+=p._scrollFriction*c,s>0&&(u=!1,d=r*s*c),n>0&&(u=!1,_=a*n*c);const v=this._newGestureEvent(f.CHANGE);v.translationX=d,v.translationY=_,t.forEach(e=>e.dispatchEvent(v)),u||this._inertia(e,t,h,s,r,o+d,n,a,l+_)})}_handleTouchMove(e){const t=Date.now();for(let i=0,s=e.changedTouches.length;i3&&(r.rollingPageX.shift(),r.rollingPageY.shift(),r.rollingTimestamps.shift()),r.rollingPageX.push(s.pageX),r.rollingPageY.push(s.pageY),r.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}}t.Gesture=p,p._scrollFriction=-.005,p._holdDelay=700,p._clearTapCountTime=400,n([function(e,t,i){let s=null,r=null;if("function"==typeof i.value?(s="value",r=i.value,0!==r.length&&console.warn("Memoize should only be used in functions with zero parameters")):"function"==typeof i.get&&(s="get",r=i.get),!r||!s)throw new Error("not supported");const o=`$memoize$${t}`;i[s]=function(...e){return this.hasOwnProperty(o)||Object.defineProperty(this,o,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,e)}),this[o]}}],p,"isTouchDevice",null)},8997(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.VerticalScrollbar=void 0;const s=i(8501),r=i(1270);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition(),n=t.verticalHasArrows;super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(n?t.verticalScrollbarSize:0,2===t.vertical?0:t.verticalScrollbarSize,0,s.height,s.scrollHeight,o.scrollTop),visibility:t.vertical,extraScrollbarClassName:"xterm-vertical",scrollable:e,scrollByPage:t.scrollByPage}),this._arrowScrollDelta=0,this._setArrows(n,t.verticalScrollbarSize),this._createSlider(0,Math.floor((t.verticalScrollbarSize-t.verticalSliderSize)/2),t.verticalSliderSize,void 0)}_updateSlider(e,t){this.slider.setHeight(e),this.slider.setTop(t)}_renderDomNode(e,t){this.domNode.setWidth(t),this.domNode.setHeight(e),this.domNode.setRight(0),this.domNode.setTop(0)}handleScroll(e){return this._shouldRender=this._handleElementScrollSize(e.scrollHeight)||this._shouldRender,this._shouldRender=this._handleElementScrollPosition(e.scrollTop)||this._shouldRender,this._shouldRender=this._handleElementSize(e.height)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return t}_sliderPointerPosition(e){return e.pageY}_sliderOrthogonalPointerPosition(e){return e.pageX}_updateScrollbarSize(e){this.slider.setWidth(e)}writeScrollPosition(e,t){e.scrollTop=t}_arrowScroll(e){const t=this._scrollable.getCurrentScrollPosition();this._scrollable.setScrollPositionNow({scrollTop:t.scrollTop+e})}_setArrows(e,t){if(this._arrowScrollDelta=t,!this._arrowUp||!this._arrowDown){const e=0;this._arrowUp=this._createArrow({className:"xterm-scra xterm-arrow-up",top:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(-this._arrowScrollDelta)}),this._arrowDown=this._createArrow({className:"xterm-scra xterm-arrow-down",bottom:e,left:e,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(this._arrowScrollDelta)})}if(this._updateArrowSize(this._arrowUp,t),this._updateArrowSize(this._arrowDown,t),!this._arrowUp||!this._arrowDown)return;const i=e?"":"none";this._arrowUp.bgDomNode.style.display=i,this._arrowUp.domNode.style.display=i,this._arrowDown.bgDomNode.style.display=i,this._arrowDown.domNode.style.display=i}_updateArrowSize(e,t){e&&(e.bgDomNode.style.width=`${t}px`,e.bgDomNode.style.height=`${t}px`,e.domNode.style.width=`${t}px`,e.domNode.style.height=`${t}px`)}updateOptions(e){const t=e.verticalHasArrows?e.verticalScrollbarSize:0;this._scrollbarState.setArrowSize(t),this._setArrows(e.verticalHasArrows,e.verticalScrollbarSize),this.updateScrollbarSize(2===e.vertical?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}}t.VerticalScrollbar=o},7741(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nt(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseover(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_OVER,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}_onmouseleave(e,t){this._register(a.addDisposableListener(e,a.eventType.MOUSE_LEAVE,i=>t(new h.StandardMouseEvent(a.getWindow(e),i))))}}t.Widget=c},5959(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SelectionModel=void 0,t.SelectionModel=class{constructor(e){this._bufferService=e,this.isSelectAllActive=!1,this.selectionStartLength=0}clearSelection(){this.selectionStart=void 0,this.selectionEnd=void 0,this.isSelectAllActive=!1,this.selectionStartLength=0}get finalSelectionStart(){return this.isSelectAllActive?[0,0]:this.selectionEnd&&this.selectionStart&&this.areSelectionValuesReversed()?this.selectionEnd:this.selectionStart}get finalSelectionEnd(){if(this.isSelectAllActive)return[this._bufferService.cols,this._bufferService.buffer.ybase+this._bufferService.rows-1];if(this.selectionStart){if(!this.selectionEnd||this.areSelectionValuesReversed()){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?e%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)-1]:[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[e,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[Math.max(e,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){const e=this.selectionStart,t=this.selectionEnd;return!(!e||!t)&&(e[1]>t[1]||e[1]===t[1]&&e[0]>t[0])}handleTrim(e){return this.selectionStart&&(this.selectionStart[1]-=e),this.selectionEnd&&(this.selectionEnd[1]-=e),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):!!(this.selectionStart&&this.selectionStart[1]<0)&&(this.selectionStart=[0,0],!0)}}},4792(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharSizeService=void 0;const o=i(6501),n=i(4812),a=i(8636);let h=class extends n.Disposable{get hasValidSize(){return this.width>0&&this.height>0}constructor(e,t,i){super(),this._optionsService=i,this.width=0,this.height=0,this._onCharSizeChange=this._register(new a.Emitter),this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new d(this._optionsService))}catch{this._measureStrategy=this._register(new c(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}measure(){const e=this._measureStrategy.measure();e.width===this.width&&e.height===this.height||(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};t.CharSizeService=h,t.CharSizeService=h=s([r(2,o.IOptionsService)],h);class l extends n.Disposable{constructor(){super(...arguments),this._result={width:0,height:0}}_validateAndSet(e,t){void 0!==e&&e>0&&void 0!==t&&t>0&&(this._result.width=e,this._result.height=t)}}class c extends l{constructor(e,t,i){super(),this._document=e,this._parentElement=t,this._optionsService=i,this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}}class d extends l{constructor(e){super(),this._optionsService=e,this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");const t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;const e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}}},945(e,t,i){var s,r=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},o=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharacterJoinerService=t.JoinedCellData=void 0;const n=i(5451),a=i(8938),h=i(3055),l=i(6501);class c extends n.AttributeData{constructor(e,t,i){super(),this.content=0,this.combinedData="",this.fg=e.fg,this.bg=e.bg,this.combinedData=t,this._width=i}isCombined(){return 2097152}getWidth(){return this._width}getChars(){return this.combinedData}getCode(){return 2097151}setFromCharData(e){throw new Error("not implemented")}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.JoinedCellData=c;let d=s=class{constructor(e){this._bufferService=e,this._characterJoiners=[],this._nextCharacterJoinerId=0,this._workCell=new h.CellData}register(e){const t={id:this._nextCharacterJoinerId++,handler:e};return this._characterJoiners.push(t),t.id}deregister(e){for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;t1){const e=this._getJoinedRanges(s,h,n,t,o);for(let t=0;tthis._screenDprMonitor.setWindow(e))),this._register(s.EventUtils.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register((0,r.addDisposableListener)(this._textarea,"focus",()=>this._isFocused=!0)),this._register((0,r.addDisposableListener)(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return void 0===this._cachedIsFocused&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}}t.CoreBrowserService=n;class a extends o.Disposable{constructor(e){super(),this._parentWindow=e,this._windowResizeListener=this._register(new o.MutableDisposable),this._onDprChange=this._register(new s.Emitter),this.onDprChange=this._onDprChange.event,this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register((0,o.toDisposable)(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=(0,r.addDisposableListener)(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){this._resolutionMediaMatchList&&this._outerListener&&(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}}},2136(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.KeyboardService=void 0;const o=i(706),n=i(7241),a=i(9249),h=i(701),l=i(6501);let c=class{constructor(e,t){this._coreService=e,this._optionsService=t}_getWin32InputMode(){return this._win32InputMode??=new a.Win32InputMode,this._win32InputMode}_getKittyKeyboard(){return this._kittyKeyboard??=new n.KittyKeyboard,this._kittyKeyboard}evaluateKeyDown(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!0);const t=this._coreService.kittyKeyboard.flags;return this.useKitty?this._getKittyKeyboard().evaluate(e,t,e.repeat?2:1,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):(0,o.evaluateKeyboardEvent)(e,this._coreService.decPrivateModes.applicationCursorKeys,h.isMac,this._optionsService.rawOptions.macOptionIsMeta)}evaluateKeyUp(e){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(e,!1);const t=this._coreService.kittyKeyboard.flags;return this.useKitty&&2&t?this._getKittyKeyboard().evaluate(e,t,3,h.isMac&&this._optionsService.rawOptions.macOptionIsMeta):void 0}get useKitty(){const e=this._coreService.kittyKeyboard.flags;return!(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard||!n.KittyKeyboard.shouldUseProtocol(e))}get useWin32InputMode(){return!(!this._optionsService.rawOptions.vtExtensions?.win32InputMode||!this._coreService.decPrivateModes.win32InputMode)}};t.KeyboardService=c,t.KeyboardService=c=s([r(0,l.ICoreService),r(1,l.IOptionsService)],c)},9820(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.LinkProviderService=void 0;const s=i(4812);class r extends s.Disposable{constructor(){super(),this.linkProviders=[],this._register((0,s.toDisposable)(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{const t=this.linkProviders.indexOf(e);-1!==t&&this.linkProviders.splice(t,1)}}}}t.LinkProviderService=r},8294(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.MouseCoordsService=void 0;const o=i(4159),n=i(5251),a=i(7098);let h=class{constructor(e,t){this._charSizeService=e,this._renderService=t}getCoords(e,t,i,s,r){return(0,n.getCoords)((0,o.getWindow)(t),e,t,i,s,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,r)}getMouseReportCoords(e,t){const i=(0,n.getCoordsRelativeToElement)((0,o.getWindow)(t),e,t);if(this._charSizeService.hasValidSize)return i[0]=Math.min(Math.max(i[0],0),this._renderService.dimensions.css.canvas.width-1),i[1]=Math.min(Math.max(i[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(i[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(i[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(i[0]),y:Math.floor(i[1])}}};t.MouseCoordsService=h,t.MouseCoordsService=h=s([r(0,a.ICharSizeService),r(1,a.IRenderService)],h)},9784(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.AltMouseCursorController=t.MouseService=void 0;const o=i(4159),n=i(6501),a=i(4812),h=i(7098),l=i(2650);let c=class{constructor(e,t,i,s,r,o,n,a,h){this._renderService=e,this._mouseCoordsService=t,this._mouseStateService=i,this._coreService=s,this._bufferService=r,this._optionsService=o,this._selectionService=n,this._logService=a,this._coreBrowserService=h,this._lastEvent=null,this._wheelPartialScroll=0,this._touchScrollAccumulator=0}bindMouse(e,t,i){const{element:s,document:r}=e,n={mouseup:null,wheel:null,mousedrag:null,mousemove:null},h={target:e,focus:i,requestedEvents:n},c={mouseup:e=>this._handleMouseUp(h,e),wheel:e=>this._handleWheel(h,e),mousedrag:e=>this._handleMouseDrag(h,e),mousemove:e=>this._handleMouseMove(h,e)};this._altMouseCursor=new d(s,r,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),t(this._altMouseCursor),t(this._mouseStateService.onProtocolChange(e=>{this._handleProtocolChange(h,c,e)})),t(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(s),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,t((0,a.toDisposable)(()=>{n.mouseup&&r.removeEventListener("mouseup",n.mouseup),n.mousedrag&&r.removeEventListener("mousemove",n.mousedrag)})),t((0,o.addDisposableListener)(s,"mousedown",e=>this._handleMouseDown(h,e))),t((0,o.addDisposableListener)(s,"wheel",e=>this._handlePassiveWheel(h,e),{passive:!1})),t(l.Gesture.addTarget(e.screenElement)),t((0,o.addDisposableListener)(e.screenElement,l.EventType.START,()=>this._handleTouchStart())),t((0,o.addDisposableListener)(e.screenElement,l.EventType.CHANGE,e=>this._handleTouchChange(h,e)))}_sendEvent(e,t){const i=this._mouseCoordsService.getMouseReportCoords(t,e.target.screenElement);if(!i)return!1;let s,r;switch(t.overrideType||t.type){case"mousemove":r=32,void 0===t.buttons?(s=3,void 0!==t.button&&(s=t.button<3?t.button:3)):s=1&t.buttons?0:4&t.buttons?1:2&t.buttons?2:3;break;case"mouseup":r=0,s=t.button<3?t.button:3;break;case"mousedown":r=1,s=t.button<3?t.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;const e=t.deltaY;if(0===e)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return!1;r=e<0?0:1,s=4;break;default:return!1}if(void 0===r||void 0===s||s>4)return!1;if(4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!t.altKey)return!1;const o=4!==s&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:i.col,row:i.row,x:i.x,y:i.y,button:s,action:r,ctrl:t.ctrlKey,alt:!o&&t.altKey,shift:t.shiftKey})}_handleMouseUp(e,t){this._sendEvent(e,t),t.buttons||(e.requestedEvents.mouseup&&e.target.document.removeEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.removeEventListener("mousemove",e.requestedEvents.mousedrag))}_handleWheel(e,t){return this._sendEvent(e,t),t.preventDefault(),t.stopPropagation(),!1}_handleMouseDrag(e,t){t.buttons&&this._sendEvent(e,t)}_handleMouseMove(e,t){t.buttons||this._sendEvent(e,t)}_handleMouseDown(e,t){t.preventDefault(),e.focus(),this._mouseStateService.areMouseEventsActive&&!this._selectionService.shouldForceSelection(t)&&(this._sendEvent(e,t),e.requestedEvents.mouseup&&e.target.document.addEventListener("mouseup",e.requestedEvents.mouseup),e.requestedEvents.mousedrag&&e.target.document.addEventListener("mousemove",e.requestedEvents.mousedrag))}_handlePassiveWheel(e,t){if(!e.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(t))return!1;if(!this._bufferService.buffer.hasScrollback){if(0===t.deltaY)return!1;if(0===this._consumeWheelEvent(t,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr))return t.preventDefault(),t.stopPropagation(),!1;const e=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(e,!0),t.preventDefault(),t.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(e,t){t.preventDefault(),t.stopPropagation(),e.requestedEvents.wheel?this._handleTouchScrollAsWheel(e,t):this._bufferService.buffer.hasScrollback?e.target.handleTouchScroll?.(t.translationY):this._handleTouchScrollAsKeys(t)}_handleTouchScrollAsKeys(e){const t=this._renderService?.dimensions.css.cell.height;if(!t)return;this._touchScrollAccumulator-=e.translationY;const i=Math.trunc(this._touchScrollAccumulator/t);if(0===i)return;this._touchScrollAccumulator-=i*t;const s=""+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(i<0?"A":"B");for(let e=0;e0?1:-1),this._wheelPartialScroll%=1):e.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(r*=this._bufferService.rows),r}_triggerMouseEvent(e){if(e.col<0||e.col>=this._bufferService.cols||e.row<0||e.row>=this._bufferService.rows)return!1;if(4===e.button&&32===e.action)return!1;if(3===e.button&&32!==e.action)return!1;if(4!==e.button&&(2===e.action||3===e.action))return!1;if(e.col++,e.row++,32===e.action&&this._lastEvent&&this._equalEvents(this._lastEvent,e,this._mouseStateService.isPixelEncoding))return!1;if(!this._mouseStateService.restrictMouseEvent(e))return!1;const t=this._mouseStateService.encodeMouseEvent(e);return t&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(t):this._coreService.triggerDataEvent(t,!0)),this._lastEvent=e,!0}_explainEvents(e){return{down:!!(1&e),up:!!(2&e),drag:!!(4&e),move:!!(8&e),wheel:!!(16&e)}}_equalEvents(e,t,i){if(i){if(e.x!==t.x)return!1;if(e.y!==t.y)return!1}else{if(e.col!==t.col)return!1;if(e.row!==t.row)return!1}return e.button===t.button&&e.action===t.action&&e.ctrl===t.ctrl&&e.alt===t.alt&&e.shift===t.shift}};t.MouseService=c,t.MouseService=c=s([r(0,h.IRenderService),r(1,h.IMouseCoordsService),r(2,n.IMouseStateService),r(3,n.ICoreService),r(4,n.IBufferService),r(5,n.IOptionsService),r(6,h.ISelectionService),r(7,n.ILogService),r(8,h.ICoreBrowserService)],c);class d{constructor(e,t,i){this._element=e,this._document=t,this._isActive=i,this._listeners=new a.MutableDisposable}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;const e=new a.DisposableStore,t=e=>this.syncFromModifier(e);e.add((0,o.addDisposableListener)(this._document,"keydown",t)),e.add((0,o.addDisposableListener)(this._document,"keyup",t)),e.add((0,o.addDisposableListener)(this._element,"mousemove",t));const i=this._element.ownerDocument?.defaultView;i&&e.add((0,o.addDisposableListener)(i,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=e}resetClass(){this._updateClass(!1)}syncFromModifier(e){this._isActive()&&this._updateClass(e.getModifierState("Alt"))}_updateClass(e){e?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}}t.AltMouseCursorController=d},5783(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.RenderService=void 0;const o=i(4852),n=i(7098),a=i(4812),h=i(6168),l=i(6501),c=i(8636);let d=class extends a.Disposable{get dimensions(){return this._renderer.value.dimensions}constructor(e,t,i,s,r,n,l,d,u,f){super(),this._rowCount=e,this._optionsService=i,this._logService=s,this._charSizeService=r,this._coreService=n,this._coreBrowserService=u,this._renderer=this._register(new a.MutableDisposable),this._observerDisposable=this._register(new a.MutableDisposable),this._isPaused=!1,this._needsFullRefresh=!1,this._isNextRenderRedrawOnly=!0,this._needsSelectionRefresh=!1,this._canvasWidth=0,this._canvasHeight=0,this._selectionState={start:void 0,end:void 0,columnSelectMode:!1},this._onDimensionsChange=this._register(new c.Emitter),this.onDimensionsChange=this._onDimensionsChange.event,this._onRenderedViewportChange=this._register(new c.Emitter),this.onRenderedViewportChange=this._onRenderedViewportChange.event,this._onRender=this._register(new c.Emitter),this.onRender=this._onRender.event,this._onRefreshRequest=this._register(new c.Emitter),this.onRefreshRequest=this._onRefreshRequest.event,this._pausedResizeTask=this._register(new h.DebouncedIdleTask(this._logService)),this._renderDebouncer=new o.RenderDebouncer((e,t)=>this._renderRows(e,t),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new _(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register((0,a.toDisposable)(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(d.onResize(()=>this._fullRefresh())),this._register(d.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(d.cols,d.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(d.buffer.y,d.buffer.y,void 0,!0))),this._register(f.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(e=>this._registerIntersectionObserver(e,t)))}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){const i=new e.IntersectionObserver(e=>this._handleIntersectionChange(e[e.length-1]),{threshold:0});this._observerDisposable.value=(0,a.toDisposable)(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=i,i.observe(t)}}_handleIntersectionChange(e){this._isPaused=void 0===e.isIntersecting?0===e.intersectionRatio:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),this._isPaused||this._charSizeService.hasValidSize||this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,i=!1,s=!1){if(this._isPaused)return void(this._needsFullRefresh=!0);if(this._coreService.decPrivateModes.synchronizedOutput)return void this._syncOutputHandler.bufferRows(e,t);const r=this._syncOutputHandler.flush();r&&(e=Math.min(e,r.start),t=Math.max(t,r.end)),s||(this._isNextRenderRedrawOnly=!1),i?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){this._renderer.value&&(this._coreService.decPrivateModes.synchronizedOutput?this._syncOutputHandler.bufferRows(e,t):(e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0))}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(e=>this.refreshRows(e.start,e.end,e.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,i){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=i,this._renderer.value?.handleSelectionChanged(e,t,i)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};t.RenderService=d,t.RenderService=d=s([r(2,l.IOptionsService),r(3,l.ILogService),r(4,n.ICharSizeService),r(5,l.ICoreService),r(6,l.IDecorationService),r(7,l.IBufferService),r(8,n.ICoreBrowserService),r(9,n.IThemeService)],d);class _{constructor(e,t,i){this._coreBrowserService=e,this._coreService=t,this._onTimeout=i,this._start=0,this._end=0,this._isBuffering=!1}bufferRows(e,t){this._isBuffering?(this._start=Math.min(this._start,e),this._end=Math.max(this._end,t)):(this._start=e,this._end=t,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;const e={start:this._start,end:this._end};return this._isBuffering=!1,e}dispose(){void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}}},2079(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},a=this&&this.__importStar||(s=function(e){return s=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},s(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i=s(e),n=0;nthis._handleMouseMove(e),this._mouseUpListener=e=>this._handleMouseUp(e),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(e=>this._handleTrim(e)),this._register(this._bufferService.buffers.onBufferActivate(e=>this._handleBufferActivate(e))),this.enable(),this._model=new d.SelectionModel(this._bufferService),this._activeSelectionMode=0,this._register((0,u.toDisposable)(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(e=>{e.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!(!e||!t||e[0]===t[0]&&e[1]===t[1])}get selectionText(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";const i=this._bufferService.buffer,s=[];if(3===this._activeSelectionMode){if(e[0]===t[0])return"";const r=e[0]e.replace(b," ")).join(f.isWindows?"\r\n":"\n")}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._refresh())),f.isLinux&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:3===this._activeSelectionMode})}_isClickInSelection(e){const t=this._getMouseBufferCoords(e),i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!!(i&&s&&t)&&this._areCoordsInSelection(t,i,s)}isCellInSelection(e,t){const i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!(!i||!s)&&this._areCoordsInSelection([e,t],i,s)}_areCoordsInSelection(e,t,i){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){const i=this._linkifier.currentLink?.link?.range;if(i)return this._model.selectionStart=[i.start.x-1,i.start.y-1],this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols),this._model.selectionEnd=void 0,!0;const s=this._getMouseBufferCoords(e);return!!s&&(this._selectWordAt(s,t),this._model.selectionEnd=void 0,!0)}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){const t=this._mouseCoordsService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=(0,l.getCoordsRelativeToElement)(this._coreBrowserService.window,e,this._screenElement)[1];const i=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=i?0:(t>i&&(t-=i),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(14*t))}shouldForceSelection(e){return this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive?!e.altKey:f.isMac?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,!(2===e.button&&this.hasSelection||0!==e.button||this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&e.altKey)){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):1===e.detail?this._handleSingleClick(e):2===e.detail?this._handleDoubleClick(e):3===e.detail&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener("mouseup",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval(()=>this._dragScroll(),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener("mouseup",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){const t=this.hasSelection;if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0,t&&this._fireOnSelectionChange(this._model.finalSelectionStart,this._model.finalSelectionEnd,!1);const i=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);i&&i.length!==this._model.selectionStart[0]&&0===i.hasWidth(this._model.selectionStart[0])&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){const t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return(!this._optionsService.rawOptions.mouseEventsRequireAlt||!this._mouseStateService.areMouseEventsActive)&&e.altKey&&!(f.isMac&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;const t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd)return void this.refresh(!0);2===this._activeSelectionMode?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));const i=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows-1,e.lines.length-1)):(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){const t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){const t=this._mouseCoordsService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(t&&void 0!==t[0]&&void 0!==t[1]){const e=(0,c.moveToCellSequence)(t[0]-1,t[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(e,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,i=!(!e||!t||e[0]===t[0]&&e[1]===t[1]);i?e&&t&&(this._oldSelectionStart&&this._oldSelectionEnd&&e[0]===this._oldSelectionStart[0]&&e[1]===this._oldSelectionStart[1]&&t[0]===this._oldSelectionEnd[0]&&t[1]===this._oldSelectionEnd[1]||this._fireOnSelectionChange(e,t,i)):this._oldHasSelection&&this._fireOnSelectionChange(e,t,i)}_fireOnSelectionChange(e,t,i){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=i,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.value=e.activeBuffer.lines.onTrim(e=>this._handleTrim(e))}_convertViewportColToCharacterIndex(e,t){let i=t;for(let s=0;t>=s;s++){const r=e.loadCell(s,this._workCell).getChars().length;0===this._workCell.getWidth()?i--:r>1&&t!==s&&(i+=r-1)}return i}setSelection(e,t,i){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=i,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,i=!0,s=!0){if(e[0]>=this._bufferService.cols)return;const r=this._bufferService.buffer,o=r.lines.get(e[1]);if(!o)return;const n=r.translateBufferLineToString(e[1],!1);let a=this._convertViewportColToCharacterIndex(o,e[0]),h=a;const l=e[0]-a;let c=0,d=0,_=0,u=0;if(" "===n.charAt(a)){for(;a>0&&" "===n.charAt(a-1);)a--;for(;h1&&(u+=s-1,h+=s-1);t>0&&a>0&&!this._isCharWordSeparator(o.loadCell(t-1,this._workCell));){o.loadCell(t-1,this._workCell);const e=this._workCell.getChars().length;0===this._workCell.getWidth()?(c++,t--):e>1&&(_+=e-1,a-=e-1),a--,t--}for(;i1&&(u+=e-1,h+=e-1),h++,i++}}h++;let f=a+l-c+_,p=Math.min(this._bufferService.cols,h-a+c+d-_-u);if(t||""!==n.slice(a,h).trim()){if(i&&0===f&&32!==o.getCodePoint(0)){const t=r.lines.get(e[1]-1);if(t&&o.isWrapped&&32!==t.getCodePoint(this._bufferService.cols-1)){const t=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(t){const e=this._bufferService.cols-t.start;f-=e,p+=e}}}if(s&&f+p===this._bufferService.cols&&32!==o.getCodePoint(this._bufferService.cols-1)){const t=r.lines.get(e[1]+1);if(t?.isWrapped&&32!==t.getCodePoint(0)){const t=this._getWordAt([0,e[1]+1],!1,!1,!0);t&&(p+=t.length)}}return{start:f,length:p}}}_selectWordAt(e,t){const i=this._getWordAt(e,t);if(i){for(;i.start<0;)i.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[i.start,e[1]],this._model.selectionStartLength=i.length}}_selectToWordAt(e){const t=this._getWordAt(e,!0);if(t){let i=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,i--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,i++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,i]}}_isCharWordSeparator(e){return 0!==e.getWidth()&&this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){const t=this._bufferService.buffer.getWrappedRangeForLine(e),i={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=(0,p.getRangeLength)(i,this._bufferService.cols)}};t.SelectionService=y,t.SelectionService=y=n([h(3,g.IBufferService),h(4,g.ICoreService),h(5,_.IMouseCoordsService),h(6,g.IOptionsService),h(7,g.IMouseStateService),h(8,_.IRenderService),h(9,_.ICoreBrowserService)],y)},7098(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IKeyboardService=t.ILinkProviderService=t.IThemeService=t.ICharacterJoinerService=t.ISelectionService=t.IRenderService=t.IMouseService=t.IMouseCoordsService=t.ICoreBrowserService=t.ICharSizeService=void 0;const s=i(6201);t.ICharSizeService=(0,s.createDecorator)("CharSizeService"),t.ICoreBrowserService=(0,s.createDecorator)("CoreBrowserService"),t.IMouseCoordsService=(0,s.createDecorator)("MouseCoordsService"),t.IMouseService=(0,s.createDecorator)("MouseService"),t.IRenderService=(0,s.createDecorator)("RenderService"),t.ISelectionService=(0,s.createDecorator)("SelectionService"),t.ICharacterJoinerService=(0,s.createDecorator)("CharacterJoinerService"),t.IThemeService=(0,s.createDecorator)("ThemeService"),t.ILinkProviderService=(0,s.createDecorator)("LinkProviderService"),t.IKeyboardService=(0,s.createDecorator)("KeyboardService")},9078(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeService=void 0;const o=i(7174),n=i(9302),a=i(4103),h=i(4812),l=i(6501),c=i(8636),d=a.css.toColor("#ffffff"),_=a.css.toColor("#000000"),u=a.css.toColor("#ffffff"),f=_,p={css:"rgba(255, 255, 255, 0.3)",rgba:4294967117},v=d;let g=class extends h.Disposable{get colors(){return this._colors}constructor(e){super(),this._optionsService=e,this._contrastCache=new o.ColorContrastCache,this._halfContrastCache=new o.ColorContrastCache,this._onChangeColors=this._register(new c.Emitter),this.onChangeColors=this._onChangeColors.event,this._colors={foreground:d,background:_,cursor:u,cursorAccent:f,selectionForeground:void 0,selectionBackgroundTransparent:p,selectionBackgroundOpaque:a.color.blend(_,p),selectionInactiveBackgroundTransparent:p,selectionInactiveBackgroundOpaque:a.color.blend(_,p),scrollbarSliderBackground:a.color.opacity(d,.2),scrollbarSliderHoverBackground:a.color.opacity(d,.4),scrollbarSliderActiveBackground:a.color.opacity(d,.5),overviewRulerBorder:d,ansi:n.DEFAULT_ANSI_COLORS.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this._register(this._optionsService.onSpecificOptionChange("minimumContrastRatio",()=>this._contrastCache.clear())),this._register(this._optionsService.onSpecificOptionChange("theme",()=>this._setTheme(this._optionsService.rawOptions.theme)))}_setTheme(e={}){const t=this._colors;if(t.foreground=m(e.foreground,d),t.background=m(e.background,_),t.cursor=a.color.blend(t.background,m(e.cursor,u)),t.cursorAccent=a.color.blend(t.background,m(e.cursorAccent,f)),t.selectionBackgroundTransparent=m(e.selectionBackground,p),t.selectionBackgroundOpaque=a.color.blend(t.background,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundTransparent=m(e.selectionInactiveBackground,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundOpaque=a.color.blend(t.background,t.selectionInactiveBackgroundTransparent),t.selectionForeground=e.selectionForeground?m(e.selectionForeground,a.NULL_COLOR):void 0,t.selectionForeground===a.NULL_COLOR&&(t.selectionForeground=void 0),a.color.isOpaque(t.selectionBackgroundTransparent)){const e=.3;t.selectionBackgroundTransparent=a.color.opacity(t.selectionBackgroundTransparent,e)}if(a.color.isOpaque(t.selectionInactiveBackgroundTransparent)){const e=.3;t.selectionInactiveBackgroundTransparent=a.color.opacity(t.selectionInactiveBackgroundTransparent,e)}if(t.scrollbarSliderBackground=m(e.scrollbarSliderBackground,a.color.opacity(t.foreground,.2)),t.scrollbarSliderHoverBackground=m(e.scrollbarSliderHoverBackground,a.color.opacity(t.foreground,.4)),t.scrollbarSliderActiveBackground=m(e.scrollbarSliderActiveBackground,a.color.opacity(t.foreground,.5)),t.overviewRulerBorder=m(e.overviewRulerBorder,v),t.ansi=n.DEFAULT_ANSI_COLORS.slice(),t.ansi[0]=m(e.black,n.DEFAULT_ANSI_COLORS[0]),t.ansi[1]=m(e.red,n.DEFAULT_ANSI_COLORS[1]),t.ansi[2]=m(e.green,n.DEFAULT_ANSI_COLORS[2]),t.ansi[3]=m(e.yellow,n.DEFAULT_ANSI_COLORS[3]),t.ansi[4]=m(e.blue,n.DEFAULT_ANSI_COLORS[4]),t.ansi[5]=m(e.magenta,n.DEFAULT_ANSI_COLORS[5]),t.ansi[6]=m(e.cyan,n.DEFAULT_ANSI_COLORS[6]),t.ansi[7]=m(e.white,n.DEFAULT_ANSI_COLORS[7]),t.ansi[8]=m(e.brightBlack,n.DEFAULT_ANSI_COLORS[8]),t.ansi[9]=m(e.brightRed,n.DEFAULT_ANSI_COLORS[9]),t.ansi[10]=m(e.brightGreen,n.DEFAULT_ANSI_COLORS[10]),t.ansi[11]=m(e.brightYellow,n.DEFAULT_ANSI_COLORS[11]),t.ansi[12]=m(e.brightBlue,n.DEFAULT_ANSI_COLORS[12]),t.ansi[13]=m(e.brightMagenta,n.DEFAULT_ANSI_COLORS[13]),t.ansi[14]=m(e.brightCyan,n.DEFAULT_ANSI_COLORS[14]),t.ansi[15]=m(e.brightWhite,n.DEFAULT_ANSI_COLORS[15]),e.extendedAnsi){const i=Math.min(t.ansi.length-16,e.extendedAnsi.length);for(let s=0;ssetTimeout(t,e))},t.disposableTimeout=function(e,t=0,i){const r=setTimeout(()=>{e(),i&&o.dispose()},t),o=(0,s.toDisposable)(()=>{clearTimeout(r)});return i?.add(o),o};const s=i(4812);t.TimeoutTimer=class{constructor(){this._token=-1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,e()},t)}setIfNotSet(e,t){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout(()=>{this._token=-1,e()},t))}},t.MicrotaskTimer=class{constructor(){this._isScheduled=!1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(e){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,e())}))}},t.IntervalTimer=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(e,t,i=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();const s=i.setInterval(()=>{e()},t);this._disposable={dispose:()=>{i.clearInterval(s),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}}},5639(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CircularList=void 0;const s=i(4812),r=i(8636);class o extends s.Disposable{constructor(e){super(),this._maxLength=e,this.onDeleteEmitter=this._register(new r.Emitter),this.onDelete=this.onDeleteEmitter.event,this.onInsertEmitter=this._register(new r.Emitter),this.onInsert=this.onInsertEmitter.event,this.onTrimEmitter=this._register(new r.Emitter),this.onTrim=this.onTrimEmitter.event,this._array=new Array(this._maxLength),this._startIndex=0,this._length=0}get maxLength(){return this._maxLength}set maxLength(e){if(this._maxLength===e)return;const t=new Array(e);for(let i=0;ithis._length)for(let t=this._length;t=e;t--)this._array[this._getCyclicIndex(t+i.length)]=this._array[this._getCyclicIndex(t)];for(let t=0;tthis._maxLength){const e=this._length+i.length-this._maxLength;this._startIndex+=e,this._length=this._maxLength,this.onTrimEmitter.fire(e)}else this._length+=i.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,i){if(!(t<=0)){if(e<0||e>=this._length)throw new Error("start argument out of range");if(e+i<0)throw new Error("Cannot shift elements in list beyond index 0");if(i>0){for(let s=t-1;s>=0;s--)this.set(e+s+i,this.get(e+s));const s=e+t+i-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;s>>0},e.toColor=function(t,i,s,r){return{css:e.toCss(t,i,s,r),rgba:e.toRgba(t,i,s,r)}}}(n||(t.channels=n={})),function(e){function t(e,t){return o=Math.round(255*t),[i,s,r]=c.toChannels(e.rgba),{css:n.toCss(i,s,r,o),rgba:n.toRgba(i,s,r,o)}}e.blend=function(e,t){if(o=(255&t.rgba)/255,1===o)return{css:t.css,rgba:t.rgba};const a=t.rgba>>24&255,h=t.rgba>>16&255,l=t.rgba>>8&255,c=e.rgba>>24&255,d=e.rgba>>16&255,_=e.rgba>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),{css:n.toCss(i,s,r),rgba:n.toRgba(i,s,r)}},e.isOpaque=function(e){return!(255&~e.rgba)},e.ensureContrastRatio=function(e,t,i){const s=c.ensureContrastRatio(e.rgba,t.rgba,i);if(s)return n.toColor(s>>24&255,s>>16&255,s>>8&255)},e.opaque=function(e){const t=(255|e.rgba)>>>0;return[i,s,r]=c.toChannels(t),{css:n.toCss(i,s,r),rgba:t}},e.opacity=t,e.multiplyOpacity=function(e,i){return o=255&e.rgba,t(e,o*i/255)},e.toColorRGB=function(e){return[e.rgba>>24&255,e.rgba>>16&255,e.rgba>>8&255]}}(a||(t.color=a={})),function(e){let t,a;try{const e=document.createElement("canvas");e.width=1,e.height=1;const i=e.getContext("2d",{willReadFrequently:!0});i&&(t=i,t.globalCompositeOperation="copy",a=t.createLinearGradient(0,0,1,1))}catch{}e.toColor=function(e){if(e.match(/#[\da-f]{3,8}/i))switch(e.length){case 4:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),n.toColor(i,s,r);case 5:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),o=parseInt(e.slice(4,5).repeat(2),16),n.toColor(i,s,r,o);case 7:return{css:e,rgba:(parseInt(e.slice(1),16)<<8|255)>>>0};case 9:return{css:e,rgba:parseInt(e.slice(1),16)>>>0}}const h=e.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(h)return i=parseInt(h[1],10),s=parseInt(h[2],10),r=parseInt(h[3],10),o=Math.round(255*(void 0===h[5]?1:parseFloat(h[5]))),n.toColor(i,s,r,o);if("transparent"===e)return{css:"transparent",rgba:0};if(!t||!a)throw new Error("css.toColor: Unsupported css format");if(t.fillStyle=a,t.fillStyle=e,"string"!=typeof t.fillStyle)throw new Error("css.toColor: Unsupported css format");if(t.fillRect(0,0,1,1),[i,s,r,o]=t.getImageData(0,0,1,1).data,255!==o)throw new Error("css.toColor: Unsupported css format");return{rgba:n.toRgba(i,s,r,o),css:e}}}(h||(t.css=h={})),function(e){function t(e,t,i){const s=e/255,r=t/255,o=i/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:Math.pow((r+.055)/1.055,2.4))+.0722*(o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4))}e.relativeLuminance=function(e){return t(e>>16&255,e>>8&255,255&e)},e.relativeLuminance2=t}(l||(t.rgb=l={})),function(e){function t(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c0||a>0||h>0);)n-=Math.max(0,Math.ceil(.1*n)),a-=Math.max(0,Math.ceil(.1*a)),h-=Math.max(0,Math.ceil(.1*h)),c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));return(n<<24|a<<16|h<<8|255)>>>0}function a(e,t,i){const s=e>>24&255,r=e>>16&255,o=e>>8&255;let n=t>>24&255,a=t>>16&255,h=t>>8&255,c=_(l.relativeLuminance2(n,a,h),l.relativeLuminance2(s,r,o));for(;c>>0}e.blend=function(e,t){if(o=(255&t)/255,1===o)return t;const a=t>>24&255,h=t>>16&255,l=t>>8&255,c=e>>24&255,d=e>>16&255,_=e>>8&255;return i=c+Math.round((a-c)*o),s=d+Math.round((h-d)*o),r=_+Math.round((l-_)*o),n.toRgba(i,s,r)},e.ensureContrastRatio=function(e,i,s){const r=l.relativeLuminance(e>>8),o=l.relativeLuminance(i>>8);if(_(r,o)>8));if(n_(r,l.relativeLuminance(t>>8))?o:t}return o}const n=a(e,i,s),h=_(r,l.relativeLuminance(n>>8));if(h_(r,l.relativeLuminance(o>>8))?n:o}return n}},e.reduceLuminance=t,e.increaseLuminance=a,e.toChannels=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}}(c||(t.rgba=c={}))},5777(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CoreTerminal=void 0;const s=i(6501),r=i(6025),o=i(7276),n=i(9640),a=i(56),h=i(4071),l=i(6478),c=i(7428),d=i(6415),_=i(5746),u=i(5882),f=i(2486),p=i(3562),v=i(8811),g=i(8636),m=i(4812);let S=!1;class b extends m.Disposable{get onScroll(){return this._onScrollApi||(this._onScrollApi=this._register(new g.Emitter),this._onScroll.event(e=>{this._onScrollApi?.fire(e.position)})),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(const t in e)this.optionsService.options[t]=e[t]}constructor(e){super(),this._windowsWrappingHeuristics=this._register(new m.MutableDisposable),this._onBinary=this._register(new g.Emitter),this.onBinary=this._onBinary.event,this._onData=this._register(new g.Emitter),this.onData=this._onData.event,this._onLineFeed=this._register(new g.Emitter),this.onLineFeed=this._onLineFeed.event,this._onRender=this._register(new g.Emitter),this.onRender=this._onRender.event,this._onResize=this._register(new g.Emitter),this.onResize=this._onResize.event,this._onWriteParsed=this._register(new g.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._onScroll=this._register(new g.Emitter),this._instantiationService=new r.InstantiationService,this.optionsService=this._register(new a.OptionsService(e)),this._instantiationService.setService(s.IOptionsService,this.optionsService),this._logService=this._register(this._instantiationService.createInstance(o.LogService)),this._instantiationService.setService(s.ILogService,this._logService),this._bufferService=this._register(this._instantiationService.createInstance(n.BufferService)),this._instantiationService.setService(s.IBufferService,this._bufferService),this.coreService=this._register(this._instantiationService.createInstance(h.CoreService)),this._instantiationService.setService(s.ICoreService,this.coreService),this.mouseStateService=this._register(this._instantiationService.createInstance(l.MouseStateService)),this._instantiationService.setService(s.IMouseStateService,this.mouseStateService),this.unicodeService=this._register(this._instantiationService.createInstance(d.UnicodeService)),this.unicodeService.register(new c.UnicodeV6),this._instantiationService.setService(s.IUnicodeService,this.unicodeService),this._charsetService=this._instantiationService.createInstance(_.CharsetService),this._instantiationService.setService(s.ICharsetService,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(v.OscLinkService),this._instantiationService.setService(s.IOscLinkService,this._oscLinkService),this._inputHandler=this._register(new f.InputHandler(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.mouseStateService,this.unicodeService)),this._register(g.EventUtils.forward(this._inputHandler.onLineFeed,this._onLineFeed)),this._register(g.EventUtils.forward(this._bufferService.onResize,this._onResize)),this._register(g.EventUtils.forward(this.coreService.onData,this._onData)),this._register(g.EventUtils.forward(this.coreService.onBinary,this._onBinary)),this._register(this.coreService.onRequestScrollToBottom(()=>this.scrollToBottom(!0))),this._register(this.coreService.onUserInput(()=>this._writeBuffer.handleUserInput())),this._register(this.optionsService.onMultipleOptionChange(["windowsPty"],()=>this._handleWindowsPtyOptionChange())),this._register(this._bufferService.onScroll(()=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)})),this._writeBuffer=this._register(new p.WriteBuffer((e,t)=>this._inputHandler.parse(e,t))),this._register(g.EventUtils.forward(this._writeBuffer.onWriteParsed,this._onWriteParsed))}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=s.LogLevelEnum.WARN&&!S&&(this._logService.warn("writeSync is unreliable and will be removed soon."),S=!0),this._writeBuffer.writeSync(e,t)}input(e,t=!0){this.coreService.triggerDataEvent(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,2),t=Math.max(t,1),this._writeBuffer.flushSync(),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t){this._bufferService.scrollLines(e,t)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}registerApcHandler(e,t){return this._inputHandler.registerApcHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.mouseStateService.reset()}_handleWindowsPtyOptionChange(){let e=!1;const t=this.optionsService.rawOptions.windowsPty;t&&void 0!==t.backend&&void 0!==t.buildNumber&&(e=!!("conpty"===t.backend&&t.buildNumber<21376)),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){const e=[];e.push(this.onLineFeed(u.updateWindowsModeWrappedState.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:"H"},()=>((0,u.updateWindowsModeWrappedState)(this._bufferService),!1))),this._windowsWrappingHeuristics.value=(0,m.toDisposable)(()=>{for(const t of e)t.dispose()})}}}t.CoreTerminal=b},8636(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EventUtils=t.Emitter=void 0;const s=i(4812);var r;t.Emitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=(e,t,i)=>{if(this._disposed)return(0,s.toDisposable)(()=>{});const r={fn:e,thisArgs:t};this._listeners.push(r);const o=(0,s.toDisposable)(()=>{const e=this._listeners.indexOf(r);-1!==e&&this._listeners.splice(e,1)});return i&&(Array.isArray(i)?i.push(o):i.add(o)),o}),this._event}fire(e){if(!this._disposed)switch(this._listeners.length){case 0:return;case 1:{const{fn:t,thisArgs:i}=this._listeners[0];return void t.call(i,e)}default:{const t=this._listeners.slice();for(const{fn:i,thisArgs:s}of t)i.call(s,e)}}}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},function(e){e.forward=function(e,t){return e(e=>t.fire(e))},e.map=function(e,t){return(i,s,r)=>e(e=>i.call(s,t(e)),void 0,r)},e.any=function(...e){return(t,i,r)=>{const o=new s.DisposableStore;for(const s of e)o.add(s(e=>t.call(i,e)));return r&&(Array.isArray(r)?r.push(o):r.add(o)),o}},e.runAndSubscribe=function(e,t,i){return t(i),e(e=>t(e))}}(r||(t.EventUtils=r={}))},2486(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.InputHandler=t.WindowsOptionsReportType=void 0,t.isValidColorIndex=x;const o=i(6760),n=i(6717),a=i(4812),h=i(726),l=i(6107),c=i(8938),d=i(3055),_=i(5451),u=i(6501),f=i(6415),p=i(1346),v=i(9823),g=i(2607),m=i(8693),S=i(8636),b=i(7804),y={"(":0,")":1,"*":2,"+":3,"-":1,".":2};function w(e,t){if(e>24)return t.setWinLines||!1;switch(e){case 1:return!!t.restoreWin;case 2:return!!t.minimizeWin;case 3:return!!t.setWinPosition;case 4:return!!t.setWinSizePixels;case 5:return!!t.raiseWin;case 6:return!!t.lowerWin;case 7:return!!t.refreshWin;case 8:return!!t.setWinSizeChars;case 9:return!!t.maximizeWin;case 10:return!!t.fullscreenWin;case 11:return!!t.getWinState;case 13:return!!t.getWinPosition;case 14:return!!t.getWinSizePixels;case 15:return!!t.getScreenSizePixels;case 16:return!!t.getCellSizePixels;case 18:return!!t.getWinSizeChars;case 19:return!!t.getScreenSizeChars;case 20:return!!t.getIconTitle;case 21:return!!t.getWinTitle;case 22:return!!t.pushTitle;case 23:return!!t.popTitle;case 24:return!!t.setWinLines}return!1}var C;!function(e){e[e.GET_WIN_SIZE_PIXELS=0]="GET_WIN_SIZE_PIXELS",e[e.GET_CELL_SIZE_PIXELS=1]="GET_CELL_SIZE_PIXELS"}(C||(t.WindowsOptionsReportType=C={}));let k=0;class D extends a.Disposable{getAttrData(){return this._curAttrData}constructor(e,t,i,s,r,a,c,d,_=new n.EscapeSequenceParser){super(),this._bufferService=e,this._charsetService=t,this._coreService=i,this._logService=s,this._optionsService=r,this._oscLinkService=a,this._mouseStateService=c,this._unicodeService=d,this._parser=_,this._parseBuffer=new Uint32Array(4096),this._stringDecoder=new h.StringToUtf32,this._utf8Decoder=new h.Utf8ToUtf32,this._windowTitle="",this._iconName="",this._windowTitleStack=[],this._iconNameStack=[],this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone(),this._onRequestBell=this._register(new S.Emitter),this.onRequestBell=this._onRequestBell.event,this._onRequestRefreshRows=this._register(new S.Emitter),this.onRequestRefreshRows=this._onRequestRefreshRows.event,this._onRequestReset=this._register(new S.Emitter),this.onRequestReset=this._onRequestReset.event,this._onRequestSendFocus=this._register(new S.Emitter),this.onRequestSendFocus=this._onRequestSendFocus.event,this._onRequestSyncScrollBar=this._register(new S.Emitter),this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event,this._onRequestWindowsOptionsReport=this._register(new S.Emitter),this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event,this._onA11yChar=this._register(new S.Emitter),this.onA11yChar=this._onA11yChar.event,this._onA11yTab=this._register(new S.Emitter),this.onA11yTab=this._onA11yTab.event,this._onCursorMove=this._register(new S.Emitter),this.onCursorMove=this._onCursorMove.event,this._onLineFeed=this._register(new S.Emitter),this.onLineFeed=this._onLineFeed.event,this._onScroll=this._register(new S.Emitter),this.onScroll=this._onScroll.event,this._onTitleChange=this._register(new S.Emitter),this.onTitleChange=this._onTitleChange.event,this._onColor=this._register(new S.Emitter),this.onColor=this._onColor.event,this._onRequestColorSchemeQuery=this._register(new S.Emitter),this.onRequestColorSchemeQuery=this._onRequestColorSchemeQuery.event,this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0},this._specialColors=[256,257,258],this._register(this._parser),this._dirtyRowTracker=new E(this._bufferService),this._activeBuffer=this._bufferService.buffer,this._register(this._bufferService.buffers.onBufferActivate(e=>this._activeBuffer=e.activeBuffer)),this._parser.setCsiHandlerFallback((e,t)=>{this._logService.debug("Unknown CSI code: ",{identifier:this._parser.identToString(e),params:t.toArray()})}),this._parser.setEscHandlerFallback(e=>{this._logService.debug("Unknown ESC code: ",{identifier:this._parser.identToString(e)})}),this._parser.setExecuteHandlerFallback(e=>{this._logService.debug("Unknown EXECUTE code: ",{code:e})}),this._parser.setOscHandlerFallback((e,t,i)=>{this._logService.debug("Unknown OSC code: ",{identifier:e,action:t,data:i})}),this._parser.setDcsHandlerFallback((e,t,i)=>{"HOOK"===t&&(i=i.toArray()),this._logService.debug("Unknown DCS code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setApcHandlerFallback((e,t,i)=>{this._logService.debug("Unknown APC code: ",{identifier:this._parser.identToString(e),action:t,payload:i})}),this._parser.setPrintHandler((e,t,i)=>this.print(e,t,i)),this._parser.registerCsiHandler({final:"@"},e=>this.insertChars(e)),this._parser.registerCsiHandler({intermediates:" ",final:"@"},e=>this.scrollLeft(e)),this._parser.registerCsiHandler({final:"A"},e=>this.cursorUp(e)),this._parser.registerCsiHandler({intermediates:" ",final:"A"},e=>this.scrollRight(e)),this._parser.registerCsiHandler({final:"B"},e=>this.cursorDown(e)),this._parser.registerCsiHandler({final:"C"},e=>this.cursorForward(e)),this._parser.registerCsiHandler({final:"D"},e=>this.cursorBackward(e)),this._parser.registerCsiHandler({final:"E"},e=>this.cursorNextLine(e)),this._parser.registerCsiHandler({final:"F"},e=>this.cursorPrecedingLine(e)),this._parser.registerCsiHandler({final:"G"},e=>this.cursorCharAbsolute(e)),this._parser.registerCsiHandler({final:"H"},e=>this.cursorPosition(e)),this._parser.registerCsiHandler({final:"I"},e=>this.cursorForwardTab(e)),this._parser.registerCsiHandler({final:"J"},e=>this.eraseInDisplay(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"J"},e=>this.eraseInDisplay(e,!0)),this._parser.registerCsiHandler({final:"K"},e=>this.eraseInLine(e,!1)),this._parser.registerCsiHandler({prefix:"?",final:"K"},e=>this.eraseInLine(e,!0)),this._parser.registerCsiHandler({final:"L"},e=>this.insertLines(e)),this._parser.registerCsiHandler({final:"M"},e=>this.deleteLines(e)),this._parser.registerCsiHandler({final:"P"},e=>this.deleteChars(e)),this._parser.registerCsiHandler({final:"S"},e=>this.scrollUp(e)),this._parser.registerCsiHandler({final:"T"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"X"},e=>this.eraseChars(e)),this._parser.registerCsiHandler({final:"Z"},e=>this.cursorBackwardTab(e)),this._parser.registerCsiHandler({final:"^"},e=>this.scrollDown(e)),this._parser.registerCsiHandler({final:"`"},e=>this.charPosAbsolute(e)),this._parser.registerCsiHandler({final:"a"},e=>this.hPositionRelative(e)),this._parser.registerCsiHandler({final:"b"},e=>this.repeatPrecedingCharacter(e)),this._parser.registerCsiHandler({final:"c"},e=>this.sendDeviceAttributesPrimary(e)),this._parser.registerCsiHandler({prefix:">",final:"c"},e=>this.sendDeviceAttributesSecondary(e)),this._parser.registerCsiHandler({final:"d"},e=>this.linePosAbsolute(e)),this._parser.registerCsiHandler({final:"e"},e=>this.vPositionRelative(e)),this._parser.registerCsiHandler({final:"f"},e=>this.hVPosition(e)),this._parser.registerCsiHandler({final:"g"},e=>this.tabClear(e)),this._parser.registerCsiHandler({final:"h"},e=>this.setMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"h"},e=>this.setModePrivate(e)),this._parser.registerCsiHandler({final:"l"},e=>this.resetMode(e)),this._parser.registerCsiHandler({prefix:"?",final:"l"},e=>this.resetModePrivate(e)),this._parser.registerCsiHandler({final:"m"},e=>this.charAttributes(e)),this._parser.registerCsiHandler({final:"n"},e=>this.deviceStatus(e)),this._parser.registerCsiHandler({prefix:"?",final:"n"},e=>this.deviceStatusPrivate(e)),this._parser.registerCsiHandler({intermediates:"!",final:"p"},e=>this.softReset(e)),this._parser.registerCsiHandler({prefix:">",final:"q"},e=>this.sendXtVersion(e)),this._parser.registerCsiHandler({intermediates:" ",final:"q"},e=>this.setCursorStyle(e)),this._parser.registerCsiHandler({final:"r"},e=>this.setScrollRegion(e)),this._parser.registerCsiHandler({final:"s"},e=>this.saveCursor(e)),this._parser.registerCsiHandler({final:"t"},e=>this.windowOptions(e)),this._parser.registerCsiHandler({final:"u"},e=>this.restoreCursor(e)),this._parser.registerCsiHandler({intermediates:"'",final:"}"},e=>this.insertColumns(e)),this._parser.registerCsiHandler({intermediates:"'",final:"~"},e=>this.deleteColumns(e)),this._parser.registerCsiHandler({intermediates:'"',final:"q"},e=>this.selectProtected(e)),this._parser.registerCsiHandler({intermediates:"$",final:"p"},e=>this.requestMode(e,!0)),this._parser.registerCsiHandler({prefix:"?",intermediates:"$",final:"p"},e=>this.requestMode(e,!1)),this._parser.registerCsiHandler({prefix:"=",final:"u"},e=>this.kittyKeyboardSet(e)),this._parser.registerCsiHandler({prefix:"?",final:"u"},e=>this.kittyKeyboardQuery(e)),this._parser.registerCsiHandler({prefix:">",final:"u"},e=>this.kittyKeyboardPush(e)),this._parser.registerCsiHandler({prefix:"<",final:"u"},e=>this.kittyKeyboardPop(e)),this._parser.setExecuteHandler("",()=>this.bell()),this._parser.setExecuteHandler("\n",()=>this.lineFeed()),this._parser.setExecuteHandler("\v",()=>this.lineFeed()),this._parser.setExecuteHandler("\f",()=>this.lineFeed()),this._parser.setExecuteHandler("\r",()=>this.carriageReturn()),this._parser.setExecuteHandler("\b",()=>this.backspace()),this._parser.setExecuteHandler("\t",()=>this.tab()),this._parser.setExecuteHandler("",()=>this.shiftOut()),this._parser.setExecuteHandler("",()=>this.shiftIn()),this._parser.setExecuteHandler("„",()=>this.index()),this._parser.setExecuteHandler("…",()=>this.nextLine()),this._parser.setExecuteHandler("ˆ",()=>this.tabSet()),this._parser.registerOscHandler(0,new p.OscHandler(e=>(this.setTitle(e),this.setIconName(e),!0))),this._parser.registerOscHandler(1,new p.OscHandler(e=>this.setIconName(e))),this._parser.registerOscHandler(2,new p.OscHandler(e=>this.setTitle(e))),this._parser.registerOscHandler(4,new p.OscHandler(e=>this.setOrReportIndexedColor(e))),this._parser.registerOscHandler(8,new p.OscHandler(e=>this.setHyperlink(e))),this._parser.registerOscHandler(10,new p.OscHandler(e=>this.setOrReportFgColor(e))),this._parser.registerOscHandler(11,new p.OscHandler(e=>this.setOrReportBgColor(e))),this._parser.registerOscHandler(12,new p.OscHandler(e=>this.setOrReportCursorColor(e))),this._parser.registerOscHandler(104,new p.OscHandler(e=>this.restoreIndexedColor(e))),this._parser.registerOscHandler(110,new p.OscHandler(e=>this.restoreFgColor(e))),this._parser.registerOscHandler(111,new p.OscHandler(e=>this.restoreBgColor(e))),this._parser.registerOscHandler(112,new p.OscHandler(e=>this.restoreCursorColor(e))),this._parser.registerEscHandler({final:"7"},()=>this.saveCursor()),this._parser.registerEscHandler({final:"8"},()=>this.restoreCursor()),this._parser.registerEscHandler({final:"D"},()=>this.index()),this._parser.registerEscHandler({final:"E"},()=>this.nextLine()),this._parser.registerEscHandler({final:"H"},()=>this.tabSet()),this._parser.registerEscHandler({final:"M"},()=>this.reverseIndex()),this._parser.registerEscHandler({final:"="},()=>this.keypadApplicationMode()),this._parser.registerEscHandler({final:">"},()=>this.keypadNumericMode()),this._parser.registerEscHandler({final:"c"},()=>this.fullReset()),this._parser.registerEscHandler({final:"n"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"o"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"|"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"}"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"~"},()=>this.setgLevel(1)),this._parser.registerEscHandler({intermediates:"%",final:"@"},()=>this.selectDefaultCharset()),this._parser.registerEscHandler({intermediates:"%",final:"G"},()=>this.selectDefaultCharset());for(const e in o.CHARSETS)this._parser.registerEscHandler({intermediates:"(",final:e},()=>this.selectCharset("("+e)),this._parser.registerEscHandler({intermediates:")",final:e},()=>this.selectCharset(")"+e)),this._parser.registerEscHandler({intermediates:"*",final:e},()=>this.selectCharset("*"+e)),this._parser.registerEscHandler({intermediates:"+",final:e},()=>this.selectCharset("+"+e)),this._parser.registerEscHandler({intermediates:"-",final:e},()=>this.selectCharset("-"+e)),this._parser.registerEscHandler({intermediates:".",final:e},()=>this.selectCharset("."+e)),this._parser.registerEscHandler({intermediates:"/",final:e},()=>this.selectCharset("/"+e));this._parser.registerEscHandler({intermediates:"#",final:"8"},()=>this.screenAlignmentPattern()),this._parser.setErrorHandler(e=>(this._logService.error("Parsing error: ",e),e)),this._parser.registerDcsHandler({intermediates:"$",final:"q"},new v.DcsHandler((e,t)=>this.requestStatusString(e,t)))}_preserveStack(e,t,i,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=i,this._parseStack.position=s}_logSlowResolvingAsync(e){if(this._logService.logLevel<=u.LogLevelEnum.WARN){let t;const i=new Promise((e,i)=>{t=setTimeout(()=>i("#SLOW_TIMEOUT"),5e3)});Promise.race([e,i]).then(()=>{void 0!==t&&clearTimeout(t)},e=>{if(void 0!==t&&clearTimeout(t),"#SLOW_TIMEOUT"!==e)throw e;console.warn("async parser handler taking longer than 5000 ms")})}}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let i,s=this._activeBuffer.x,r=this._activeBuffer.y,o=0;const n=this._parseStack.paused;if(n){if(i=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(i),i;s=this._parseStack.cursorStartX,r=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>131072&&(o=this._parseStack.position+131072)}if(this._logService.logLevel<=u.LogLevelEnum.DEBUG&&this._logService.debug("parsing data "+("string"==typeof e?` "${e}"`:` "${Array.prototype.map.call(e,e=>String.fromCharCode(e)).join("")}"`)),this._logService.logLevel===u.LogLevelEnum.TRACE&&this._logService.trace("parsing data (codes)","string"==typeof e?e.split("").map(e=>e.charCodeAt(0)):e),this._parseBuffer.length131072)for(let t=o;t0&&2===p.getWidth(this._activeBuffer.x-1)&&p.setCellFromCodepoint(this._activeBuffer.x-1,0,1,u);let v=this._parser.precedingJoinState;for(let g=t;ga)if(d){const e=p;let t=this._activeBuffer.x-m;if(this._activeBuffer.x=m,this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData(),!0)):(this._activeBuffer.y>=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),p=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y),!p)return;for(m>0&&p instanceof l.BufferLine&&p.copyCellsFrom(e,t,0,m,!1);t=0;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u);continue}if(_&&(p.insertCells(this._activeBuffer.x,r-m,this._activeBuffer.getNullCell(u)),2===p.getWidth(a-1)&&p.setCellFromCodepoint(a-1,c.NULL_CELL_CODE,c.NULL_CELL_WIDTH,u)),p.setCellFromCodepoint(this._activeBuffer.x++,s,r,u),r>0)for(;--r;)p.setCellFromCodepoint(this._activeBuffer.x++,0,0,u)}this._parser.precedingJoinState=v,this._activeBuffer.x0&&0===p.getWidth(this._activeBuffer.x)&&!p.hasContent(this._activeBuffer.x)&&p.setCellFromCodepoint(this._activeBuffer.x,0,1,u),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return"t"!==e.final||e.prefix||e.intermediates?this._parser.registerCsiHandler(e,t):this._parser.registerCsiHandler(e,e=>!w(e.params[0],this._optionsService.rawOptions.windowOptions)||t(e))}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new v.DcsHandler(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new p.OscHandler(t))}registerApcHandler(e,t){return this._parser.registerApcHandler(e,new g.ApcHandler(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(0===this._activeBuffer.x&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)?.isWrapped){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;const e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){const t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){const t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){const t=e.params[0];return 0===t?delete this._activeBuffer.tabs[this._activeBuffer.x]:3===t&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){const t=e.params[0];return 1===t&&(this._curAttrData.bg|=536870912),2!==t&&0!==t||(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,i,s=!1,r=!1){const o=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);o&&(o.replaceCells(t,i,this._activeBuffer.getNullCell(this._eraseAttrData()),r),s&&(o.isWrapped=!1))}_resetBufferLine(e,t=!1){const i=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);i&&(i.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),i.isWrapped=!1)}eraseInDisplay(e,t=!1){let i;switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:for(i=this._activeBuffer.y,this._dirtyRowTracker.markDirty(i),this._eraseInBufferLine(i++,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);i=this._bufferService.cols){const e=this._activeBuffer.lines.get(i+1);e&&(e.isWrapped=!1)}for(;i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 2:if(this._optionsService.rawOptions.scrollOnEraseInDisplay){for(i=this._bufferService.rows,this._dirtyRowTracker.markRangeDirty(0,i-1);i--;){const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+i);if(e?.getTrimmedLength())break}for(;i>=0;i--)this._bufferService.scroll(this._eraseAttrData())}else{for(i=this._bufferService.rows,this._dirtyRowTracker.markDirty(i-1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0)}break;case 3:const e=this._activeBuffer.lines.length-this._bufferService.rows;e>0&&(this._activeBuffer.lines.trimStart(e),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-e,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-e,0),this._onScroll.fire(0))}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t)}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y65535?2:1}let h=a;for(let e=1;e0||(this._is("xterm")||this._is("rxvt-unicode")||this._is("screen")?this._coreService.triggerDataEvent("[?1;2c"):this._is("linux")&&this._coreService.triggerDataEvent("[?6c")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is("xterm")?this._coreService.triggerDataEvent("[>0;276;0c"):this._is("rxvt-unicode")?this._coreService.triggerDataEvent("[>85;95;0c"):this._is("linux")?this._coreService.triggerDataEvent(e.params[0]+"c"):this._is("screen")&&this._coreService.triggerDataEvent("[>83;40003;0c")),!0}sendXtVersion(e){return e.params[0]>0||this._coreService.triggerDataEvent(`P>|xterm.js(${b.XTERM_VERSION})\\`),!0}_is(e){return(this._optionsService.rawOptions.termName+"").startsWith(e)}setMode(e){for(let t=0;t(o.triggerDataEvent(`[${t?"":"?"}${e};${i}$y`),!0),_=e=>e?1:2,u=e.params[0];return t?d(u,2===u?4:4===u?_(o.modes.insertMode):12===u?3:20===u?_(c.convertEol):0):1===u?d(u,_(i.applicationCursorKeys)):3===u?d(u,c.windowOptions.setWinLines?80===a?2:132===a?1:0:0):6===u?d(u,_(i.origin)):7===u?d(u,_(i.wraparound)):8===u?d(u,3):9===u?d(u,_("X10"===s)):12===u?d(u,_(c.cursorBlink)):25===u?d(u,_(!o.isCursorHidden)):45===u?d(u,_(i.reverseWraparound)):66===u?d(u,_(i.applicationKeypad)):67===u?d(u,4):1e3===u?d(u,_("VT200"===s)):1002===u?d(u,_("DRAG"===s)):1003===u?d(u,_("ANY"===s)):1004===u?d(u,_(i.sendFocus)):1005===u?d(u,4):1006===u?d(u,_("SGR"===r)):1015===u?d(u,4):1016===u?d(u,_("SGR_PIXELS"===r)):1048===u?d(u,1):47===u||1047===u||1049===u?d(u,_(h===l)):2004===u?d(u,_(i.bracketedPasteMode)):2026===u?d(u,_(i.synchronizedOutput)):9001===u&&this._optionsService.rawOptions.vtExtensions?.win32InputMode?d(u,_(i.win32InputMode)):d(u,0)}_updateAttrColor(e,t,i,s,r){return 2===t?(e|=50331648,e&=-16777216,e|=_.AttributeData.fromColorRGB([i,s,r])):5===t&&(e&=-67108864,e|=33554432|255&i),e}_extractColor(e,t,i){const s=[0,0,-1,0,0,0];let r=0,o=0;do{if(s[o+r]=e.params[t+o],e.hasSubParams(t+o)){const i=e.getSubParams(t+o);let n=0;do{5===s[1]&&(r=1),s[o+n+1+r]=i[n]}while(++n=2||2===s[1]&&o+r>=5)break;s[1]&&(r=1)}while(++o+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,0===e&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=l.DEFAULT_ATTR_DATA.fg,e.bg=l.DEFAULT_ATTR_DATA.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(1===e.length&&0===e.params[0])return this._processSGR0(this._curAttrData),!0;const t=e.length;let i;const s=this._curAttrData;for(let r=0;r=30&&i<=37?(s.fg&=-67108864,s.fg|=16777216|i-30):i>=40&&i<=47?(s.bg&=-67108864,s.bg|=16777216|i-40):i>=90&&i<=97?(s.fg&=-67108864,s.fg|=16777224|i-90):i>=100&&i<=107?(s.bg&=-67108864,s.bg|=16777224|i-100):0===i?this._processSGR0(s):1===i?s.fg|=134217728:3===i?s.bg|=67108864:4===i?(s.fg|=268435456,this._processUnderline(e.hasSubParams(r)?e.getSubParams(r)[0]:1,s)):5===i?s.fg|=536870912:7===i?s.fg|=67108864:8===i?s.fg|=1073741824:9===i?s.fg|=2147483648:2===i?s.bg|=134217728:21===i?this._processUnderline(2,s):22===i?(s.fg&=-134217729,s.bg&=-134217729):23===i?s.bg&=-67108865:24===i?(s.fg&=-268435457,this._processUnderline(0,s)):25===i?s.fg&=-536870913:27===i?s.fg&=-67108865:28===i?s.fg&=-1073741825:29===i?s.fg&=2147483647:39===i?(s.fg&=-67108864,s.fg|=16777215&l.DEFAULT_ATTR_DATA.fg):49===i?(s.bg&=-67108864,s.bg|=16777215&l.DEFAULT_ATTR_DATA.bg):38===i||48===i||58===i?r+=this._extractColor(e,r,s):53===i?s.bg|=1073741824:55===i?s.bg&=-1073741825:221===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.fg&=-134217729:222===i&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??1)?s.bg&=-134217729:59===i?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):this._logService.debug("Unknown SGR attribute: %d.",i);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent("");break;case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[${e};${t}R`)}return!0}deviceStatusPrivate(e){switch(e.params[0]){case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`[?${e};${t}R`);break;case 15:case 25:case 26:case 53:break;case 996:(this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery??1)&&this._onRequestColorSchemeQuery.fire()}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){const t=0===e.length?1:e.params[0];if(0===t)this._coreService.decPrivateModes.cursorStyle=void 0,this._coreService.decPrivateModes.cursorBlink=void 0;else{switch(t){case 1:case 2:this._coreService.decPrivateModes.cursorStyle="block";break;case 3:case 4:this._coreService.decPrivateModes.cursorStyle="underline";break;case 5:case 6:this._coreService.decPrivateModes.cursorStyle="bar"}const e=t%2==1;this._coreService.decPrivateModes.cursorBlink=e}return!0}setScrollRegion(e){const t=e.params[0]||1;let i;return(e.length<2||(i=e.params[1])>this._bufferService.rows||0===i)&&(i=this._bufferService.rows),i>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=i-1,this._setCursor(0,0)),!0}windowOptions(e){if(!w(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;const t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:2!==t&&this._onRequestWindowsOptionsReport.fire(C.GET_WIN_SIZE_PIXELS);break;case 16:this._onRequestWindowsOptionsReport.fire(C.GET_CELL_SIZE_PIXELS);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:0!==t&&2!==t||(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),0!==t&&1!==t||(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:0!==t&&2!==t||this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),0!==t&&1!==t||this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop())}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._activeBuffer.savedCharsets=this._charsetService.charsets.slice(),this._activeBuffer.savedGlevel=this._charsetService.glevel,this._activeBuffer.savedOriginMode=this._coreService.decPrivateModes.origin,this._activeBuffer.savedWraparoundMode=this._coreService.decPrivateModes.wraparound,!0}restoreCursor(e){this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg;for(let e=0;e1;){const e=i.shift(),s=i.shift();if(/^\d+$/.exec(e)){const i=parseInt(e,10);if(x(i))if("?"===s)t.push({type:0,index:i});else{const e=(0,m.parseColor)(s);e&&t.push({type:1,index:i,color:e})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){const t=e.indexOf(";");if(-1===t)return!0;const i=e.slice(0,t).trim(),s=e.slice(t+1);return s?this._createHyperlink(i,s):!i.trim()&&this._finishHyperlink()}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();const i=e.split(":");let s;const r=i.findIndex(e=>e.startsWith("id="));return-1!==r&&(s=i[r].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){const i=e.split(";");for(let e=0;e=this._specialColors.length);++e,++t)if("?"===i[e])this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{const s=(0,m.parseColor)(i[e]);s&&this._onColor.fire([{type:1,index:this._specialColors[t],color:s}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;const t=[],i=e.split(";");for(let e=0;e=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){const e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=67108863&this._curAttrData.bg,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){const e=new d.CellData;e.content=1<<22|"E".charCodeAt(0),e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`${e}\\`),!0))('"q'===e?`P1$r${this._curAttrData.isProtected()?1:0}"q`:'"p'===e?'P1$r61;1"p':"r"===e?`P1$r${i.scrollTop+1};${i.scrollBottom+1}r`:"m"===e?"P1$r0m":" q"===e?`P1$r${{block:2,underline:4,bar:6}[s.cursorStyle]-(s.cursorBlink?1:0)} q`:"P0$r")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}kittyKeyboardSet(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=e.length>1&&e.params[1]||1,s=this._coreService.kittyKeyboard;switch(i){case 1:s.flags=t;break;case 2:s.flags|=t;break;case 3:s.flags&=~t}return!0}kittyKeyboardQuery(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=this._coreService.kittyKeyboard.flags;return this._coreService.triggerDataEvent(`[?${t}u`),!0}kittyKeyboardPush(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=e.params[0]||0,i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;return s.length>=16&&s.shift(),s.push(i.flags),i.flags=t,!0}kittyKeyboardPop(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;const t=Math.max(1,e.params[0]||1),i=this._coreService.kittyKeyboard,s=this._bufferService.buffer===this._bufferService.buffers.alt?i.altStack:i.mainStack;for(let e=0;e0;e++)i.flags=s.pop();return 0===s.length&&t>0&&(i.flags=0),!0}}t.InputHandler=D;let E=class{constructor(e){this._bufferService=e,this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(e){ethis.end&&(this.end=e)}markRangeDirty(e,t){e>t&&(k=e,e=t,t=k),ethis.end&&(this.end=t)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};function x(e){return 0<=e&&e<256}E=s([r(0,u.IBufferService)],E)},4812(e,t){function i(e){return{dispose:e}}function s(e){if(!e)return e;if(Array.isArray(e)){for(const t of e)t.dispose();return[]}return e.dispose(),e}Object.defineProperty(t,"__esModule",{value:!0}),t.MutableDisposable=t.Disposable=t.DisposableStore=void 0,t.toDisposable=i,t.dispose=s,t.combinedDisposable=function(...e){return i(()=>s(e))};class r{constructor(){this._disposables=new Set,this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(e){return this._isDisposed?e.dispose():this._disposables.add(e),e}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.clear()}}clear(){for(const e of this._disposables)e.dispose();this._disposables.clear()}}t.DisposableStore=r;class o{constructor(){this._store=new r}dispose(){this._store.dispose()}_register(e){return this._store.add(e)}}t.Disposable=o,o.None=Object.freeze({dispose(){}}),t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}}},7710(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.FourKeyMap=t.TwoKeyMap=void 0;class i{constructor(){this._data={}}set(e,t,i){this._data[e]||(this._data[e]={}),this._data[e][t]=i}get(e,t){return this._data[e]?this._data[e][t]:void 0}clear(){this._data={}}}t.TwoKeyMap=i,t.FourKeyMap=class{constructor(){this._data=new i}set(e,t,s,r,o){this._data.get(e,t)||this._data.set(e,t,new i),this._data.get(e,t).set(s,r,o)}get(e,t,i,s){return this._data.get(e,t)?.get(i,s)}clear(){this._data.clear()}}},701(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.isChromeOS=t.isLinux=t.isWindows=t.isMac=t.isSafari=t.isLegacyEdge=t.isChrome=t.isFirefox=t.isNode=void 0,t.getZoomFactor=function(e){return 1},t.getSafariVersion=function(){if(!t.isSafari)return 0;const e=i.match(/Version\/(\d+)/);return null===e||e.length<2?0:parseInt(e[1],10)},t.isNode=!("undefined"==typeof process||!("title"in process)||"undefined"!=typeof navigator&&!navigator.userAgent.startsWith("Node.js/"));const i=t.isNode?"node":navigator.userAgent,s=t.isNode?"node":navigator.platform;t.isFirefox=i.includes("Firefox"),t.isChrome=i.includes("Chrome"),t.isLegacyEdge=i.includes("Edge"),t.isSafari=/^((?!chrome|android).)*safari/i.test(i),t.isMac=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(s),t.isWindows=["Windows","Win16","Win32","WinCE"].includes(s),t.isLinux=s.indexOf("Linux")>=0,t.isChromeOS=/\bCrOS\b/.test(i)},3087(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.SortedList=void 0;const s=i(6168);let r=0;t.SortedList=class{constructor(e,t){this._getKey=e,this._array=[],this._insertedValues=[],this._isFlushingInserted=!1,this._deletedIndices=[],this._isFlushingDeleted=!1,this._flushInsertedTask=new s.IdleTaskQueue(t),this._flushDeletedTask=new s.IdleTaskQueue(t)}clear(){this._array.length=0,this._insertedValues.length=0,this._flushInsertedTask.clear(),this._isFlushingInserted=!1,this._deletedIndices.length=0,this._flushDeletedTask.clear(),this._isFlushingDeleted=!1}insert(e){this._flushCleanupDeleted(),0===this._insertedValues.length&&this._flushInsertedTask.enqueue(()=>this._flushInserted()),this._insertedValues.push(e)}_flushInserted(){const e=this._insertedValues.sort((e,t)=>this._getKey(e)-this._getKey(t));let t=0,i=0;const s=new Array(this._array.length+this._insertedValues.length);for(let r=0;r=this._array.length||this._getKey(e[t])<=this._getKey(this._array[i])?(s[r]=e[t],t++):s[r]=this._array[i++];this._array=s,this._insertedValues.length=0}_flushCleanupInserted(){!this._isFlushingInserted&&this._insertedValues.length>0&&this._flushInsertedTask.flush()}delete(e){if(this._flushCleanupInserted(),0===this._array.length)return!1;const t=this._getKey(e);return void 0!==t&&(!!this._deleteAtKey(e,t)||0!==this._deletedIndices.length&&(this._flushCleanupDeleted(),this._deleteAtKey(e,t)))}_deleteAtKey(e,t){if(r=this._search(t),-1===r)return!1;if(this._getKey(this._array[r])!==t)return!1;do{if(this._array[r]===e)return 0===this._deletedIndices.length&&this._flushDeletedTask.enqueue(()=>this._flushDeleted()),this._deletedIndices.push(r),!0}while(++re-t);let t=0;const i=new Array(this._array.length-e.length);let s=0;for(let r=0;r0&&this._flushDeletedTask.flush()}*getKeyIterator(e){if(this._flushCleanupInserted(),this._flushCleanupDeleted(),0!==this._array.length&&(r=this._search(e),!(r<0||r>=this._array.length)&&this._getKey(this._array[r])===e))do{yield this._array[r]}while(++r=this._array.length)&&this._getKey(this._array[r])===e))do{t(this._array[r])}while(++r=t;){let s=t+i>>1;const r=this._getKey(this._array[s]);if(r>e)i=s-1;else{if(!(r0&&this._getKey(this._array[s-1])===e;)s--;return s}t=s+1}}return t}}},4220(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.LimitedStringBuilder=t.StringBuilder=void 0;class i{constructor(){this._chunks=[],this._length=0}get length(){return this._length}reset(){this._chunks.length=0,this._length=0}append(e){this._chunks.push(e),this._length+=e.length}toString(){return this._chunks.join("")}}t.StringBuilder=i,t.LimitedStringBuilder=class{constructor(e){this._limit=e,this._builder=new i}get length(){return this._builder.length}get limit(){return this._limit}reset(){this._builder.reset()}append(e){return this._builder.append(e),this._builder.length>this._limit&&(this._builder.reset(),!0)}toString(){return this._builder.toString()}}},6168(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DebouncedIdleTask=t.IdleTaskQueue=t.PriorityTaskQueue=void 0;class i{constructor(e){this._tasks=[],this._i=0,this._logService=e}enqueue(e){this._tasks.push(e),this._start()}flush(){for(;this._ii)return r-t<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-t))}ms`),void this._start();r=i}this.clear()}}class s extends i{_requestCallback(e){return setTimeout(()=>e(this._createDeadline(16)))}_cancelCallback(e){clearTimeout(e)}_createDeadline(e){const t=performance.now()+e;return{timeRemaining:()=>Math.max(0,t-performance.now())}}}t.PriorityTaskQueue=s,t.IdleTaskQueue="requestIdleCallback"in globalThis?class extends i{_requestCallback(e){return requestIdleCallback(e)}_cancelCallback(e){cancelIdleCallback(e)}}:s,t.DebouncedIdleTask=class{constructor(e){this._queue=new t.IdleTaskQueue(e)}set(e){this._queue.clear(),this._queue.enqueue(e)}flush(){this._queue.flush()}dispose(){this._queue.clear()}}},7804(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.XTERM_VERSION=void 0,t.XTERM_VERSION="6.1.0-beta.287"},5882(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.updateWindowsModeWrappedState=function(e){const t=e.buffer.lines.get(e.buffer.ybase+e.buffer.y-1),i=t?.get(e.cols-1),r=e.buffer.lines.get(e.buffer.ybase+e.buffer.y);r&&i&&(r.isWrapped=i[s.CHAR_DATA_CODE_INDEX]!==s.NULL_CELL_CODE&&i[s.CHAR_DATA_CODE_INDEX]!==s.WHITESPACE_CELL_CODE)};const s=i(8938)},5451(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ExtendedAttrs=t.AttributeData=void 0;class i{constructor(){this.fg=0,this.bg=0,this.extended=new s}static toColorRGB(e){return[e>>>16&255,e>>>8&255,255&e]}static fromColorRGB(e){return(255&e[0])<<16|(255&e[1])<<8|255&e[2]}clone(){const e=new i;return e.fg=this.fg,e.bg=this.bg,e.extended=this.extended.clone(),e}isInverse(){return 67108864&this.fg}isBold(){return 134217728&this.fg}isUnderline(){return this.hasExtendedAttrs()&&0!==this.extended.underlineStyle?1:268435456&this.fg}isBlink(){return 536870912&this.fg}isInvisible(){return 1073741824&this.fg}isItalic(){return 67108864&this.bg}isDim(){return 134217728&this.bg}isStrikethrough(){return 2147483648&this.fg}isProtected(){return 536870912&this.bg}isOverline(){return 1073741824&this.bg}getFgColorMode(){return 50331648&this.fg}getBgColorMode(){return 50331648&this.bg}isFgRGB(){return!(50331648&~this.fg)}isBgRGB(){return!(50331648&~this.bg)}isFgPalette(){return 16777216==(50331648&this.fg)||33554432==(50331648&this.fg)}isBgPalette(){return 16777216==(50331648&this.bg)||33554432==(50331648&this.bg)}isFgDefault(){return!(50331648&this.fg)}isBgDefault(){return!(50331648&this.bg)}isAttributeDefault(){return 0===this.fg&&0===this.bg}getFgColor(){switch(50331648&this.fg){case 16777216:case 33554432:return 255&this.fg;case 50331648:return 16777215&this.fg;default:return-1}}getBgColor(){switch(50331648&this.bg){case 16777216:case 33554432:return 255&this.bg;case 50331648:return 16777215&this.bg;default:return-1}}hasExtendedAttrs(){return 268435456&this.bg}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(268435456&this.bg&&~this.extended.underlineColor)switch(50331648&this.extended.underlineColor){case 16777216:case 33554432:return 255&this.extended.underlineColor;case 50331648:return 16777215&this.extended.underlineColor;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return 268435456&this.bg&&~this.extended.underlineColor?50331648&this.extended.underlineColor:this.getFgColorMode()}isUnderlineColorRGB(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&~this.extended.underlineColor):this.isFgRGB()}isUnderlineColorPalette(){return 268435456&this.bg&&~this.extended.underlineColor?16777216==(50331648&this.extended.underlineColor)||33554432==(50331648&this.extended.underlineColor):this.isFgPalette()}isUnderlineColorDefault(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&this.extended.underlineColor):this.isFgDefault()}getUnderlineStyle(){return 268435456&this.fg?268435456&this.bg?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}}t.AttributeData=i;class s{get ext(){return this._urlId?-469762049&this._ext|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(469762048&this._ext)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return 67108863&this._ext}set underlineColor(e){this._ext&=-67108864,this._ext|=67108863&e}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){const e=(3758096384&this._ext)>>29;return e<0?4294967288^e:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}clone(){return new s(this._ext,this._urlId)}isEmpty(){return 0===this.underlineStyle&&0===this._urlId}}t.ExtendedAttrs=s},1073(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Buffer=t.MAX_BUFFER_SIZE=void 0;const s=i(5639),r=i(4812),o=i(6168),n=i(5451),a=i(6107),h=i(3326),l=i(732),c=i(3055),d=i(8938),_=i(8158),u=i(6760);t.MAX_BUFFER_SIZE=4294967295;class f extends r.Disposable{constructor(e,t,i,n){super(),this._hasScrollback=e,this._optionsService=t,this._bufferService=i,this._logService=n,this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.tabs={},this.savedY=0,this.savedX=0,this.savedCurAttrData=a.DEFAULT_ATTR_DATA.clone(),this.savedCharset=u.DEFAULT_CHARSET,this.savedCharsets=[],this.savedGlevel=0,this.savedOriginMode=!1,this.savedWraparoundMode=!0,this.markers=[],this._nullCell=c.CellData.fromCharData([0,d.NULL_CELL_CHAR,d.NULL_CELL_WIDTH,d.NULL_CELL_CODE]),this._whitespaceCell=c.CellData.fromCharData([0,d.WHITESPACE_CELL_CHAR,d.WHITESPACE_CELL_WIDTH,d.WHITESPACE_CELL_CODE]),this._isClearing=!1,this._memoryCleanupPosition=0,this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops(),this._memoryCleanupQueue=new o.IdleTaskQueue(this._logService),this._register((0,r.toDisposable)(()=>this._memoryCleanupQueue.clear())),this._register((0,r.toDisposable)(()=>this.clearAllMarkers())),this._stringCache=this._register(new h.BufferLineStringCache)}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new n.ExtendedAttrs),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new n.ExtendedAttrs),this._whitespaceCell}getBlankLine(e,t){return new a.BufferLine(this._stringCache,this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){const e=this.ybase+this.y-this.ydisp;return e>=0&&et.MAX_BUFFER_SIZE?t.MAX_BUFFER_SIZE:i}fillViewportRows(e){if(0===this.lines.length){e??=a.DEFAULT_ATTR_DATA;let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this._stringCache.clear(),this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){const i=this.getNullCell(a.DEFAULT_ATTR_DATA);this._stringCache.clear();let s=0;const r=this._getCorrectBufferLength(t);if(r>this.lines.maxLength&&(this.lines.maxLength=r),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+o+1?(this.ybase--,o++,this.ydisp>0&&this.ydisp--):this.lines.push(new a.BufferLine(this._stringCache,e,i,!1)));else for(let e=this._rows;e>t;e--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(r0&&(this.lines.trimStart(e),this.ybase=Math.max(this.ybase-e,0),this.ydisp=Math.max(this.ydisp-e,0),this.savedY=Math.max(this.savedY-e,0)),this.lines.maxLength=r}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),o&&(this.y+=o),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let t=0;t0){const e=Math.max(0,this.lines.length-this.ybase-1);this.y=Math.min(this.y,e)}this._memoryCleanupQueue.clear(),s>.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue(()=>this._batchedMemoryCleanup()))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){const e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&"conpty"===e.backend&&e.buildNumber>=21376:this._hasScrollback}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){const i=this._optionsService.rawOptions.reflowCursorLine,s=(0,l.reflowLargerGetLinesToRemove)(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(a.DEFAULT_ATTR_DATA),i);if(s.length>0){const i=(0,l.reflowLargerCreateNewLayout)(this.lines,s);(0,l.reflowLargerApplyNewLayout)(this.lines,i.layout),this._reflowLargerAdjustViewport(e,t,i.countRemoved)}}_reflowLargerAdjustViewport(e,t,i){const s=this.getNullCell(a.DEFAULT_ATTR_DATA);let r=i;for(;r-- >0;)0===this.ybase?(this.y>0&&this.y--,this.lines.length=0;n--){let h=this.lines.get(n);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;const c=[h];for(;h.isWrapped&&n>0;)h=this.lines.get(--n),c.unshift(h);if(!i){const e=this.ybase+this.y;if(e>=n&&e0&&(r.push({start:n+c.length+o,newLines:p}),o+=p.length),c.push(...p);let v=_.length-1,g=_[v];0===g&&(v--,g=_[v]);let m=c.length-u-1,S=d;for(;m>=0;){const e=Math.min(S,g);if(void 0===c[v])break;if(c[v].copyCellsFrom(c[m],S-e,g-e,e,!0),g-=e,0===g&&(v--,g=_[v]),S-=e,0===S){m--;const e=Math.max(m,0);S=(0,l.getWrappedLineTrimmedLength)(c,e,this._cols)}}for(let t=0;t0;)0===this.ybase?this.y0){const e=[],t=[];for(let e=0;e=0;l--)if(a&&a.start>s+h){for(let e=a.newLines.length-1;e>=0;e--)this.lines.set(l--,a.newLines[e]);l++,e.push({index:s+1,amount:a.newLines.length}),h+=a.newLines.length,a=r[++n]}else this.lines.set(l,t[s--]);let l=0;for(let t=e.length-1;t>=0;t--)e[t].index+=l,this.lines.onInsertEmitter.fire(e[t]),l+=e[t].amount;const c=Math.max(0,i+o-this.lines.maxLength);c>0&&this.lines.onTrimEmitter.fire(c)}}translateBufferLineToString(e,t,i=0,s){const r=this.lines.get(e);return r?r.translateToString(t,i,s):""}getWrappedRangeForLine(e){let t=e,i=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;i+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(e??=this.x;!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=e,t.line<0&&t.dispose()})),t.register(this.lines.onInsert(e=>{t.line>=e.index&&(t.line+=e.amount)})),t.register(this.lines.onDelete(e=>{t.line>=e.index&&t.linee.index&&(t.line-=e.amount)})),t.register(t.onDispose(()=>this._removeMarker(t))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}}t.Buffer=f},6107(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferLine=t.DEFAULT_ATTR_DATA=void 0;const s=i(5451),r=i(3055),o=i(8938),n=i(726),a=i(4220);t.DEFAULT_ATTR_DATA=Object.freeze(new s.AttributeData);let h=0;const l=new r.CellData,c=new a.StringBuilder;class d{constructor(e,t,i,s=!1){this._stringCache=e,this.isWrapped=s,this._combined={},this._extendedAttrs={},this._data=new Uint32Array(3*t);const n=i??r.CellData.fromCharData([0,o.NULL_CELL_CHAR,o.NULL_CELL_WIDTH,o.NULL_CELL_CODE]);for(let e=0;e>22,2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):i]}set(e,t){this._invalidateStringCache(),this._data[3*e+1]=t[o.CHAR_DATA_ATTR_INDEX],t[o.CHAR_DATA_CHAR_INDEX].length>1?(this._combined[e]=t[1],this._data[3*e+0]=2097152|e|t[o.CHAR_DATA_WIDTH_INDEX]<<22):this._data[3*e+0]=t[o.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|t[o.CHAR_DATA_WIDTH_INDEX]<<22}getWidth(e){return this._data[3*e+0]>>22}hasWidth(e){return 12582912&this._data[3*e+0]}getFg(e){return this._data[3*e+1]}getBg(e){return this._data[3*e+2]}hasContent(e){return 4194303&this._data[3*e+0]}getCodePoint(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):2097151&t}isCombined(e){return 2097152&this._data[3*e+0]}getString(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e]:2097151&t?(0,n.stringFromCodePoint)(2097151&t):""}isProtected(e){return 536870912&this._data[3*e+2]}loadCell(e,i){return h=3*e,i.content=this._data[h+0],i.fg=this._data[h+1],i.bg=this._data[h+2],2097152&i.content?i.combinedData=this._combined[e]:i.combinedData="",268435456&i.bg?i.extended=this._extendedAttrs[e]:i.extended=t.DEFAULT_ATTR_DATA.extended.clone(),i}setCell(e,t){this._invalidateStringCache(),2097152&t.content&&(this._combined[e]=t.combinedData),268435456&t.bg&&(this._extendedAttrs[e]=t.extended),this._data[3*e+0]=t.content,this._data[3*e+1]=t.fg,this._data[3*e+2]=t.bg}setCellFromCodepoint(e,t,i,s){this._invalidateStringCache(),268435456&s.bg&&(this._extendedAttrs[e]=s.extended),this._data[3*e+0]=t|i<<22,this._data[3*e+1]=s.fg,this._data[3*e+2]=s.bg}addCodepointToCell(e,t,i){this._invalidateStringCache();let s=this._data[3*e+0];2097152&s?this._combined[e]+=(0,n.stringFromCodePoint)(t):2097151&s?(this._combined[e]=(0,n.stringFromCodePoint)(2097151&s)+(0,n.stringFromCodePoint)(t),s&=-2097152,s|=2097152):s=t|1<<22,i&&(s&=-12582913,s|=i<<22),this._data[3*e+0]=s}insertCells(e,t,i){if(this._invalidateStringCache(),(e%=this.length)&&2===this.getWidth(e-1)&&this.setCellFromCodepoint(e-1,0,1,i),t=0;--i)this.setCell(e+t+i,this.loadCell(e+i,l));for(let s=0;sthis.length){if(this._data.buffer.byteLength>=4*i)this._data=new Uint32Array(this._data.buffer,0,i);else{const e=new Uint32Array(i);e.set(this._data),this._data=e}for(let i=this.length;i=e&&delete this._combined[s]}const s=Object.keys(this._extendedAttrs);for(let t=0;t=e&&delete this._extendedAttrs[i]}}return this.length=e,4*i*2=0;--e)if(4194303&this._data[3*e+0])return e+(this._data[3*e+0]>>22);return 0}getNoBgTrimmedLength(){for(let e=this.length-1;e>=0;--e)if(4194303&this._data[3*e+0]||50331648&this._data[3*e+2])return e+(this._data[3*e+0]>>22);return 0}copyCellsFrom(e,t,i,s,r){this._invalidateStringCache();const o=e._data;if(r)for(let r=s-1;r>=0;r--){for(let e=0;e<3;e++)this._data[3*(i+r)+e]=o[3*(t+r)+e];this._copyCellMapsFrom(e,t+r,i+r)}else for(let r=0;r>22||1}s&&s.push(t);const h=c.toString();if(c.reset(),r){const t=this._getStringCacheEntry(!0);t.value=h,t.isTrimmed=!!e}return h}_getStringCacheEntry(e){const t=this._stringCacheEntryRef?.deref();if(t&&t.generation===this._stringCache.generation)return t;if(!e)return;const i=this._stringCache.allocateEntry();return this._stringCacheEntryRef=new WeakRef(i),i}_invalidateStringCache(){const e=this._getStringCacheEntry(!1);e&&(e.value=void 0,e.isTrimmed=!1)}_copyCellMapsFrom(e,t,i){const s=3*t;2097152&e._data[s+0]&&(this._combined[i]=e._combined[t]),268435456&e._data[s+2]&&(this._extendedAttrs[i]=e._extendedAttrs[t])}_copySparseMapsFrom(e){this._combined={},this._extendedAttrs={};for(let t=0;tthis.entries.clear()))}touch(){this._scheduleClear()}allocateEntry(){const e={value:void 0,isTrimmed:!1,generation:this.generation};return this.entries.add(e),this._scheduleClear(),e}clear(){this._clearTimeout.clear(),this._lastAccessTimestamp=0,this.generation++;for(const e of this.entries)e.value=void 0,e.isTrimmed=!1;this.entries.clear()}_scheduleClear(){this._lastAccessTimestamp=Date.now(),this._clearTimeout.value||this._scheduleClearTimeout(15e3)}_scheduleClearTimeout(e){this._clearTimeout.value=(0,s.disposableTimeout)(()=>{const e=Date.now()-this._lastAccessTimestamp;e>=15e3?this.clear():this._scheduleClearTimeout(15e3-e)},e)}}t.BufferLineStringCache=o},9384(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.getRangeLength=function(e,t){if(e.start.y>e.end.y)throw new Error(`Buffer range end (${e.end.x}, ${e.end.y}) cannot be before start (${e.start.x}, ${e.start.y})`);return t*(e.end.y-e.start.y)+(e.end.x-e.start.x+1)}},732(e,t){function i(e,t,i){if(t===e.length-1)return e[t].getTrimmedLength();const s=!e[t].hasContent(i-1)&&1===e[t].getWidth(i-1),r=2===e[t+1].getWidth(0);return s&&r?i-1:i}Object.defineProperty(t,"__esModule",{value:!0}),t.reflowLargerGetLinesToRemove=function(e,t,s,r,o,n){const a=[];for(let h=0;h=h&&r0&&(e>_||0===d[e].getTrimmedLength());e--)v++;v>0&&(a.push(h+d.length-v),a.push(v)),h+=d.length-1}return a},t.reflowLargerCreateNewLayout=function(e,t){const i=[];let s=0,r=t[s],o=0;for(let n=0;nl&&(n-=l,a++);const c=2===e[a].getWidth(n-1);c&&n--;const d=c?s-1:s;r.push(d),h+=d}return r},t.getWrappedLineTrimmedLength=i},4097(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferSet=void 0;const s=i(4812),r=i(1073),o=i(8636);class n extends s.Disposable{constructor(e,t,i){super(),this._optionsService=e,this._bufferService=t,this._logService=i,this._normalBuffer=this._register(new s.MutableDisposable),this._altBuffer=this._register(new s.MutableDisposable),this._onBufferActivate=this._register(new o.Emitter),this.onBufferActivate=this._onBufferActivate.event,this.reset(),this._register(this._optionsService.onSpecificOptionChange("scrollback",()=>this.resize(this._bufferService.cols,this._bufferService.rows))),this._register(this._optionsService.onSpecificOptionChange("tabStopWidth",()=>this.setupTabStops()))}reset(){this._normal=new r.Buffer(!0,this._optionsService,this._bufferService,this._logService),this._normalBuffer.value=this._normal,this._normal.fillViewportRows(),this._alt=new r.Buffer(!1,this._optionsService,this._bufferService,this._logService),this._altBuffer.value=this._alt,this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}}t.BufferSet=n},3055(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.CellData=void 0;const s=i(726),r=i(8938),o=i(5451);class n extends o.AttributeData{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new o.ExtendedAttrs,this.combinedData=""}static fromCharData(e){const t=new n;return t.setFromCharData(e),t}isCombined(){return 2097152&this.content}getWidth(){return this.content>>22}getChars(){return 2097152&this.content?this.combinedData:2097151&this.content?(0,s.stringFromCodePoint)(2097151&this.content):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):2097151&this.content}setFromCharData(e){this.fg=e[r.CHAR_DATA_ATTR_INDEX],this.bg=0;let t=!1;if(e[r.CHAR_DATA_CHAR_INDEX].length>2)t=!0;else if(2===e[r.CHAR_DATA_CHAR_INDEX].length){const i=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0);if(55296<=i&&i<=56319){const s=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(1);56320<=s&&s<=57343?this.content=1024*(i-55296)+s-56320+65536|e[r.CHAR_DATA_WIDTH_INDEX]<<22:t=!0}else t=!0}else this.content=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|e[r.CHAR_DATA_WIDTH_INDEX]<<22;t&&(this.combinedData=e[r.CHAR_DATA_CHAR_INDEX],this.content=2097152|e[r.CHAR_DATA_WIDTH_INDEX]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}attributesEquals(e){if(this.getFgColorMode()!==e.getFgColorMode()||this.getFgColor()!==e.getFgColor())return!1;if(this.getBgColorMode()!==e.getBgColorMode()||this.getBgColor()!==e.getBgColor())return!1;if(this.isInverse()!==e.isInverse())return!1;if(this.isBold()!==e.isBold())return!1;if(this.isUnderline()!==e.isUnderline())return!1;if(this.isUnderline()){if(this.getUnderlineStyle()!==e.getUnderlineStyle())return!1;const t=this.isUnderlineColorDefault(),i=e.isUnderlineColorDefault();if(!t||!i){if(t!==i)return!1;if(this.getUnderlineColor()!==e.getUnderlineColor())return!1;if(this.getUnderlineColorMode()!==e.getUnderlineColorMode())return!1}}return this.isOverline()===e.isOverline()&&this.isBlink()===e.isBlink()&&this.isInvisible()===e.isInvisible()&&this.isItalic()===e.isItalic()&&this.isDim()===e.isDim()&&this.isStrikethrough()===e.isStrikethrough()}}t.CellData=n},8938(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.WHITESPACE_CELL_CODE=t.WHITESPACE_CELL_WIDTH=t.WHITESPACE_CELL_CHAR=t.NULL_CELL_CODE=t.NULL_CELL_WIDTH=t.NULL_CELL_CHAR=t.CHAR_DATA_CODE_INDEX=t.CHAR_DATA_WIDTH_INDEX=t.CHAR_DATA_CHAR_INDEX=t.CHAR_DATA_ATTR_INDEX=t.DEFAULT_EXT=t.DEFAULT_ATTR=t.DEFAULT_COLOR=void 0,t.DEFAULT_COLOR=0,t.DEFAULT_ATTR=t.DEFAULT_COLOR<<9|256,t.DEFAULT_EXT=0,t.CHAR_DATA_ATTR_INDEX=0,t.CHAR_DATA_CHAR_INDEX=1,t.CHAR_DATA_WIDTH_INDEX=2,t.CHAR_DATA_CODE_INDEX=3,t.NULL_CELL_CHAR="",t.NULL_CELL_WIDTH=1,t.NULL_CELL_CODE=0,t.WHITESPACE_CELL_CHAR=" ",t.WHITESPACE_CELL_WIDTH=1,t.WHITESPACE_CELL_CODE=32},8158(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Marker=void 0;const s=i(4812),r=i(8636);class o{get id(){return this._id}constructor(e){this.line=e,this.isDisposed=!1,this._disposables=[],this._id=o._nextId++,this._onDispose=this.register(new r.Emitter),this.onDispose=this._onDispose.event}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),(0,s.dispose)(this._disposables),this._disposables.length=0)}register(e){return this._disposables.push(e),e}}t.Marker=o,o._nextId=1},6760(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CHARSET=t.CHARSETS=void 0,t.CHARSETS={},t.DEFAULT_CHARSET=t.CHARSETS.B,t.CHARSETS[0]={"`":"◆",a:"▒",b:"␉",c:"␌",d:"␍",e:"␊",f:"°",g:"±",h:"␤",i:"␋",j:"┘",k:"┐",l:"┌",m:"└",n:"┼",o:"⎺",p:"⎻",q:"─",r:"⎼",s:"⎽",t:"├",u:"┤",v:"┴",w:"┬",x:"│",y:"≤",z:"≥","{":"π","|":"≠","}":"£","~":"·"},t.CHARSETS.A={"#":"£"},t.CHARSETS.B=void 0,t.CHARSETS[4]={"#":"£","@":"¾","[":"ij","\\":"½","]":"|","{":"¨","|":"f","}":"¼","~":"´"},t.CHARSETS.C=t.CHARSETS[5]={"[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS.R={"#":"£","@":"à","[":"°","\\":"ç","]":"§","{":"é","|":"ù","}":"è","~":"¨"},t.CHARSETS.Q={"@":"à","[":"â","\\":"ç","]":"ê","^":"î","`":"ô","{":"é","|":"ù","}":"è","~":"û"},t.CHARSETS.K={"@":"§","[":"Ä","\\":"Ö","]":"Ü","{":"ä","|":"ö","}":"ü","~":"ß"},t.CHARSETS.Y={"#":"£","@":"§","[":"°","\\":"ç","]":"é","`":"ù","{":"à","|":"ò","}":"è","~":"ì"},t.CHARSETS.E=t.CHARSETS[6]={"@":"Ä","[":"Æ","\\":"Ø","]":"Å","^":"Ü","`":"ä","{":"æ","|":"ø","}":"å","~":"ü"},t.CHARSETS.Z={"#":"£","@":"§","[":"¡","\\":"Ñ","]":"¿","{":"°","|":"ñ","}":"ç"},t.CHARSETS.H=t.CHARSETS[7]={"@":"É","[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS["="]={"#":"ù","@":"à","[":"é","\\":"ç","]":"ê","^":"î",_:"è","`":"ô","{":"ä","|":"ö","}":"ü","~":"û"}},706(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.evaluateKeyboardEvent=function(e,t,s,r){const o={type:0,cancel:!1,key:void 0},n=(e.shiftKey?1:0)|(e.altKey?2:0)|(e.ctrlKey?4:0)|(e.metaKey?8:0);switch(e.keyCode){case 0:"UIKeyInputUpArrow"===e.key?o.key=t?"OA":"":"UIKeyInputLeftArrow"===e.key?o.key=t?"OD":"":"UIKeyInputRightArrow"===e.key?o.key=t?"OC":"":"UIKeyInputDownArrow"===e.key&&(o.key=t?"OB":"");break;case 8:o.key=e.ctrlKey?"\b":"",e.altKey&&(o.key=""+o.key);break;case 9:if(e.shiftKey){o.key="";break}o.key="\t",o.cancel=!0;break;case 13:"c"===e.key&&e.ctrlKey?o.key="":o.key=e.altKey?"\r":"\r",o.cancel=!0;break;case 27:o.key="",e.altKey&&(o.key=""),o.cancel=!0;break;case 37:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"D":t?"OD":"";break;case 39:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"C":t?"OC":"";break;case 38:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"A":t?"OA":"";break;case 40:if(e.metaKey)break;o.key=n?"[1;"+(n+1)+"B":t?"OB":"";break;case 45:e.shiftKey||e.ctrlKey||(o.key="[2~");break;case 46:o.key=n?"[3;"+(n+1)+"~":"[3~";break;case 36:o.key=n?"[1;"+(n+1)+"H":t?"OH":"";break;case 35:o.key=n?"[1;"+(n+1)+"F":t?"OF":"";break;case 33:e.shiftKey?o.type=2:e.ctrlKey?o.key="[5;"+(n+1)+"~":o.key="[5~";break;case 34:e.shiftKey?o.type=3:e.ctrlKey?o.key="[6;"+(n+1)+"~":o.key="[6~";break;case 112:o.key=n?"[1;"+(n+1)+"P":"OP";break;case 113:o.key=n?"[1;"+(n+1)+"Q":"OQ";break;case 114:o.key=n?"[1;"+(n+1)+"R":"OR";break;case 115:o.key=n?"[1;"+(n+1)+"S":"OS";break;case 116:o.key=n?"[15;"+(n+1)+"~":"[15~";break;case 117:o.key=n?"[17;"+(n+1)+"~":"[17~";break;case 118:o.key=n?"[18;"+(n+1)+"~":"[18~";break;case 119:o.key=n?"[19;"+(n+1)+"~":"[19~";break;case 120:o.key=n?"[20;"+(n+1)+"~":"[20~";break;case 121:o.key=n?"[21;"+(n+1)+"~":"[21~";break;case 122:o.key=n?"[23;"+(n+1)+"~":"[23~";break;case 123:o.key=n?"[24;"+(n+1)+"~":"[24~";break;default:if(!e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)if(s&&!r||!e.altKey||e.metaKey)if(!s||e.altKey||e.ctrlKey||e.shiftKey||!e.metaKey){if(e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.keyCode>=48&&1===e.key.length)o.key=e.key;else if(e.key&&e.ctrlKey&&e.shiftKey)switch(e.code){case"Minus":o.key="";break;case"Digit2":o.key="\0";break;case"Digit6":o.key=""}}else 65===e.keyCode&&(o.type=1);else{const t=i[e.keyCode],s=t?.[e.shiftKey?1:0];if(s)o.key=""+s;else if(e.keyCode>=65&&e.keyCode<=90){const t=e.ctrlKey?e.keyCode-64:e.keyCode+32;let i=String.fromCharCode(t);e.shiftKey&&(i=i.toUpperCase()),o.key=""+i}else if(32===e.keyCode)o.key=""+(e.ctrlKey?"\0":" ");else if("Dead"===e.key&&e.code.startsWith("Key")){let t=e.code.slice(3,4);e.shiftKey||(t=t.toLowerCase()),o.key=""+t,o.cancel=!0}}else e.keyCode>=65&&e.keyCode<=90?o.key=String.fromCharCode(e.keyCode-64):32===e.keyCode?o.key="\0":e.keyCode>=51&&e.keyCode<=55?o.key=String.fromCharCode(e.keyCode-51+27):56===e.keyCode?o.key="":"/"===e.key?o.key="":219===e.keyCode?o.key="":220===e.keyCode?o.key="":221===e.keyCode&&(o.key="")}return o};const i={48:["0",")"],49:["1","!"],50:["2","@"],51:["3","#"],52:["4","$"],53:["5","%"],54:["6","^"],55:["7","&"],56:["8","*"],57:["9","("],186:[";",":"],187:["=","+"],188:[",","<"],189:["-","_"],190:[".",">"],191:["/","?"],192:["`","~"],219:["[","{"],220:["\\","|"],221:["]","}"],222:["'",'"']}},7241(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.KittyKeyboard=void 0,t.KittyKeyboard=class{constructor(){this._functionalKeyCodes={Escape:27,Enter:13,Tab:9,Backspace:127,CapsLock:57358,ScrollLock:57359,NumLock:57360,PrintScreen:57361,Pause:57362,ContextMenu:57363,F13:57376,F14:57377,F15:57378,F16:57379,F17:57380,F18:57381,F19:57382,F20:57383,F21:57384,F22:57385,F23:57386,F24:57387,F25:57388,KP_0:57399,KP_1:57400,KP_2:57401,KP_3:57402,KP_4:57403,KP_5:57404,KP_6:57405,KP_7:57406,KP_8:57407,KP_9:57408,KP_Decimal:57409,KP_Divide:57410,KP_Multiply:57411,KP_Subtract:57412,KP_Add:57413,KP_Enter:57414,KP_Equal:57415,ShiftLeft:57441,ShiftRight:57447,ControlLeft:57442,ControlRight:57448,AltLeft:57443,AltRight:57449,MetaLeft:57444,MetaRight:57450,MediaPlayPause:57430,MediaStop:57432,MediaTrackNext:57435,MediaTrackPrevious:57436,AudioVolumeDown:57438,AudioVolumeUp:57439,AudioVolumeMute:57440},this._csiTildeKeys={Insert:2,Delete:3,PageUp:5,PageDown:6,F5:15,F6:17,F7:18,F8:19,F9:20,F10:21,F11:23,F12:24},this._csiLetterKeys={ArrowUp:"A",ArrowDown:"B",ArrowRight:"C",ArrowLeft:"D",Home:"H",End:"F"},this._ss3FunctionKeys={F1:"P",F2:"Q",F3:"R",F4:"S"}}_getNumpadKeyCode(e){if(e.code.startsWith("Numpad")){const t=e.code.slice(6);if(t>="0"&&t<="9")return 57399+parseInt(t,10);switch(t){case"Decimal":return 57409;case"Divide":return 57410;case"Multiply":return 57411;case"Subtract":return 57412;case"Add":return 57413;case"Enter":return 57414;case"Equal":return 57415}}}_getModifierKeyCode(e){switch(e.code){case"ShiftLeft":return 57441;case"ShiftRight":return 57447;case"ControlLeft":return 57442;case"ControlRight":return 57448;case"AltLeft":return 57443;case"AltRight":return 57449;case"MetaLeft":return 57444;case"MetaRight":return 57450}}_encodeModifiers(e){let t=0;return e.shiftKey&&(t|=1),e.altKey&&(t|=2),e.ctrlKey&&(t|=4),e.metaKey&&(t|=8),t>0?t+1:0}_getKeyCode(e,t){const i=this._getNumpadKeyCode(e);if(void 0!==i)return i;const s=this._getModifierKeyCode(e);if(void 0!==s)return s;const r=this._functionalKeyCodes[e.key];if(void 0!==r)return r;if((e.shiftKey||t&&e.altKey)&&e.code){if(e.code.startsWith("Digit")&&6===e.code.length){const t=e.code.charAt(5);if(t>="0"&&t<="9")return t.charCodeAt(0)}if(e.code.startsWith("Key")&&4===e.code.length)return e.code.charAt(3).toLowerCase().charCodeAt(0)}if(1===e.key.length){const t=e.key.codePointAt(0);return t>=65&&t<=90?t+32:t}}_isModifierKey(e){return"Shift"===e.key||"Control"===e.key||"Alt"===e.key||"Meta"===e.key}_isLockKey(e){return"CapsLock"===e.key||"NumLock"===e.key||"ScrollLock"===e.key}_buildCsiLetterSequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"["+e}_buildSs3Sequence(e,t,i,s){const r=s&&1!==i;if(t>0||r){let s="[1;"+(t>0?t:"1");return r&&(s+=":"+i),s+=e,s}return"O"+e}_buildCsiTildeSequence(e,t,i,s){const r=s&&1!==i;let o="["+e;return(t>0||r)&&(o+=";"+(t>0?t:"1"),r&&(o+=":"+i)),o+="~",o}_buildCsiUSequence(e,t,i,s,r,o,n){const a=!!(2&r);let h,l="["+t;4&r&&e.shiftKey&&1===e.key.length&&!o&&!n&&(h=e.key.codePointAt(0),l+=":"+h);const c=16&r&&3!==s&&1===e.key.length&&!o&&!n&&!e.ctrlKey?e.key.codePointAt(0):void 0,d=a&&1!==s&&(3===s||void 0===c);return(i>0||d||void 0!==c)&&(l+=";",i>0?l+=i:d&&(l+="1"),d&&(l+=":"+s)),void 0!==c&&(l+=";"+c),l+="u",l}evaluate(e,t,i=1,s=!1){const r={type:0,cancel:!1,key:void 0},o=this._encodeModifiers(e),n=this._isModifierKey(e),a=!!(2&t);if(!a&&3===i)return r;if(n&&!(8&t))return r;if(this._isLockKey(e)&&!(8&t))return r;const h=this._csiLetterKeys[e.key];if(h)return r.key=this._buildCsiLetterSequence(h,o,i,a),r.cancel=!0,r;const l=this._ss3FunctionKeys[e.key];if(l)return r.key=this._buildSs3Sequence(l,o,i,a),r.cancel=!0,r;const c=this._csiTildeKeys[e.key];if(void 0!==c)return r.key=this._buildCsiTildeSequence(c,o,i,a),r.cancel=!0,r;const d=this._getKeyCode(e,s);if(void 0===d)return r;const _=13===d||9===d||127===d;if(_&&3===i&&!(8&t))return r;const u=void 0!==this._functionalKeyCodes[e.key]||void 0!==this._getNumpadKeyCode(e);if(8&t||a&&3===i||(1&t||a)&&(u&&!_||o>0&&1!==e.key.length||o-1>1))r.key=this._buildCsiUSequence(e,d,o,i,t,u,n),r.cancel=!0;else{const t=13===d?"\r":9===d?"\t":127===d?"":void 0;t?r.key=t:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||(r.key=e.key)}return r}static shouldUseProtocol(e){return e>0}}},726(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Utf8ToUtf32=t.StringToUtf32=void 0,t.stringFromCodePoint=function(e){return e>65535?(e-=65536,String.fromCharCode(55296+(e>>10))+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)},t.utf32ToString=function(e,t=0,i=e.length){let s="";for(let r=t;r65535?(t-=65536,s+=String.fromCharCode(55296+(t>>10))+String.fromCharCode(t%1024+56320)):s+=String.fromCharCode(t)}return s},t.StringToUtf32=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){const i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){const i=e.charCodeAt(r++);56320<=i&&i<=57343?t[s++]=1024*(this._interim-55296)+i-56320+65536:(t[s++]=this._interim,t[s++]=i),this._interim=0}for(let o=r;o=i)return this._interim=r,s;const n=e.charCodeAt(o);56320<=n&&n<=57343?t[s++]=1024*(r-55296)+n-56320+65536:(t[s++]=r,t[s++]=n);continue}65279!==r&&(t[s++]=r)}return s}},t.Utf8ToUtf32=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){const i=e.length;if(!i)return 0;let s,r,o,n,a,h=0,l=0;if(this.interim[0]){let s=!1,r=this.interim[0];r&=192==(224&r)?31:224==(240&r)?15:7;let o,n=0;for(;(o=this.interim[++n])&&n<4;)r<<=6,r|=63&o;const a=192==(224&this.interim[0])?2:224==(240&this.interim[0])?3:4,c=a-n;for(;l=i)return 0;if(o=e[l++],128!=(192&o)){l--,s=!0;break}this.interim[n++]=o,r<<=6,r|=63&o}s||(2===a?r<128?l--:t[h++]=r:3===a?r<2048||r>=55296&&r<=57343||65279===r||(t[h++]=r):r<65536||r>1114111||(t[h++]=r)),this.interim.fill(0)}const c=i-4;let d=l;for(;d=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(a=(31&s)<<6|63&r,a<128){d--;continue}t[h++]=a}else if(224==(240&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(a=(15&s)<<12|(63&r)<<6|63&o,a<2048||a>=55296&&a<=57343||65279===a)continue;t[h++]=a}else if(240==(248&s)){if(d>=i)return this.interim[0]=s,h;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,h;if(o=e[d++],128!=(192&o)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,this.interim[2]=o,h;if(n=e[d++],128!=(192&n)){d--;continue}if(a=(7&s)<<18|(63&r)<<12|(63&o)<<6|63&n,a<65536||a>1114111)continue;t[h++]=a}}return h}}},7428(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeV6=void 0;const s=i(6415),r=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],o=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]];let n;t.UnicodeV6=class{constructor(){if(this.version="6",!n){n=new Uint8Array(65536),n.fill(1),n[0]=0,n.fill(0,1,32),n.fill(0,127,160),n.fill(2,4352,4448),n[9001]=2,n[9002]=2,n.fill(2,11904,42192),n[12351]=1,n.fill(2,44032,55204),n.fill(2,63744,64256),n.fill(2,65040,65050),n.fill(2,65072,65136),n.fill(2,65280,65377),n.fill(2,65504,65511);for(let e=0;et[r][1])return!1;for(;r>=s;)if(i=s+r>>1,e>t[i][1])s=i+1;else{if(!(e=131072&&e<=196605||e>=196608&&e<=262141?2:1}charProperties(e,t){let i=this.wcwidth(e),r=0===i&&0!==t;if(r){const e=s.UnicodeService.extractWidth(t);0===e?r=!1:e>i&&(i=e)}return s.UnicodeService.createPropertyValue(0,i,r)}}},9249(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Win32InputMode=void 0,t.Win32InputMode=class{constructor(){this._codeToVk={KeyA:65,KeyB:66,KeyC:67,KeyD:68,KeyE:69,KeyF:70,KeyG:71,KeyH:72,KeyI:73,KeyJ:74,KeyK:75,KeyL:76,KeyM:77,KeyN:78,KeyO:79,KeyP:80,KeyQ:81,KeyR:82,KeyS:83,KeyT:84,KeyU:85,KeyV:86,KeyW:87,KeyX:88,KeyY:89,KeyZ:90,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,F16:127,F17:128,F18:129,F19:130,F20:131,F21:132,F22:133,F23:134,F24:135,Numpad0:96,Numpad1:97,Numpad2:98,Numpad3:99,Numpad4:100,Numpad5:101,Numpad6:102,Numpad7:103,Numpad8:104,Numpad9:105,NumpadMultiply:106,NumpadAdd:107,NumpadSeparator:108,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,NumLock:144,ArrowUp:38,ArrowDown:40,ArrowLeft:37,ArrowRight:39,Home:36,End:35,PageUp:33,PageDown:34,Insert:45,Delete:46,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,CapsLock:20,ScrollLock:145,Escape:27,Enter:13,Tab:9,Space:32,Backspace:8,Pause:19,ContextMenu:93,PrintScreen:44,Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,IntlBackslash:226},this._codeToScancode={KeyQ:16,KeyW:17,KeyE:18,KeyR:19,KeyT:20,KeyY:21,KeyU:22,KeyI:23,KeyO:24,KeyP:25,KeyA:30,KeyS:31,KeyD:32,KeyF:33,KeyG:34,KeyH:35,KeyJ:36,KeyK:37,KeyL:38,KeyZ:44,KeyX:45,KeyC:46,KeyV:47,KeyB:48,KeyN:49,KeyM:50,Digit1:2,Digit2:3,Digit3:4,Digit4:5,Digit5:6,Digit6:7,Digit7:8,Digit8:9,Digit9:10,Digit0:11,F1:59,F2:60,F3:61,F4:62,F5:63,F6:64,F7:65,F8:66,F9:67,F10:68,F11:87,F12:88,Numpad0:82,Numpad1:79,Numpad2:80,Numpad3:81,Numpad4:75,Numpad5:76,Numpad6:77,Numpad7:71,Numpad8:72,Numpad9:73,NumpadMultiply:55,NumpadAdd:78,NumpadSubtract:74,NumpadDecimal:83,NumpadDivide:53,NumpadEnter:28,NumLock:69,ArrowUp:72,ArrowDown:80,ArrowLeft:75,ArrowRight:77,Home:71,End:79,PageUp:73,PageDown:81,Insert:82,Delete:83,ShiftLeft:42,ShiftRight:54,ControlLeft:29,ControlRight:29,AltLeft:56,AltRight:56,CapsLock:58,ScrollLock:70,Escape:1,Enter:28,Tab:15,Space:57,Backspace:14,Pause:69,Semicolon:39,Equal:13,Comma:51,Minus:12,Period:52,Slash:53,Backquote:41,BracketLeft:26,Backslash:43,BracketRight:27,Quote:40},this._enhancedKeyCodes=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Insert","Delete","NumpadEnter","NumpadDivide","ControlRight","AltRight","PrintScreen","Pause","ContextMenu","MetaLeft","MetaRight"]),this._keyToControlChar={Enter:13,Backspace:8,Tab:9,Escape:27}}_getVirtualKeyCode(e){const t=this._codeToVk[e.code];return void 0!==t?t:e.keyCode||0}_getScanCode(e){return this._codeToScancode[e.code]||0}_getUnicodeChar(e){if(e.ctrlKey&&!e.altKey&&!e.metaKey){if("Enter"===e.key)return 10;if("Backspace"===e.key)return 127}const t=this._keyToControlChar[e.key];if(void 0!==t)return t;if(1===e.key.length){const t=e.key.codePointAt(0)||0;if(e.ctrlKey&&!e.altKey&&!e.metaKey){if(t>=65&&t<=90)return t-64;if(t>=97&&t<=122)return t-96}return t}return 0}_getControlKeyState(e){let t=0;return e.shiftKey&&(t|=16),e.ctrlKey&&("ControlRight"===e.code?t|=4:t|=8),e.altKey&&("AltRight"===e.code?t|=1:t|=2),this._enhancedKeyCodes.has(e.code)&&(t|=256),t}evaluateKeyboardEvent(e,t){return{type:0,cancel:!0,key:`[${this._getVirtualKeyCode(e)};${this._getScanCode(e)};${this._getUnicodeChar(e)};${t?1:0};${this._getControlKeyState(e)};1_`}}}},3562(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.WriteBuffer=void 0;const s=i(3132),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._action=e,this._writeBuffer=[],this._callbacks=[],this._pendingData=0,this._bufferOffset=0,this._isSyncWriting=!1,this._syncCalls=0,this._didUserInput=!1,this._innerWriteTimer=this._register(new s.TimeoutTimer),this._onWriteParsed=this._register(new o.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._register((0,r.toDisposable)(()=>{this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0}))}handleUserInput(){this._didUserInput=!0}flushSync(){if(this._store.isDisposed)return;if(this._isSyncWriting)return;let e;this._isSyncWriting=!0;let t=!1;for(;e=this._writeBuffer.shift();){t=!0,this._action(e);const i=this._callbacks.shift();i&&i()}this._pendingData=0,this._bufferOffset=2147483647,this._writeBuffer.length=0,this._callbacks.length=0,this._isSyncWriting=!1,t&&this._onWriteParsed.fire()}writeSync(e,t){if(this._store.isDisposed)return;if(void 0!==t&&this._syncCalls>t)return void(this._syncCalls=0);if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;let i;for(this._isSyncWriting=!0;i=this._writeBuffer.shift();){this._action(i);const e=this._callbacks.shift();e&&e()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(!this._store.isDisposed){if(this._pendingData>5e7)throw new Error("write data discarded, use flow control to avoid losing data");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput)return this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),void this._innerWrite();this._scheduleInnerWrite()}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}}_scheduleInnerWrite(e=0,t=!0){this._store.isDisposed||this._innerWriteTimer.cancelAndSet(()=>this._innerWrite(e,t),0)}_innerWrite(e=0,t=!0){if(this._store.isDisposed)return;const i=e||performance.now();for(;this._writeBuffer.length>this._bufferOffset;){const e=this._writeBuffer[this._bufferOffset],s=this._action(e,t);if(s){const e=e=>{this._store.isDisposed||(performance.now()-i>=12?this._scheduleInnerWrite(0,e):this._innerWrite(i,e))};return void s.catch(e=>(queueMicrotask(()=>{throw e}),Promise.resolve(!1))).then(e)}const r=this._callbacks[this._bufferOffset];if(r&&r(),this._bufferOffset++,this._pendingData-=e.length,performance.now()-i>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),this._scheduleInnerWrite()):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}}t.WriteBuffer=n},8693(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.parseColor=function(e){if(!e)return;let t=e.toLowerCase();if(t.startsWith("rgb:")){t=t.slice(4);const e=i.exec(t);if(e){const t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(t.startsWith("#")&&(t=t.slice(1),s.exec(t)&&[3,6,9,12].includes(t.length))){const e=t.length/3,i=[0,0,0];for(let s=0;s<3;++s){const r=parseInt(t.slice(e*s,e*s+e),16);i[s]=1===e?r<<4:2===e?r:3===e?r>>4:r>>8}return i}},t.toRgbString=function(e,t=16){const[i,s,o]=e;return`rgb:${r(i,t)}/${r(s,t)}/${r(o,t)}`};const i=/^([\da-f])\/([\da-f])\/([\da-f])$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/,s=/^[\da-f]+$/;function r(e,t){const i=e.toString(16),s=i.length<2?"0"+i:i;switch(t){case 4:return i[0];case 8:return s;case 12:return(s+s).slice(0,3);default:return s+s}}},2607(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.ApcHandler=t.ApcParser=void 0;const s=i(726),r=i(4220),o=[];t.ApcParser=class{constructor(){this._handlers=Object.create(null),this._active=o,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._ident=0}start(e){if(this.reset(),this._ident=e,this._active=this._handlers[e]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._ident,"START")}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}end(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"END",e);this._active=o,this._ident=0}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.ApcHandler=n,n._payloadLimit=1e7},9823(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DcsHandler=t.DcsParser=void 0;const s=i(726),r=i(7262),o=i(4220),n=[];t.DcsParser=class{constructor(){this._handlers=Object.create(null),this._active=n,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=n}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].unhook(!1);this._stack.paused=!1,this._active=n,this._ident=0}hook(e,t){if(this.reset(),this._ident=e,this._active=this._handlers[e]||n,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].hook(t);else this._handlerFb(this._ident,"HOOK",t)}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}unhook(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].unhook(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].unhook(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"UNHOOK",e);this._active=n,this._ident=0}};const a=new r.Params;a.addParam(0);class h{constructor(e){this._handler=e,this._data=new o.LimitedStringBuilder(h._payloadLimit),this._params=a,this._hitLimit=!1}hook(e){this._params=e.length>1||e.params[0]?e.clone():a,this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}unhook(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString(),this._params),t instanceof Promise))return t.then(e=>(this._params=a,this._data.reset(),this._hitLimit=!1,e));return this._params=a,this._data.reset(),this._hitLimit=!1,t}}t.DcsHandler=h,h._payloadLimit=1e7},6717(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.EscapeSequenceParser=t.VT500_TRANSITION_TABLE=t.TransitionTable=void 0;const s=i(4812),r=i(7262),o=i(1346),n=i(9823),a=i(2607);class h{constructor(e){this.table=new Uint16Array(e)}setDefault(e,t){this.table.fill(e<<8|t)}add(e,t,i,s){this.table[t<<8|e]=i<<8|s}addMany(e,t,i,s){for(let r=0;rt),i=(e,i)=>t.slice(e,i),s=i(32,127),r=i(0,24);r.push(25),r.push.apply(r,i(28,32));const o=i(0,17);e.setDefault(1,0),e.addMany(s,0,2,0);for(const t of o)e.addMany([24,26,153,154],t,3,0),e.addMany(i(128,144),t,3,0),e.addMany(i(144,152),t,3,0),e.add(156,t,0,0),e.add(27,t,11,1),e.add(157,t,4,8),e.addMany([152,158],t,0,7),e.add(159,t,11,14),e.add(155,t,11,3),e.add(144,t,11,9);return e.addMany(r,0,3,0),e.addMany(r,1,3,1),e.add(127,1,0,1),e.addMany(r,8,0,8),e.addMany(r,3,3,3),e.add(127,3,0,3),e.addMany(r,4,3,4),e.add(127,4,0,4),e.addMany(r,6,3,6),e.addMany(r,5,3,5),e.add(127,5,0,5),e.addMany(r,2,3,2),e.add(127,2,0,2),e.add(93,1,4,8),e.addMany(s,8,5,8),e.add(127,8,5,8),e.addMany([156,27,24,26,7],8,6,0),e.addMany(i(28,32),8,0,8),e.addMany([88,94],1,0,7),e.addMany(s,7,0,7),e.addMany(r,7,0,7),e.add(156,7,0,0),e.add(127,7,0,7),e.add(95,1,11,14),e.addMany(r,14,0,14),e.add(127,14,0,14),e.addMany(i(32,48),14,9,15),e.addMany(i(48,127),14,15,16),e.addMany(i(48,127),15,15,16),e.addMany(r,15,0,15),e.addMany(i(32,48),15,9,15),e.add(127,15,0,15),e.addMany(s,16,16,16),e.addMany(r,16,0,16),e.addMany(i(8,14),16,16,16),e.add(127,16,0,16),e.addMany([27,156,24,26],16,17,0),e.add(91,1,11,3),e.addMany(i(64,127),3,7,0),e.addMany(i(48,60),3,8,4),e.addMany([60,61,62,63],3,9,4),e.addMany(i(48,60),4,8,4),e.addMany(i(64,127),4,7,0),e.addMany([60,61,62,63],4,0,6),e.addMany(i(32,64),6,0,6),e.add(127,6,0,6),e.addMany(i(64,127),6,0,0),e.addMany(i(32,48),3,9,5),e.addMany(i(32,48),5,9,5),e.addMany(i(48,64),5,0,6),e.addMany(i(64,127),5,7,0),e.addMany(i(32,48),4,9,5),e.addMany(i(32,48),1,9,2),e.addMany(i(32,48),2,9,2),e.addMany(i(48,127),2,10,0),e.addMany(i(48,80),1,10,0),e.addMany(i(81,88),1,10,0),e.addMany([89,90,92],1,10,0),e.addMany(i(96,127),1,10,0),e.add(80,1,11,9),e.addMany(r,9,0,9),e.add(127,9,0,9),e.addMany(i(32,48),9,9,12),e.addMany(i(48,60),9,8,10),e.addMany([60,61,62,63],9,9,10),e.addMany(r,11,0,11),e.addMany(i(32,128),11,0,11),e.addMany(r,10,0,10),e.add(127,10,0,10),e.addMany(i(48,60),10,8,10),e.addMany([60,61,62,63],10,0,11),e.addMany(i(32,48),10,9,12),e.addMany(r,12,0,12),e.add(127,12,0,12),e.addMany(i(32,48),12,9,12),e.addMany(i(48,64),12,0,11),e.addMany(i(64,127),12,12,13),e.addMany(i(64,127),10,12,13),e.addMany(i(64,127),9,12,13),e.addMany(r,13,13,13),e.addMany(s,13,13,13),e.add(127,13,0,13),e.addMany([27,156,24,26],13,14,0),e.add(l,0,2,0),e.add(l,8,5,8),e.add(l,6,0,6),e.add(l,11,0,11),e.add(l,13,13,13),e.add(l,16,16,16),e}();class c extends s.Disposable{constructor(e=t.VT500_TRANSITION_TABLE){super(),this._transitions=e,this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0},this.initialState=0,this.currentState=this.initialState,this._params=new r.Params,this._params.addParam(0),this._collect=0,this.precedingJoinState=0,this._printHandlerFb=(e,t,i)=>{},this._executeHandlerFb=e=>{},this._csiHandlerFb=(e,t)=>{},this._escHandlerFb=e=>{},this._errorHandlerFb=e=>e,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this._register((0,s.toDisposable)(()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._escHandlers=Object.create(null)})),this._oscParser=this._register(new o.OscParser),this._dcsParser=this._register(new n.DcsParser),this._apcParser=this._register(new a.ApcParser),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:"\\"},()=>!0)}_identifier(e,t=[64,126]){let i=0;if(e.prefix){if(e.prefix.length>1)throw new Error("only one byte as prefix supported");if(i=e.prefix.charCodeAt(0),i<60||i>63)throw new Error("prefix must be in range 0x3c .. 0x3f")}if(e.intermediates){if(e.intermediates.length>2)throw new Error("only two bytes as intermediates are supported");for(let t=0;ts||s>47)throw new Error("intermediate must be in range 0x20 .. 0x2f");i<<=8,i|=s}}if(1!==e.final.length)throw new Error("final must be a single byte");const s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return i<<=8,i|=s,i}identToString(e){const t=[];for(;e;)t.push(String.fromCharCode(255&e)),e>>=8;return t.reverse().join("")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){const i=this._identifier(e,[48,126]);this._escHandlers[i]??=[];const s=this._escHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){const i=e.charCodeAt(0);this._executeHandlers[i]=t,i<24&&(this._executeHandlersArr[i]=t)}clearExecuteHandler(e){const t=e.charCodeAt(0);this._executeHandlers[t]&&delete this._executeHandlers[t],t<24&&(this._executeHandlersArr[t]=void 0)}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){const i=this._identifier(e);this._csiHandlers[i]??=[];const s=this._csiHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}registerApcHandler(e,t){return e.prefix=void 0,this._apcParser.registerHandler(this._identifier(e,[48,126]),t)}clearApcHandler(e){e.prefix=void 0,this._apcParser.clearHandler(this._identifier(e,[48,126]))}setApcHandlerFallback(e){this._apcParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._apcParser.reset(),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0,0!==this._parseStack.state&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,i,s,r){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=i,this._parseStack.transition=s,this._parseStack.chunkPos=r}parse(e,t,i){let s,r,o,n=0;if(this._parseStack.state)if(2===this._parseStack.state)this._parseStack.state=0,n=this._parseStack.chunkPos+1;else{if(void 0===i||1===this._parseStack.state)throw this._parseStack.state=1,new Error("improper continuation due to previous async handler, giving up parsing");const t=this._parseStack.handlers;let r=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](this._params),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 4:if(!1===i&&r>-1)for(;r>=0&&(o=t[r](),!0!==o);r--)if(o instanceof Promise)return this._parseStack.handlerPos=r,o;this._parseStack.handlers=[];break;case 6:if(s=e[this._parseStack.chunkPos],o=this._dcsParser.unhook(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 5:if(s=e[this._parseStack.chunkPos],o=this._oscParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 7:if(s=e[this._parseStack.chunkPos],o=this._apcParser.end(24!==s&&26!==s,i),o)return o;27===s&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0}this._parseStack.state=0,n=this._parseStack.chunkPos+1,this.precedingJoinState=0,this.currentState=255&this._parseStack.transition}for(let i=n;i=60&&n<=63&&(this._collect=n,s++);let a=!1;for(;s=48&&n<=57)this._params.addDigit(n-48);else if(59===n)this._params.addParam(0);else{if(58!==n){if(n>=64&&n<=126){const e=this._csiHandlers[this._collect<<8|n];let t=e?e.length-1:-1;for(;t>=0&&(o=e[t](this._params),!0!==o);t--)if(o instanceof Promise)return r=1792,this._preserveStack(3,e,t,r,s),o;t<0&&this._csiHandlerFb(this._collect<<8|n,this._params),this.precedingJoinState=0,i=s,this.currentState=0,a=!0;break}break}this._params.addSubParam(-1)}a||(i=s-1,this.currentState=4);continue}switch(r=this._transitions.table[this.currentState<<8|(s>8){case 2:let n=i;const a=t-4;for(;n=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l)&&e[++n]>=32&&(e[n]<=126||e[n]>=l););if(n>=a)for(;n=32&&(e[n]<=126||e[n]>=l);)n++;this._printHandler(e,i,n),i=n-1;break;case 3:this._executeHandlers[s]?this._executeHandlers[s]():this._executeHandlerFb(s),this.precedingJoinState=0;break;case 0:break;case 1:if(this._errorHandler({position:i,code:s,currentState:this.currentState,collect:this._collect,params:this._params,abort:!1}).abort)return;break;case 7:const h=this._csiHandlers[this._collect<<8|s];let c=h?h.length-1:-1;for(;c>=0&&(o=h[c](this._params),!0!==o);c--)if(o instanceof Promise)return this._preserveStack(3,h,c,r,i),o;c<0&&this._csiHandlerFb(this._collect<<8|s,this._params),this.precedingJoinState=0;break;case 8:do{switch(s){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(s-48)}}while(++i47&&s<60);i--;break;case 9:this._collect<<=8,this._collect|=s;break;case 10:const d=this._escHandlers[this._collect<<8|s];let _=d?d.length-1:-1;for(;_>=0&&(o=d[_](),!0!==o);_--)if(o instanceof Promise)return this._preserveStack(4,d,_,r,i),o;_<0&&this._escHandlerFb(this._collect<<8|s),this.precedingJoinState=0;break;case 11:this._params.resetZdm(),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|s,this._params);break;case 13:for(let r=i+1;;++r)if(r>=t||24===(s=e[r])||26===s||27===s||s>127&&s=t||(s=e[r])<32||s>127&&s=32&&e[s]<127||e[s]>=8&&e[s]<14||e[s]>=l))){this._apcParser.put(e,i,s),i=s-1;break}break;case 17:if(o=this._apcParser.end(24!==s&&26!==s),o)return this._preserveStack(7,[],0,r,i),o;27===s&&(r|=1),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0}this.currentState=255&r}}}t.EscapeSequenceParser=c},1346(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OscHandler=t.OscParser=void 0;const s=i(726),r=i(4220),o=[];t.OscParser=class{constructor(){this._state=0,this._active=o,this._id=-1,this._handlers=Object.create(null),this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){this._handlers[e]??=[];const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}reset(){if(2===this._state)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=o,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._id,"START")}_put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._id,"PUT",(0,s.utf32ToString)(e,t,i))}start(){this.reset(),this._state=1}put(e,t,i){if(3!==this._state){if(1===this._state)for(;t0&&this._put(e,t,i)}}end(e,t=!0){if(0!==this._state){if(3!==this._state)if(1===this._state&&this._start(),this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._id,"END",e);this._active=o,this._id=-1,this._state=0}}};class n{constructor(e){this._handler=e,this._data=new r.LimitedStringBuilder(n._payloadLimit),this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(e,t,i){this._hitLimit||this._data.append((0,s.utf32ToString)(e,t,i))&&(this._hitLimit=!0)}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data.toString()),t instanceof Promise))return t.then(e=>(this._data.reset(),this._hitLimit=!1,e));return this._data.reset(),this._hitLimit=!1,t}}t.OscHandler=n,n._payloadLimit=1e7},7262(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Params=void 0;class i{static fromArray(e){const t=new i;if(!e.length)return t;for(let i=Array.isArray(e[0])?1:0;i256)throw new Error("maxSubParamsLength must not be greater than 256");this.params=new Int32Array(e),this.length=0,this._subParams=new Int32Array(t),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(e),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}clone(){const e=new i(this.maxLength,this.maxSubParamsLength);return e.params.set(this.params),e.length=this.length,e._subParams.set(this._subParams),e._subParamsLength=this._subParamsLength,e._subParamsIdx.set(this._subParamsIdx),e._rejectDigits=this._rejectDigits,e._rejectSubDigits=this._rejectSubDigits,e._digitIsSub=this._digitIsSub,e}toArray(){const e=[];for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&e.push(Array.prototype.slice.call(this._subParams,i,s))}return e}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}resetZdm(){this.length=1,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1,this._subParamsIdx[0]=0,this.params[0]=0}addParam(e){if(this._digitIsSub=!1,this.length>=this.maxLength)this._rejectDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=e>2147483647?2147483647:e}}addSubParam(e){if(this._digitIsSub=!0,this.length)if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength)this._rejectSubDigits=!0;else{if(e<-1)throw new Error("values less than -1 are not allowed");this._subParams[this._subParamsLength++]=e>2147483647?2147483647:e,this._subParamsIdx[this.length-1]++}}hasSubParams(e){return(255&this._subParamsIdx[e])-(this._subParamsIdx[e]>>8)>0}getSubParams(e){const t=this._subParamsIdx[e]>>8,i=255&this._subParamsIdx[e];return i-t>0?this._subParams.subarray(t,i):null}getSubParamsAll(){const e={};for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&(e[t]=this._subParams.slice(i,s))}return e}addDigit(e){let t;if(this._rejectDigits||!(t=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;const i=this._digitIsSub?this._subParams:this.params,s=i[t-1];i[t-1]=~s?Math.min(10*s+e,2147483647):e}}t.Params=i},3027(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.AddonManager=void 0,t.AddonManager=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){const i={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(i),t.dispose=()=>this._wrappedAddonDispose(i),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let i=0;i=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new s.CellData)}translateToString(e,t,i){return this._line.translateToString(e,t,i)}}},5101(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BufferNamespaceApi=void 0;const s=i(3235),r=i(4812),o=i(8636);class n extends r.Disposable{constructor(e){super(),this._core=e,this._onBufferChange=this._register(new o.Emitter),this.onBufferChange=this._onBufferChange.event,this._normal=new s.BufferApiView(this._core.buffers.normal,"normal"),this._alternate=new s.BufferApiView(this._core.buffers.alt,"alternate"),this._register(this._core.buffers.onBufferActivate(()=>this._onBufferChange.fire(this.active)))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw new Error("Active buffer is neither normal nor alternate")}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}}t.BufferNamespaceApi=n},6097(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ParserApi=void 0,t.ParserApi=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,e=>t(e.toArray()))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,(e,i)=>t(e,i.toArray()))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}registerApcHandler(e,t){return this._core.registerApcHandler(e,t)}}},4335(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeApi=void 0,t.UnicodeApi=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}}},9640(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferService=void 0;const o=i(4812),n=i(4097),a=i(6501),h=i(8636);let l=class extends o.Disposable{get buffer(){return this.buffers.active}constructor(e,t){super(),this.isUserScrolling=!1,this._onResize=this._register(new h.Emitter),this.onResize=this._onResize.event,this._onScroll=this._register(new h.Emitter),this.onScroll=this._onScroll.event,this.cols=Math.max(e.rawOptions.cols||0,2),this.rows=Math.max(e.rawOptions.rows||0,1),this.buffers=this._register(new n.BufferSet(e,this,t)),this._register(this.buffers.onBufferActivate(e=>{this._onScroll.fire(e.activeBuffer.ydisp)}))}resize(e,t){const i=this.cols!==e,s=this.rows!==t;this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t,colsChanged:i,rowsChanged:s})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){const i=this.buffer;let s;s=this._cachedBlankLine,s&&s.length===this.cols&&s.getFg(0)===e.fg&&s.getBg(0)===e.bg||(s=i.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;const r=i.ybase+i.scrollTop,o=i.ybase+i.scrollBottom;if(0===i.scrollTop){const e=i.lines.isFull;o===i.lines.length-1?e?i.lines.recycle().copyFrom(s):i.lines.push(s.clone()):i.lines.splice(o+1,0,s.clone()),e?this.isUserScrolling&&(i.ydisp=Math.max(i.ydisp-1,0)):(i.ybase++,this.isUserScrolling||i.ydisp++)}else{const e=o-r+1;i.lines.shiftElements(r+1,e-1,-1),i.lines.set(o,s.clone())}this.isUserScrolling||(i.ydisp=i.ybase),this._onScroll.fire(i.ydisp)}scrollLines(e,t){const i=this.buffer;if(e<0){if(0===i.ydisp)return;this.isUserScrolling=!0}else e+i.ydisp>=i.ybase&&(this.isUserScrolling=!1);const s=i.ydisp;i.ydisp=Math.max(Math.min(i.ydisp+e,i.ybase),0),s!==i.ydisp&&(t||this._onScroll.fire(i.ydisp))}};t.BufferService=l,t.BufferService=l=s([r(0,a.IOptionsService),r(1,a.ILogService)],l)},5746(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.CharsetService=void 0,t.CharsetService=class{constructor(){this.glevel=0,this._charsets=[]}get charsets(){return this._charsets}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(e){this.glevel=e,this.charset=this._charsets[e]}setgCharset(e,t){this._charsets[e]=t,this.glevel===e&&(this.charset=t)}}},4071(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CoreService=void 0;const o=i(4812),n=i(6501),a=i(8636),h=Object.freeze({insertMode:!1}),l=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,colorSchemeUpdates:!1,cursorBlink:void 0,cursorStyle:void 0,origin:!1,reverseWraparound:!1,sendFocus:!1,synchronizedOutput:!1,win32InputMode:!1,wraparound:!0});let c=class extends o.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._logService=t,this._optionsService=i,this.isCursorHidden=!1,this._onData=this._register(new a.Emitter),this.onData=this._onData.event,this._onUserInput=this._register(new a.Emitter),this.onUserInput=this._onUserInput.event,this._onBinary=this._register(new a.Emitter),this.onBinary=this._onBinary.event,this._onRequestScrollToBottom=this._register(new a.Emitter),this.onRequestScrollToBottom=this._onRequestScrollToBottom.event,this.isCursorInitialized=i.rawOptions.showCursorImmediately??!1,this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}reset(){this.modes=structuredClone(h),this.decPrivateModes=structuredClone(l),this.kittyKeyboard={flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;const i=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&i.ybase!==i.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data "${e}"`),this._logService.trace("sending data (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary "${e}"`),this._logService.trace("sending binary (codes)",()=>e.split("").map(e=>e.charCodeAt(0))),this._onBinary.fire(e))}};t.CoreService=c,t.CoreService=c=s([r(0,n.IBufferService),r(1,n.ILogService),r(2,n.IOptionsService)],c)},4720(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationLineCache=t.DecorationService=void 0;const o=i(3132),n=i(4103),a=i(4812),h=i(6501),l=i(3087),c=i(8636);let d=0,_=0,u=class extends a.Disposable{get decorations(){return this._decorations.values()}constructor(e,t){super(),this._logService=e,this._bufferService=t,this._lineCache=this._register(new f),this._onDecorationRegistered=this._register(new c.Emitter),this.onDecorationRegistered=this._onDecorationRegistered.event,this._onDecorationRemoved=this._register(new c.Emitter),this.onDecorationRemoved=this._onDecorationRemoved.event,this._decorations=new l.SortedList(e=>e?.marker.line,this._logService),this._register((0,a.toDisposable)(()=>this.reset())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)})),this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)}registerDecoration(e){if(e.marker.isDisposed)return;const t=new p(e);if(t){const e=t.marker.onDispose(()=>t.dispose()),i=t.onDispose(()=>{i.dispose(),t&&(this._decorations.delete(t)&&(this._lineCache.remove(t),this._onDecorationRemoved.fire(t)),e.dispose())});this._decorations.insert(t),this._lineCache.add(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(const e of this._decorations.values())e.dispose();this._decorations.clear(),this._lineCache.clear()}*getDecorationsAtCell(e,t,i){const s=this._lineCache.getDecorationsOnLine(t);if(s)for(const t of s)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&(yield t)}forEachDecorationAtCell(e,t,i,s){const r=this._lineCache.getDecorationsOnLine(t);if(r)for(const t of r)d=t.options.x??0,_=d+(t.options.width??1),e>=d&&e<_&&(!i||(t.options.layer??"bottom")===i)&&s(t)}};t.DecorationService=u,t.DecorationService=u=s([r(0,h.ILogService),r(1,h.IBufferService)],u);class f extends a.Disposable{constructor(){super(...arguments),this._decorationsByLine=new Map,this._decorations=new Set,this._bufferLineListeners=this._register(new a.MutableDisposable),this._lineIndexSyncTimer=this._register(new o.MicrotaskTimer),this._lineIndexSyncCallbacks=[]}clear(){this._lineIndexSyncCallbacks.length=0,this._lineIndexSyncTimer.cancel(),this._decorationsByLine.clear(),this._decorations.clear()}add(e){this._decorations.add(e),this._addToLineBuckets(e)}remove(e){this._decorations.delete(e),this._removeFromLineBuckets(e)}getDecorationsOnLine(e){return this._decorationsByLine.get(e)}attachToBufferLines(e){const t=new a.DisposableStore;this._bufferLineListeners.value=t,t.add(e.onTrim(e=>this._handleBufferLinesTrim(e))),t.add(e.onInsert(e=>this._handleBufferLinesInsert(e))),t.add(e.onDelete(e=>this._handleBufferLinesDelete(e)))}_getDecorationHeight(e){return e.options.height??1}_addToLineBuckets(e){const t=e.marker.line;if(t<0)return;e._indexedStartLine=t;const i=this._getDecorationHeight(e);for(let s=t;s=0&&this._addToLineBuckets(e)}_scheduleLineIndexSync(e){this._lineIndexSyncCallbacks.push(e),this._lineIndexSyncTimer.set(()=>{const e=this._lineIndexSyncCallbacks;this._lineIndexSyncCallbacks=[];for(const t of e)t()})}_handleBufferLinesTrim(e){if(e<=0)return;const t=new Map;for(const[i,s]of this._decorationsByLine){const r=i-e;r<0||this._mergeLineBucket(t,r,s)}this._decorationsByLine.clear();for(const[e,i]of t)this._decorationsByLine.set(e,i);for(const t of this._decorations)t.marker.isDisposed||(t._indexedStartLine-=e)}_handleBufferLinesInsert(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesInsert(e))}_handleBufferLinesDelete(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesDelete(e))}_mergeLineBucket(e,t,i){const s=e.get(t);if(s)for(let e=0,t=i.length;et&&(s.push(e),this._removeFromLineBuckets(e))}const r=new Map;for(const[e,s]of this._decorationsByLine){const o=e>=t?e+i:e;this._mergeLineBucket(r,o,s)}this._decorationsByLine.clear();for(const[e,t]of r)this._decorationsByLine.set(e,t);for(const e of this._decorations)e.marker.isDisposed||e._indexedStartLine>=t&&(e._indexedStartLine=e.marker.line);for(const e of s)this._addToLineBuckets(e)}_applyBufferLinesDelete(e){const t=e.index+e.amount,i=new Map;for(const[s,r]of this._decorationsByLine){if(s>=e.index&&s=t?s-e.amount:s;this._mergeLineBucket(i,o,r)}this._decorationsByLine.clear();for(const[e,t]of i)this._decorationsByLine.set(e,t);const s=[];for(const i of this._decorations){if(i.marker.isDisposed)continue;const r=i._indexedStartLine,o=this._getDecorationHeight(i);r>=t?i._indexedStartLine=i.marker.line:rt&&s.push(i)}for(const e of s)this._reindexDecoration(e)}}t.DecorationLineCache=f;class p extends a.DisposableStore{get backgroundColorRGB(){return null===this._cachedBg&&(this.options.backgroundColor?this._cachedBg=n.css.toColor(this.options.backgroundColor):this._cachedBg=void 0),this._cachedBg}get foregroundColorRGB(){return null===this._cachedFg&&(this.options.foregroundColor?this._cachedFg=n.css.toColor(this.options.foregroundColor):this._cachedFg=void 0),this._cachedFg}constructor(e){super(),this.options=e,this.onRenderEmitter=this.add(new c.Emitter),this.onRender=this.onRenderEmitter.event,this._onDispose=this.add(new c.Emitter),this.onDispose=this._onDispose.event,this._cachedBg=null,this._cachedFg=null,this.marker=e.marker,this._indexedStartLine=e.marker.line,this.options.overviewRulerOptions&&!this.options.overviewRulerOptions.position&&(this.options.overviewRulerOptions.position="full")}dispose(){this._onDispose.fire(),super.dispose()}}},6025(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.InstantiationService=t.ServiceCollection=void 0;const s=i(6501),r=i(6201);class o{constructor(...e){this._entries=new Map;for(const[t,i]of e)this.set(t,i)}set(e,t){const i=this._entries.get(e);return this._entries.set(e,t),i}forEach(e){for(const[t,i]of this._entries.entries())e(t,i)}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)}}t.ServiceCollection=o,t.InstantiationService=class{constructor(){this._services=new o,this._services.set(s.IInstantiationService,this)}setService(e,t){this._services.set(e,t)}getService(e){return this._services.get(e)}createInstance(e,...t){const i=(0,r.getServiceDependencies)(e).sort((e,t)=>e.index-t.index),s=[];for(const t of i){const i=this._services.get(t.id);if(!i)throw new Error(`[createInstance] ${e.name} depends on UNKNOWN service ${t.id._id}.`);s.push(i)}const o=i.length>0?i[0].index:t.length;if(t.length!==o)throw new Error(`[createInstance] First service dependency of ${e.name} at position ${o+1} conflicts with ${t.length} static arguments`);return new e(...[...t,...s])}}},7276(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.LogService=void 0;const o=i(4812),n=i(6501),a={trace:n.LogLevelEnum.TRACE,debug:n.LogLevelEnum.DEBUG,info:n.LogLevelEnum.INFO,warn:n.LogLevelEnum.WARN,error:n.LogLevelEnum.ERROR,off:n.LogLevelEnum.OFF};let h=class extends o.Disposable{get logLevel(){return this._logLevel}constructor(e){super(),this._optionsService=e,this._logLevel=n.LogLevelEnum.OFF,this._updateLogLevel(),this._register(this._optionsService.onSpecificOptionChange("logLevel",()=>this._updateLogLevel()))}_updateLogLevel(){this._logLevel=a[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;t!1},X10:{events:1,restrict:e=>4!==e.button&&1===e.action&&(e.ctrl=!1,e.alt=!1,e.shift=!1,!0)},VT200:{events:19,restrict:e=>32!==e.action},DRAG:{events:23,restrict:e=>32!==e.action||3!==e.button},ANY:{events:31,restrict:e=>!0}};function n(e,t){let i=(e.ctrl?16:0)|(e.shift?4:0)|(e.alt?8:0);return 4===e.button?(i|=64,i|=e.action):(i|=3&e.button,4&e.button&&(i|=64),8&e.button&&(i|=128),32===e.action?i|=32:0!==e.action||t||(i|=3)),i}const a=String.fromCharCode,h={DEFAULT:e=>{const t=[n(e,!1)+32,e.col+32,e.row+32];return t[0]>255||t[1]>255||t[2]>255?"":`${a(t[0])}${a(t[1])}${a(t[2])}`},SGR:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.col};${e.row}${t}`},SGR_PIXELS:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${n(e,!0)};${e.x};${e.y}${t}`}};class l extends s.Disposable{constructor(){super(),this._protocols={},this._encodings={},this._activeProtocol="",this._activeEncoding="",this._onProtocolChange=this._register(new r.Emitter),this.onProtocolChange=this._onProtocolChange.event;for(const e of Object.keys(o))this.addProtocol(e,o[e]);for(const e of Object.keys(h))this.addEncoding(e,h[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return 0!==this._protocols[this._activeProtocol].events}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol "${e}"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding "${e}"`);this._activeEncoding=e}reset(){this.activeProtocol="NONE",this.activeEncoding="DEFAULT"}setCustomWheelEventHandler(e){this._customWheelEventHandler=e}allowCustomWheelEvent(e){return!this._customWheelEventHandler||!1!==this._customWheelEventHandler(e)}restrictMouseEvent(e){return this._protocols[this._activeProtocol].restrict(e)}encodeMouseEvent(e){return this._encodings[this._activeEncoding](e)}get isDefaultEncoding(){return"DEFAULT"===this._activeEncoding}get isPixelEncoding(){return"SGR_PIXELS"===this._activeEncoding}}t.MouseStateService=l},56(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.OptionsService=t.DEFAULT_OPTIONS=void 0;const s=i(4812),r=i(701),o=i(8636);t.DEFAULT_OPTIONS={cols:80,rows:24,showCursorImmediately:!1,cursorBlink:!1,blinkIntervalDuration:0,cursorStyle:"block",cursorWidth:1,cursorInactiveStyle:"outline",drawBoldTextInBrightColors:!0,documentOverride:null,fastScrollSensitivity:5,fontFamily:"monospace",fontSize:15,fontWeight:"normal",fontWeightBold:"bold",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:"info",logger:null,scrollback:1e3,scrollbar:{showScrollbar:!0},scrollOnEraseInDisplay:!1,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,mouseEventsRequireAlt:!1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},reflowCursorLine:!1,rescaleOverlappingGlyphs:!1,rightClickSelectsWord:r.isMac,windowOptions:{},windowsPty:{},wordSeparator:" ()[]{}',\"`",altClickMovesCursor:!0,convertEol:!1,termName:"xterm",quirks:{},vtExtensions:{}};const n=["normal","bold","100","200","300","400","500","600","700","800","900"];class a extends s.Disposable{constructor(e){super(),this._onOptionChange=this._register(new o.Emitter),this.onOptionChange=this._onOptionChange.event;const i={...t.DEFAULT_OPTIONS};for(const t in e)if(t in i)try{const s=e[t];i[t]=this._sanitizeAndValidateOption(t,s)}catch(e){console.error(e)}this.rawOptions=i,this.options={...i},this._setupOptions(),this._register((0,s.toDisposable)(()=>{this.rawOptions.linkHandler=null,this.rawOptions.documentOverride=null}))}onSpecificOptionChange(e,t){return this.onOptionChange(i=>{i===e&&t(this.rawOptions[e])})}onMultipleOptionChange(e,t){return this.onOptionChange(i=>{-1!==e.indexOf(i)&&t()})}_setupOptions(){const e=e=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);return this.rawOptions[e]},i=(e,i)=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);i=this._sanitizeAndValidateOption(e,i),this.rawOptions[e]!==i&&(this.rawOptions[e]=i,this._onOptionChange.fire(e))};for(const t in this.rawOptions){const s={get:e.bind(this,t),set:i.bind(this,t)};Object.defineProperty(this.options,t,s)}}_sanitizeAndValidateOption(e,i){switch(e){case"cursorStyle":if(i||(i=t.DEFAULT_OPTIONS[e]),!function(e){return"block"===e||"underline"===e||"bar"===e}(i))throw new Error(`"${i}" is not a valid value for ${e}`);break;case"wordSeparator":i||(i=t.DEFAULT_OPTIONS[e]);break;case"fontWeight":case"fontWeightBold":if("number"==typeof i&&1<=i&&i<=1e3)break;i=n.includes(i)?i:t.DEFAULT_OPTIONS[e];break;case"blinkIntervalDuration":if((i=Math.floor(i))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"cursorWidth":i=Math.floor(i);case"lineHeight":case"tabStopWidth":if(i<1)throw new Error(`${e} cannot be less than 1, value: ${i}`);break;case"minimumContrastRatio":i=Math.max(1,Math.min(21,Math.round(10*i)/10));break;case"scrollback":if((i=Math.min(i,4294967295))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"fastScrollSensitivity":case"scrollSensitivity":if(i<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${i}`);break;case"rows":case"cols":if(!i&&0!==i)throw new Error(`${e} must be numeric, value: ${i}`);break;case"windowsPty":i=i??{}}return i}}t.OptionsService=a},8811(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,o=arguments.length,n=o<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(o<3?r(n):o>3?r(t,i,n):r(t,i))||n);return o>3&&n&&Object.defineProperty(t,i,n),n},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkService=void 0;const o=i(6501);let n=class{constructor(e){this._bufferService=e,this._nextId=1,this._entriesWithId=new Map,this._dataByLinkId=new Map}registerLink(e){const t=this._bufferService.buffer;if(void 0===e.id){const i=t.addMarker(t.ybase+t.y),s={data:e,id:this._nextId++,lines:[i]};return i.onDispose(()=>this._removeMarkerFromLink(s,i)),this._dataByLinkId.set(s.id,s),s.id}const i=e,s=this._getEntryIdKey(i),r=this._entriesWithId.get(s);if(r)return this.addLineToLink(r.id,t.ybase+t.y),r.id;const o=t.addMarker(t.ybase+t.y),n={id:this._nextId++,key:this._getEntryIdKey(i),data:i,lines:[o]};return o.onDispose(()=>this._removeMarkerFromLink(n,o)),this._entriesWithId.set(n.key,n),this._dataByLinkId.set(n.id,n),n.id}addLineToLink(e,t){const i=this._dataByLinkId.get(e);if(i&&i.lines.every(e=>e.line!==t)){const e=this._bufferService.buffer.addMarker(t);i.lines.push(e),e.onDispose(()=>this._removeMarkerFromLink(i,e))}}getLinkData(e){return this._dataByLinkId.get(e)?.data}_getEntryIdKey(e){return`${e.id};;${e.uri}`}_removeMarkerFromLink(e,t){const i=e.lines.indexOf(t);-1!==i&&(e.lines.splice(i,1),0===e.lines.length&&(void 0!==e.data.id&&this._entriesWithId.delete(e.key),this._dataByLinkId.delete(e.id)))}};t.OscLinkService=n,t.OscLinkService=n=s([r(0,o.IBufferService)],n)},6201(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.serviceRegistry=void 0,t.getServiceDependencies=function(e){return e.di$dependencies||[]},t.createDecorator=function(e){if(t.serviceRegistry.has(e))return t.serviceRegistry.get(e);const i=function(e,t,s){if(3!==arguments.length)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");!function(e,t,i){t.di$target===t?t.di$dependencies.push({id:e,index:i}):(t.di$dependencies=[{id:e,index:i}],t.di$target=t)}(i,e,s)};return i._id=e,t.serviceRegistry.set(e,i),i},t.serviceRegistry=new Map},6501(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.IDecorationService=t.IUnicodeService=t.IOscLinkService=t.IOptionsService=t.ILogService=t.LogLevelEnum=t.IInstantiationService=t.ICharsetService=t.ICoreService=t.IMouseStateService=t.IBufferService=void 0;const s=i(6201);var r;t.IBufferService=(0,s.createDecorator)("BufferService"),t.IMouseStateService=(0,s.createDecorator)("MouseStateService"),t.ICoreService=(0,s.createDecorator)("CoreService"),t.ICharsetService=(0,s.createDecorator)("CharsetService"),t.IInstantiationService=(0,s.createDecorator)("InstantiationService"),function(e){e[e.TRACE=0]="TRACE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.OFF=5]="OFF"}(r||(t.LogLevelEnum=r={})),t.ILogService=(0,s.createDecorator)("LogService"),t.IOptionsService=(0,s.createDecorator)("OptionsService"),t.IOscLinkService=(0,s.createDecorator)("OscLinkService"),t.IUnicodeService=(0,s.createDecorator)("UnicodeService"),t.IDecorationService=(0,s.createDecorator)("DecorationService")},6415(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeService=void 0;const s=i(8636);class r{constructor(){this._providers=Object.create(null),this._active="",this._onChange=new s.Emitter,this.onChange=this._onChange.event}static extractShouldJoin(e){return!!(1&e)}static extractWidth(e){return e>>1&3}static extractCharKind(e){return e>>3}static createPropertyValue(e,t,i=!1){return(16777215&e)<<3|(3&t)<<1|(i?1:0)}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(e){if(!this._providers[e])throw new Error(`unknown Unicode version "${e}"`);this._active=e,this._activeProvider=this._providers[e],this._onChange.fire(e)}register(e){this._providers[e.version]=e,this._active||(this.activeVersion=e.version)}wcwidth(e){return this._activeProvider.wcwidth(e)}getStringCellWidth(e){let t=0,i=0;const s=e.length;for(let o=0;o=s)return t+this.wcwidth(n);const i=e.charCodeAt(o);56320<=i&&i<=57343?n=1024*(n-55296)+i-56320+65536:t+=this.wcwidth(i)}const a=this.charProperties(n,i);let h=r.extractWidth(a);r.extractShouldJoin(a)&&(h-=r.extractWidth(i)),t+=h,i=a}return t}charProperties(e,t){return this._activeProvider.charProperties(e,t)}}t.UnicodeService=r}},t={};return function i(s){var r=t[s];if(void 0!==r)return r.exports;var o=t[s]={exports:{}};return e[s].call(o.exports,o,o.exports,i),o.exports}(6081)})()); //# sourceMappingURL=xterm.js.map \ No newline at end of file diff --git a/lib/xterm.js.map b/lib/xterm.js.map -index ba88618b821ff21e51e8c58a63813d82b939fc77..541e4d5a6bcffb8552bd945fa04ee2f9eb6c8c22 100644 +index ba88618b821ff21e51e8c58a63813d82b939fc77..fde85381c605860cbf97ba2899e6535a51bf737f 100644 --- a/lib/xterm.js.map +++ b/lib/xterm.js.map @@ -1 +1 @@ -{"version":3,"file":"xterm.js","mappings":"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AAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,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","sources":["webpack://@xterm/xterm/webpack/universalModuleDefinition","webpack://@xterm/xterm/./src/browser/AccessibilityManager.ts","webpack://@xterm/xterm/./src/browser/Clipboard.ts","webpack://@xterm/xterm/./src/browser/ColorContrastCache.ts","webpack://@xterm/xterm/./src/browser/CoreBrowserTerminal.ts","webpack://@xterm/xterm/./src/browser/Dom.ts","webpack://@xterm/xterm/./src/browser/Linkifier.ts","webpack://@xterm/xterm/./src/browser/LocalizableStrings.ts","webpack://@xterm/xterm/./src/browser/OscLinkProvider.ts","webpack://@xterm/xterm/./src/browser/RenderDebouncer.ts","webpack://@xterm/xterm/./src/browser/TimeBasedDebouncer.ts","webpack://@xterm/xterm/./src/browser/Types.ts","webpack://@xterm/xterm/./src/browser/Viewport.ts","webpack://@xterm/xterm/./src/browser/decorations/BufferDecorationRenderer.ts","webpack://@xterm/xterm/./src/browser/decorations/ColorZoneStore.ts","webpack://@xterm/xterm/./src/browser/decorations/OverviewRulerRenderer.ts","webpack://@xterm/xterm/./src/browser/input/CompositionHelper.ts","webpack://@xterm/xterm/./src/browser/input/Mouse.ts","webpack://@xterm/xterm/./src/browser/input/MoveToCell.ts","webpack://@xterm/xterm/./src/browser/public/Terminal.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRenderer.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRendererRowFactory.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/WidthCache.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/Constants.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/RendererUtils.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/SelectionRenderModel.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/TextBlinkStateManager.ts","webpack://@xterm/xterm/./src/browser/scrollable/abstractScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/fastDomNode.ts","webpack://@xterm/xterm/./src/browser/scrollable/globalPointerMoveMonitor.ts","webpack://@xterm/xterm/./src/browser/scrollable/horizontalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/mouseEvent.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollable.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollableElement.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarArrow.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarState.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarVisibilityController.ts","webpack://@xterm/xterm/./src/browser/scrollable/touch.ts","webpack://@xterm/xterm/./src/browser/scrollable/verticalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/widget.ts","webpack://@xterm/xterm/./src/browser/selection/SelectionModel.ts","webpack://@xterm/xterm/./src/browser/services/CharSizeService.ts","webpack://@xterm/xterm/./src/browser/services/CharacterJoinerService.ts","webpack://@xterm/xterm/./src/browser/services/CoreBrowserService.ts","webpack://@xterm/xterm/./src/browser/services/KeyboardService.ts","webpack://@xterm/xterm/./src/browser/services/LinkProviderService.ts","webpack://@xterm/xterm/./src/browser/services/MouseCoordsService.ts","webpack://@xterm/xterm/./src/browser/services/MouseService.ts","webpack://@xterm/xterm/./src/browser/services/RenderService.ts","webpack://@xterm/xterm/./src/browser/services/SelectionService.ts","webpack://@xterm/xterm/./src/browser/services/Services.ts","webpack://@xterm/xterm/./src/browser/services/ThemeService.ts","webpack://@xterm/xterm/./src/common/Async.ts","webpack://@xterm/xterm/./src/common/CircularList.ts","webpack://@xterm/xterm/./src/common/Color.ts","webpack://@xterm/xterm/./src/common/CoreTerminal.ts","webpack://@xterm/xterm/./src/common/Event.ts","webpack://@xterm/xterm/./src/common/InputHandler.ts","webpack://@xterm/xterm/./src/common/Lifecycle.ts","webpack://@xterm/xterm/./src/common/MultiKeyMap.ts","webpack://@xterm/xterm/./src/common/Platform.ts","webpack://@xterm/xterm/./src/common/SortedList.ts","webpack://@xterm/xterm/./src/common/StringBuilder.ts","webpack://@xterm/xterm/./src/common/TaskQueue.ts","webpack://@xterm/xterm/./src/common/Version.ts","webpack://@xterm/xterm/./src/common/WindowsMode.ts","webpack://@xterm/xterm/./src/common/buffer/AttributeData.ts","webpack://@xterm/xterm/./src/common/buffer/Buffer.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLine.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLineStringCache.ts","webpack://@xterm/xterm/./src/common/buffer/BufferRange.ts","webpack://@xterm/xterm/./src/common/buffer/BufferReflow.ts","webpack://@xterm/xterm/./src/common/buffer/BufferSet.ts","webpack://@xterm/xterm/./src/common/buffer/CellData.ts","webpack://@xterm/xterm/./src/common/buffer/Constants.ts","webpack://@xterm/xterm/./src/common/buffer/Marker.ts","webpack://@xterm/xterm/./src/common/data/Charsets.ts","webpack://@xterm/xterm/./src/common/input/Keyboard.ts","webpack://@xterm/xterm/./src/common/input/KittyKeyboard.ts","webpack://@xterm/xterm/./src/common/input/TextDecoder.ts","webpack://@xterm/xterm/./src/common/input/UnicodeV6.ts","webpack://@xterm/xterm/./src/common/input/Win32InputMode.ts","webpack://@xterm/xterm/./src/common/input/WriteBuffer.ts","webpack://@xterm/xterm/./src/common/input/XParseColor.ts","webpack://@xterm/xterm/./src/common/parser/ApcParser.ts","webpack://@xterm/xterm/./src/common/parser/DcsParser.ts","webpack://@xterm/xterm/./src/common/parser/EscapeSequenceParser.ts","webpack://@xterm/xterm/./src/common/parser/OscParser.ts","webpack://@xterm/xterm/./src/common/parser/Params.ts","webpack://@xterm/xterm/./src/common/public/AddonManager.ts","webpack://@xterm/xterm/./src/common/public/BufferApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferLineApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferNamespaceApi.ts","webpack://@xterm/xterm/./src/common/public/ParserApi.ts","webpack://@xterm/xterm/./src/common/public/UnicodeApi.ts","webpack://@xterm/xterm/./src/common/services/BufferService.ts","webpack://@xterm/xterm/./src/common/services/CharsetService.ts","webpack://@xterm/xterm/./src/common/services/CoreService.ts","webpack://@xterm/xterm/./src/common/services/DecorationService.ts","webpack://@xterm/xterm/./src/common/services/InstantiationService.ts","webpack://@xterm/xterm/./src/common/services/LogService.ts","webpack://@xterm/xterm/./src/common/services/MouseStateService.ts","webpack://@xterm/xterm/./src/common/services/OptionsService.ts","webpack://@xterm/xterm/./src/common/services/OscLinkService.ts","webpack://@xterm/xterm/./src/common/services/ServiceRegistry.ts","webpack://@xterm/xterm/./src/common/services/Services.ts","webpack://@xterm/xterm/./src/common/services/UnicodeService.ts","webpack://@xterm/xterm/webpack/bootstrap","webpack://@xterm/xterm/webpack/startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (␛).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', () => this._compositionHelper!.compositionend()));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n this.coreService.triggerDataEvent(key, true);\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private _isSendingComposition: boolean;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isSendingComposition = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._isComposing = true;\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data}\\u200E`;\n this.updateCompositionElements();\n setTimeout(() => {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max( this._compositionPosition.start, end);\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(): void {\n this._finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._isComposing || this._isSendingComposition) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean): void {\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n\n if (!waitForPropagation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this._isSendingComposition = false;\n const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);\n this._coreService.triggerDataEvent(input, true);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n };\n const currentCompositionSuffix = this._compositionSuffix;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this._isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this._isSendingComposition) {\n this._isSendingComposition = false;\n let input;\n // Add length of data already sent due to keydown event,\n // otherwise input characters can be duplicated. (Issue #3191)\n currentCompositionPosition.start += this._dataAlreadySent.length;\n if (this._isComposing) {\n // Use the start position of the new composition to get the string\n // if a new composition has started.\n input = this._textarea.value.substring(currentCompositionPosition.start, this._compositionPosition.start);\n } else {\n // Keep support for non-composition characters typed immediately after composition end\n // while avoiding re-sending the trailing text that was already present\n // before composition started.\n const value = this._textarea.value;\n const valueEnd = currentCompositionSuffix.length > 0 && value.endsWith(currentCompositionSuffix)\n ? value.length - currentCompositionSuffix.length\n : value.length;\n input = value.substring(currentCompositionPosition.start, Math.max(currentCompositionPosition.start, valueEnd));\n }\n if (input.length > 0) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n","/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n","/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const INVERTED_DEFAULT_COLOR = 257;\n\nexport const enum RendererConstants {\n /**\n * The idle time after which cursor blinking stops.\n */\n CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n","import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n²) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const DEFAULT_COLOR = 0;\nexport const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);\nexport const DEFAULT_EXT = 0;\n\nexport const CHAR_DATA_ATTR_INDEX = 0;\nexport const CHAR_DATA_CHAR_INDEX = 1;\nexport const CHAR_DATA_WIDTH_INDEX = 2;\nexport const CHAR_DATA_CODE_INDEX = 3;\n\n/**\n * Null cell - a real empty cell (containing nothing).\n * Note that code should always be 0 for a null cell as\n * several test condition of the buffer line rely on this.\n */\nexport const NULL_CELL_CHAR = '';\nexport const NULL_CELL_WIDTH = 1;\nexport const NULL_CELL_CODE = 0;\n\n/**\n * Whitespace cell.\n * This is meant as a replacement for empty cells when needed\n * during rendering lines to preserve correct alignment.\n */\nexport const WHITESPACE_CELL_CHAR = ' ';\nexport const WHITESPACE_CELL_WIDTH = 1;\nexport const WHITESPACE_CELL_CODE = 32;\n\n/**\n * Bitmasks for accessing data in `content`.\n */\nexport const enum Content {\n /**\n * bit 1..21 codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)\n * read: `codepoint = content & Content.CODEPOINT_MASK;`\n * write: `content |= codepoint & Content.CODEPOINT_MASK;`\n * shortcut if precondition `codepoint <= 0x10FFFF` is met:\n * `content |= codepoint;`\n */\n CODEPOINT_MASK = 0x1FFFFF,\n\n /**\n * bit 22 flag indicating whether a cell contains combined content\n * read: `isCombined = content & Content.IS_COMBINED_MASK;`\n * set: `content |= Content.IS_COMBINED_MASK;`\n * clear: `content &= ~Content.IS_COMBINED_MASK;`\n */\n IS_COMBINED_MASK = 0x200000, // 1 << 21\n\n /**\n * bit 1..22 mask to check whether a cell contains any string data\n * we need to check for codepoint and isCombined bits to see\n * whether a cell contains anything\n * read: `isEmpty = !(content & Content.HAS_CONTENT_MASK)`\n */\n HAS_CONTENT_MASK = 0x3FFFFF,\n\n /**\n * bit 23..24 wcwidth value of cell, takes 2 bits (ranges from 0..2)\n * read: `width = (content & Content.WIDTH_MASK) >> Content.WIDTH_SHIFT;`\n * `hasWidth = content & Content.WIDTH_MASK;`\n * as long as wcwidth is highest value in `content`:\n * `width = content >> Content.WIDTH_SHIFT;`\n * write: `content |= (width << Content.WIDTH_SHIFT) & Content.WIDTH_MASK;`\n * shortcut if precondition `0 <= width <= 3` is met:\n * `content |= width << Content.WIDTH_SHIFT;`\n */\n WIDTH_MASK = 0xC00000, // 3 << 22\n WIDTH_SHIFT = 22\n}\n\nexport const enum Attributes {\n /**\n * bit 1..8 blue in RGB, color in P256 and P16\n */\n BLUE_MASK = 0xFF,\n BLUE_SHIFT = 0,\n PCOLOR_MASK = 0xFF,\n PCOLOR_SHIFT = 0,\n\n /**\n * bit 9..16 green in RGB\n */\n GREEN_MASK = 0xFF00,\n GREEN_SHIFT = 8,\n\n /**\n * bit 17..24 red in RGB\n */\n RED_MASK = 0xFF0000,\n RED_SHIFT = 16,\n\n /**\n * bit 25..26 color mode: DEFAULT (0) | P16 (1) | P256 (2) | RGB (3)\n */\n CM_MASK = 0x3000000,\n CM_DEFAULT = 0,\n CM_P16 = 0x1000000,\n CM_P256 = 0x2000000,\n CM_RGB = 0x3000000,\n\n /**\n * bit 1..24 RGB room\n */\n RGB_MASK = 0xFFFFFF\n}\n\nexport const enum FgFlags {\n /**\n * bit 27..32\n */\n INVERSE = 0x4000000,\n BOLD = 0x8000000,\n UNDERLINE = 0x10000000,\n BLINK = 0x20000000,\n INVISIBLE = 0x40000000,\n STRIKETHROUGH = 0x80000000,\n}\n\nexport const enum BgFlags {\n /**\n * bit 27..32 (upper 2 unused)\n */\n ITALIC = 0x4000000,\n DIM = 0x8000000,\n HAS_EXTENDED = 0x10000000,\n PROTECTED = 0x20000000,\n OVERLINE = 0x40000000\n}\n\nexport const enum ExtFlags {\n /**\n * bit 27..29\n */\n UNDERLINE_STYLE = 0x1C000000,\n\n /**\n * bit 30..32\n *\n * An optional variant for the glyph, this can be used for example to offset underlines by a\n * number of pixels to create a perfect pattern.\n */\n VARIANT_OFFSET = 0xE0000000\n}\n\nexport const enum UnderlineStyle {\n NONE = 0,\n SINGLE = 1,\n DOUBLE = 2,\n CURLY = 3,\n DOTTED = 4,\n DASHED = 5\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u2409', // '␉' (HT)\n 'c': '\\u240c', // '␌' (FF)\n 'd': '\\u240d', // '␍' (CR)\n 'e': '\\u240a', // '␊' (LF)\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '␤' (NL)\n 'i': '\\u240b', // '␋' (VT)\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec § \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" — i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n","\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(6081);\n"],"names":["root","factory","exports","module","define","amd","a","i","globalThis","Strings","__importStar","__webpack_require__","TimeBasedDebouncer_1","Lifecycle_1","Services_1","Services_2","Dom_1","AccessibilityManager","Disposable","constructor","_terminal","instantiationService","_coreBrowserService","_renderService","super","this","_rowColumns","WeakMap","_liveRegionLineCount","_charsToConsume","_charsToAnnounce","doc","mainDocument","_accessibilityContainer","createElement","classList","add","_rowContainer","setAttribute","_rowElements","rows","_createAccessibilityTreeNode","appendChild","_topBoundaryFocusListener","e","_handleBoundaryFocus","_bottomBoundaryFocusListener","addEventListener","length","_liveRegion","_liveRegionDebouncer","_register","TimeBasedDebouncer","_renderRows","bind","element","Error","insertAdjacentElement","onResize","_handleResize","onRender","_refreshRows","start","end","onScroll","onA11yChar","char","_handleChar","onLineFeed","onA11yTab","spaceCount","_handleTab","onKey","_handleKey","key","onBlur","_clearLiveRegion","onDimensionsChange","_refreshRowsDimensions","addDisposableListener","_handleSelectionChange","onDprChange","toDisposable","remove","shift","textContent","tooMuchOutput","get","keyChar","test","push","refresh","buffer","setSize","lines","toString","line","ydisp","columns","lineData","translateToString","undefined","posInSet","set","_alignRowWidth","_announceCharacters","position","boundaryElement","target","beforeBoundaryElement","getAttribute","relatedTarget","topBoundaryElement","bottomBoundaryElement","pop","removeChild","removeEventListener","newElement","unshift","scrollLines","focus","preventDefault","stopImmediatePropagation","selection","getSelection","isCollapsed","contains","anchorNode","clearSelection","focusNode","console","error","begin","node","offset","anchorOffset","focusOffset","compareDocumentPosition","Node","DOCUMENT_POSITION_PRECEDING","DOCUMENT_POSITION_CONTAINED_BY","DOCUMENT_POSITION_FOLLOWING","childNodes","lastRowElement","slice","toRowColumn","rowElement","Text","parentNode","row","parseInt","isNaN","warn","column","cols","beginRowColumn","endRowColumn","select","children","tabIndex","_refreshRowDimensions","dimensions","css","cell","height","Object","assign","style","width","canvas","fontSize","options","transform","getBoundingClientRect","lastColumn","targetWidth","__decorate","__param","IInstantiationService","ICoreBrowserService","IRenderService","prepareTextForTerminal","text","replace","bracketTextForPaste","bracketedPasteMode","paste","textarea","coreService","optionsService","decPrivateModes","rawOptions","ignoreBracketedPasteMode","triggerDataEvent","value","moveTextAreaUnderMouseCursor","ev","screenElement","pos","left","clientX","top","clientY","zIndex","selectionService","clipboardData","setData","selectionText","stopPropagation","getData","shouldSelectWord","rightClickSelect","MultiKeyMap_1","_color","TwoKeyMap","_css","setCss","bg","fg","getCss","setColor","getColor","clear","Clipboard_1","OscLinkProvider_1","Viewport_1","BufferDecorationRenderer_1","OverviewRulerRenderer_1","CompositionHelper_1","DomRenderer_1","CharSizeService_1","CharacterJoinerService_1","CoreBrowserService_1","LinkProviderService_1","MouseCoordsService_1","MouseService_1","RenderService_1","SelectionService_1","ThemeService_1","KeyboardService_1","Color_1","CoreTerminal_1","Browser","BufferLine_1","XParseColor_1","DecorationService_1","InputHandler_1","AccessibilityManager_1","Linkifier_1","Event_1","CoreBrowserTerminal","CoreTerminal","linkifier","_linkifier","onFocus","_onFocus","event","_onBlur","_onA11yCharEmitter","_onA11yTabEmitter","onWillOpen","_onWillOpen","device","MutableDisposable","browser","_keyDownHandled","_keyDownSeen","_keyPressHandled","_unprocessedDeadKey","_accessibilityManager","_onCursorMove","Emitter","onCursorMove","_onKey","_onSelectionChange","onSelectionChange","_onTitleChange","onTitleChange","_onBell","onBell","_onDimensionsChange","_setup","_decorationService","_instantiationService","createInstance","DecorationService","setService","IDecorationService","_keyboardService","KeyboardService","IKeyboardService","_linkProviderService","LinkProviderService","ILinkProviderService","registerLinkProvider","OscLinkProvider","_inputHandler","onRequestBell","fire","onRequestRefreshRows","onRequestSendFocus","_reportFocus","onRequestReset","reset","onRequestWindowsOptionsReport","type","_reportWindowsOptions","onColor","_handleColorEvent","EventUtils","forward","_bufferService","_afterResize","_customKeyEventHandler","_themeService","req","acc","ident","index","colorRgb","color","toColorRGB","colors","ansi","toRgbString","modifyColors","channels","toColor","narrowedAcc","restoreColor","_reportColorScheme","colorSchemeMode","rgb","relativeLuminance","background","rgba","foreground","buffers","active","preventScroll","_handleScreenReaderModeOptionChange","_handleTextAreaFocus","sendFocus","_showCursor","blur","_handleTextAreaBlur","y","_syncTextArea","isCursorInViewport","_compositionHelper","isComposing","cursorY","ybase","bufferLine","cursorX","Math","min","x","cellHeight","getWidth","cellWidth","cursorTop","cursorLeft","lineHeight","_initGlobal","_bindKeys","hasSelection","copyHandler","_selectionService","pasteHandlerWrapper","handlePasteEvent","isFirefox","button","rightClickHandler","rightClickSelectsWord","isLinux","_keyUp","_keyDown","_keyPress","compositionstart","updateCompositionElements","compositionupdate","compositionend","_inputEvent","open","parent","isConnected","_logService","debug","ownerDocument","defaultView","window","_document","documentOverride","Document","dir","toggle","allowTransparency","onSpecificOptionChange","fragment","createDocumentFragment","_viewportElement","updateCursorStyle","_helperContainer","promptLabel","isChromeOS","readOnly","disableStdin","CoreBrowserService","document","_charSizeService","CharSizeService","ICharSizeService","ThemeService","IThemeService","onRequestColorSchemeQuery","onChangeColors","colorSchemeUpdates","_characterJoinerService","CharacterJoinerService","ICharacterJoinerService","RenderService","onRenderedViewportChange","_onRender","resize","_compositionView","CompositionHelper","_mouseCoordsService","MouseCoordsService","IMouseCoordsService","Linkifier","hasRenderer","setRenderer","_createRenderer","handleCursorMove","handleResize","handleBlur","handleFocus","_viewport","Viewport","onRequestScrollLines","SelectionService","ISelectionService","_mouseService","MouseService","IMouseService","amount","suppressScrollEvent","onRequestRedraw","handleSelectionChanged","columnSelectMode","onLinuxMouseSelection","any","_onScroll","queueSync","BufferDecorationRenderer","handleMouseDown","mouseStateService","areMouseEventsActive","mouseEventsRequireAlt","disable","enable","screenReaderMode","showScrollbar","scrollbar","overviewRulerWidth","_overviewRulerRenderer","OverviewRulerRenderer","shouldShow","measure","bindMouse","handleTouchScroll","disposable","DomRenderer","sync","refreshRows","shouldColumnSelect","isCursorInitialized","disp","scrollPages","pageCount","scrollToTop","scrollToBottom","disableSmoothScroll","scrollToLine","scrollAmount","data","attachCustomKeyEventHandler","customKeyEventHandler","attachCustomWheelEventHandler","customWheelEventHandler","setCustomWheelEventHandler","linkProvider","registerCharacterJoiner","handler","joinerId","register","deregisterCharacterJoiner","deregister","markers","registerMarker","cursorYOffset","addMarker","registerDecoration","decorationOptions","setSelection","getSelectionPosition","selectionStart","selectionEnd","selectAll","selectLines","shouldIgnoreComposition","isMac","macOptionIsMeta","altKey","keydown","scrollOnUserInput","result","evaluateKeyDown","scrollCount","_isThirdLevelShift","cancel","useKitty","useWin32InputMode","ctrlKey","metaKey","charCodeAt","wasModifierOnly","wasModifierKeyOnlyEvent","domEvent","thirdLevelKey","isWindows","getModifierState","keyCode","evaluateKeyUp","charCode","which","String","fromCharCode","inputType","composed","hasValidSize","clearAllMarkers","getBlankLine","DEFAULT_ATTR_DATA","clearTextureAtlas","WindowsOptionsReportType","GET_WIN_SIZE_PIXELS","canvasWidth","toFixed","canvasHeight","GET_CELL_SIZE_PIXELS","useCapture","domNode","bb","win","getWindow","scrollX","scrollY","targetWindow","runner","priority","state","getAnimationFrameState","item","AnimationFrameQueueItem","next","animFrameRequested","requestAnimationFrame","current","inAnimationFrameRunner","sort","execute","animationFrameRunner","Async_1","candidateNode","candidateEvent","view","DomListener","_node","_type","_handler","_options","dispose","useCaptureOrOptions","eventType","CLICK","MOUSE_DOWN","MOUSE_OVER","MOUSE_LEAVE","KEY_DOWN","KEY_UP","INPUT","BLUR","FOCUS","CHANGE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","MOUSE_WHEEL","WHEEL","_runner","_canceled","b","animationFrameState","Map","WindowIntervalTimer","IntervalTimer","_defaultTarget","cancelAndSet","interval","currentLink","_currentLink","_element","_linkCacheDisposables","_isMouseOut","_wasResized","_activeLine","_onShowLinkUnderline","onShowLinkUnderline","_onHideLinkUnderline","onHideLinkUnderline","_lastMouseEvent","_activeProviderReplies","_clearCurrentLink","_handleMouseMove","_handleMouseDown","_handleMouseUp","_positionFromMouseEvent","composedPath","_lastBufferCell","_handleHover","_askForLink","_linkAtPosition","link","useLineCache","forEach","reply","linkWithState","linkProvided","linkProviders","entries","existingReply","_checkLinkProviderResult","provideLinks","links","linksWithState","map","size","_removeIntersectingLinks","replies","occupiedCells","Set","providerReply","startX","range","endX","has","splice","hasLinkBefore","j","linkAtPosition","find","_handleNewLink","_mouseDownLink","activate","startRow","endRow","_linkLeave","decorations","underline","pointerCursor","isHovered","_linkHover","defineProperties","v","_fireUnderlineEvent","hover","showEvent","scrollOffset","_createLinkUnderlineEvent","leave","lower","upper","coords","getCoords","x1","y1","x2","y2","IBufferService","promptLabelInternal","tooMuchOutputInternal","CellData_1","_optionsService","_oscLinkService","_workCell","CellData","callback","linkHandler","lineLength","getTrimmedLength","currentLinkId","currentStart","finishLink","hasContent","loadCell","hasExtendedAttrs","extended","urlId","getLinkData","uri","_getRangeWithLineWrap","ignoreLink","allowNonHttpProtocols","parsed","URL","includes","protocol","defaultActivate","linkId","startY","finalStartX","endY","finalEndX","currentLine","isWrapped","previousLine","previousLineLength","_hasUrlId","previousStartX","nextLine","nextLineLength","nextEndX","confirm","newWindow","opener","location","href","IOptionsService","IOscLinkService","_renderCallback","_refreshCallbacks","_animationFrame","cancelAnimationFrame","addRefreshCallback","_innerRefresh","rowStart","rowEnd","rowCount","_rowCount","_rowStart","_rowEnd","max","_runRefreshCallbacks","_debounceThresholdMS","_lastRefreshMs","_additionalRefreshRequested","_refreshTimeoutID","clearTimeout","refreshRequestTime","performance","now","elapsed","waitPeriodBeforeTrailingRefresh","setTimeout","DEFAULT_ANSI_COLORS","freeze","r","g","toCss","toRgba","c","scrollableElement_1","scrollable_1","coreBrowserService","_coreService","themeService","_onRequestScrollLines","_isSyncing","_isHandlingScroll","_suppressOnScrollHandler","_needsSyncOnRender","scrollable","Scrollable","forceIntegerValues","smoothScrollDuration","scheduleAtNextAnimationFrame","cb","setSmoothScrollDuration","_scrollableElement","SmoothScrollableElement","vertical","horizontal","useShadows","mouseWheelSmoothScroll","verticalHasArrows","showArrows","_getChangeOptions","onMultipleOptionChange","updateOptions","onProtocolChange","handleMouseWheel","setScrollDimensions","scrollHeight","runAndSubscribe","backgroundColor","getDomNode","_styleElement","scrollbarSliderBackground","scrollbarSliderHoverBackground","scrollbarSliderActiveBackground","join","onBufferActivate","_latestYDisp","_sync","_handleScroll","getScrollPosition","setScrollPosition","reuseAnimation","scrollTop","verticalScrollbarSize","mouseWheelScrollSensitivity","scrollSensitivity","fastScrollSensitivity","_queuedAnimationFrame","synchronizedOutput","newRow","round","diff","translationY","ICoreService","IMouseStateService","_screenElement","_decorationElements","_altBufferIsActive","_dimensionsChanged","_container","_doRefreshDecorations","_queueRefresh","alt","onDecorationRegistered","onDecorationRemoved","decoration","_removeDecoration","_renderDecoration","_refreshStyle","_refreshXPosition","_createElement","layer","marker","display","onRenderEmitter","onDispose","delete","anchor","right","_zones","_zonePool","_zonePoolIndex","_linePadding","full","center","zones","addDecoration","overviewRulerOptions","z","_lineIntersectsZone","_lineAdjacentToZone","_addLineToZone","startBufferLine","endBufferLine","setPadding","padding","zone","ColorZoneStore_1","drawHeight","drawWidth","drawX","_width","_colorZoneStore","ColorZoneStore","_shouldUpdateDimensions","_shouldUpdateAnchor","_lastKnownBufferLength","_canvas","_refreshCanvasDimensions","parentElement","insertBefore","ctx","getContext","_ctx","normal","_refreshDrawHeightConstants","_refreshColorZonePadding","_refreshDrawConstants","outerWidth","floor","innerWidth","ceil","dpr","pixelsPerLine","nonFullHeight","_store","isDisposed","cssCanvasHeight","deviceCanvasHeight","_refreshDecorations","clearRect","lineWidth","_renderRulerOutline","_renderColorZone","fillStyle","overviewRulerBorder","fillRect","overviewRuler","showTopBorder","showBottomBorder","updateCanvasDimensions","updateAnchor","_isComposing","_textarea","_isSendingComposition","_compositionPosition","_compositionSuffix","_dataAlreadySent","substring","_finalizeComposition","_handleAnyTextareaChanges","waitForPropagation","currentCompositionPosition","currentCompositionSuffix","input","valueEnd","endsWith","_textareaChangeTimer","oldValue","newValue","dontRecurse","fontFamily","maxWidth","overflow","direction","compositionViewBounds","getCoordsRelativeToElement","rect","elementStyle","getComputedStyle","leftPadding","getPropertyValue","topPadding","colCount","hasValidCharSize","cssCellWidth","cssCellHeight","isSelection","moveToRequestedRow","targetY","bufferService","applicationCursor","wrappedRowsForRow","rowsToMove","abs","wrappedRows","verticalDirection","wrappedRowsCount","repeat","sequence","currentRow","lineWraps","startCol","endCol","currentCol","bufferStr","translateBufferLineToString","count","str","rpt","targetX","hasScrollback","resetStartingRow","horizontalDirection","moveToRequestedCol","rowDifference","currX","colsFromRowEnd","CoreBrowserTerminal_1","AddonManager_1","BufferNamespaceApi_1","ParserApi_1","UnicodeApi_1","CONSTRUCTOR_ONLY_OPTIONS","$value","Terminal","_core","_addonManager","AddonManager","_publicOptions","getter","propName","setter","_checkReadonlyOptions","desc","defineProperty","_checkProposedApi","allowProposedApi","onBinary","onData","onWriteParsed","parser","_parser","ParserApi","unicode","UnicodeApi","_buffer","BufferNamespaceApi","modes","m","mouseTrackingMode","activeProtocol","applicationCursorKeysMode","applicationCursorKeys","applicationKeypadMode","applicationKeypad","insertMode","originMode","origin","reverseWraparoundMode","reverseWraparound","sendFocusMode","showCursor","isCursorHidden","synchronizedOutputMode","win32InputMode","wraparoundMode","wraparound","wasUserInput","_verifyIntegers","_verifyPositiveIntegers","write","writeln","loadAddon","addon","strings","values","Infinity","DomRendererRowFactory_1","WidthCache_1","Constants_1","RendererUtils_1","SelectionRenderModel_1","TextBlinkStateManager_1","nextTerminalId","_linkifier2","_terminalClass","_selectionRenderModel","createSelectionRenderModel","_lastSelectionColumnMode","_rowHasBlinkingCells","_rowHasBlinkingCellsCount","_onRequestRedraw","_refreshRowElements","_selectionContainer","createRenderDimensions","_updateDimensions","onOptionChange","_handleOptionsChanged","_injectCss","_rowFactory","DomRendererRowFactory","_handleLinkHover","_handleLinkLeave","_cursorBlinkStateManager","CursorBlinkStateManager","restartBlinkAnimation","_textBlinkStateManager","TextBlinkStateManager","_widthCache","_themeStyleElement","_dimensionsStyleElement","WidthCache","setFont","fontWeight","fontWeightBold","_setDefaultSpacing","letterSpacing","styles","_terminalSelector","multiplyOpacity","blinkAnimationUnderlineId","blinkAnimationBarId","blinkAnimationBlockId","cursor","cursorAccent","cursorWidth","selectionBackgroundOpaque","selectionInactiveBackgroundOpaque","INVERTED_DEFAULT_COLOR","opaque","spacing","defaultSpacing","handleDevicePixelRatioChange","handleCharSizeChanged","pause","renderRows","resume","handleViewportVisibilityChange","isVisible","setViewportVisible","replaceChildren","oldViewportStart","oldViewportEnd","_lastSelectionStart","_lastSelectionEnd","update","viewportCappedStartRow","viewportCappedEndRow","newViewportStart","newViewportEnd","viewportStartRow","viewportEndRow","documentFragment","isXFlipped","_createSelectionElement","middleRowsCount","finalEndCol","renderStartRow","renderEndRow","cursorViewportRow","colStart","colEnd","fill","setNeedsBlinkInViewport","cursorAbsoluteY","cursorBlink","cursorStyle","cursorInactiveStyle","rowInfo","hasBlinkingCells","createRow","isBlinkOn","_setRowBlinkState","_updateTextBlinkState","_setCellUnderline","enabled","maxY","bufferline","_isIdlePaused","isFocused","_resetIdleTimer","_clearIdleTimer","_idleTimeout","_stopBlinkingDueToIdle","Constants_2","AttributeData_1","_columnSelectMode","_selectionStart","_selectionEnd","isCursorRow","blinkOn","widthCache","linkStart","linkEnd","elements","joinedRanges","getJoinedCharacters","charElement","getNoBgTrimmedLength","cellAmount","oldBg","oldFg","oldExt","oldLinkHover","oldSpacing","oldIsInSelection","skipJoinedCheckUntilX","classes","hasHover","isJoined","isValidJoinRange","lastCharX","firstSelectionState","_isCellInSelection","JoinedCellData","isInSelection","isCursorCell","isLinkHover","isBlink","isDecorated","forEachDecorationAtCell","d","chars","getChars","WHITESPACE_CELL_CHAR","isUnderline","isOverline","isBold","isItalic","selectionForeground","ext","isInvisible","isDim","underlineStyle","isUnderlineColorDefault","isUnderlineColorRGB","textDecorationColor","AttributeData","getUnderlineColor","drawBoldTextInBrightColors","isStrikethrough","textDecoration","getFgColor","fgColorMode","getFgColorMode","getBgColor","bgColorMode","getBgColorMode","isInverse","temp","temp2","bgOverride","fgOverride","resolvedBg","isTop","backgroundColorRGB","foregroundColorRGB","_addStyle","padStart","_applyMinimumContrast","className","minimumContrastRatio","treatGlyphAsBackgroundColor","getCode","cache","_getContrastCache","adjustedColor","ratio","ensureContrastRatio","halfContrastCache","contrastCache","canvasFactory","WidthCacheFontVariantCanvas","_flat","Float32Array","_font","_fontSize","_weight","_weightBold","_canvasElements","_holey","font","weight","weightBold","bold","italic","cp","_measure","variant","OffscreenCanvas","throwIfFalsy","fontStyle","trim","measureText","isPowerlineGlyph","codepoint","isEmoji","glyphSizeX","deviceCellWidth","isNerdFontGlyph","isBoxOrBlockGlyph","currentOffset","SelectionRenderModel","terminal","viewportY","isCellSelected","_intervalDuration","_blinkOn","_needsBlinkInViewport","_isViewportVisible","duration","setIntervalDuration","blinkIntervalDuration","_clearInterval","isEnabled","needsBlinkInViewport","_updateIntervalState","_interval","wasBlinkOn","setInterval","clearInterval","dom","fastDomNode_1","globalPointerMoveMonitor_1","scrollbarArrow_1","scrollbarVisibilityController_1","widget_1","platform","AbstractScrollbar","Widget","opts","_lazyRender","lazyRender","_host","host","_scrollable","_scrollByPage","scrollByPage","_scrollbarState","scrollbarState","_visibilityController","ScrollbarVisibilityController","visibility","extraScrollbarClassName","setIsNeeded","isNeeded","_pointerMoveMonitor","GlobalPointerMoveMonitor","_shouldRender","FastDomNode","setDomNode","setPosition","_domNodePointerDown","_createArrow","arrow","ScrollbarArrow","bgDomNode","_createSlider","slider","setClassName","setTop","setLeft","setWidth","setHeight","setLayerHinting","setContain","_sliderPointerDown","_onclick","leftButton","_handleElementSize","visibleSize","setVisibleSize","render","_handleElementScrollSize","elementScrollSize","setScrollSize","_handleElementScrollPosition","elementScrollPosition","beginReveal","setShouldBeVisible","beginHide","_renderDomNode","getRectangleLargeSize","getRectangleSmallSize","_updateSlider","getSliderSize","getArrowSize","getSliderPosition","_handlePointerDown","delegatePointerDown","domTop","getClientRects","sliderStart","sliderStop","pointerPos","_sliderPointerPosition","offsetX","offsetY","domNodePosition","getDomNodePagePosition","pageX","pageY","_pointerDownRelativePosition","_setDesiredScrollPositionNow","getDesiredScrollPositionFromOffsetPaged","getDesiredScrollPositionFromOffset","Element","initialPointerPosition","initialPointerOrthogonalPosition","_sliderOrthogonalPointerPosition","initialScrollbarState","clone","toggleClassName","startMonitoring","pointerId","buttons","pointerMoveData","pointerOrthogonalPosition","pointerOrthogonalDelta","pointerDelta","getDesiredScrollPositionFromDelta","handleDragEnd","handleDragStart","_desiredScrollPosition","desiredScrollPosition","writeScrollPosition","setScrollPositionNow","updateScrollbarSize","scrollbarSize","_updateScrollbarSize","setScrollbarSize","numberAsPixels","_height","_top","_left","_bottom","_right","_className","_position","_layerHint","_contain","setBottom","bottom","setRight","shouldHaveIt","layerHint","contain","name","_hooks","DisposableStore","_pointerMoveCallback","_onStopCallback","stopMonitoring","invokeStopCallback","isMonitoring","onStopCallback","initialElement","initialButtons","pointerMoveCallback","eventSource","setPointerCapture","releasePointerCapture","abstractScrollbar_1","scrollbarState_1","HorizontalScrollbar","scrollDimensions","getScrollDimensions","scrollPosition","getCurrentScrollPosition","ScrollbarState","horizontalHasArrows","horizontalScrollbarSize","scrollWidth","scrollLeft","horizontalSliderSize","sliderSize","sliderPosition","largeSize","smallSize","handleScroll","setOppositeScrollbarSize","setVisibility","sameOriginWindowChainCache","getParentWindowIfSameOrigin","w","parentLocation","IframeUtils","_getSameOriginWindowChain","windowChainCache","WeakRef","iframeElement","frameElement","getPositionOfChildWindowRelativeToAncestorWindow","childWindow","ancestorWindow","windowChain","windowChainEl","windowInChain","deref","boundingRect","timestamp","Date","browserEvent","middleButton","rightButton","detail","shiftKey","posx","posy","body","documentElement","iframeOffsets","deltaX","deltaY","targetNode","srcElement","shouldFactorDPR","isChrome","chromeVersionMatch","navigator","userAgent","match","e1","e2","devicePixelRatio","wheelDeltaY","VERTICAL_AXIS","axis","deltaMode","DOM_DELTA_LINE","wheelDeltaX","isSafari","HORIZONTAL_AXIS","wheelDelta","ScrollState","_forceIntegerValues","_scrollStateBrand","rawScrollLeft","rawScrollTop","equals","other","withScrollDimensions","useRawScrollPositions","withScrollPosition","createScrollEvent","previous","inSmoothScrolling","widthChanged","scrollWidthChanged","scrollLeftChanged","heightChanged","scrollHeightChanged","scrollTopChanged","oldWidth","oldScrollWidth","oldScrollLeft","oldHeight","oldScrollHeight","oldScrollTop","_scrollableBrand","_smoothScrollDuration","_scheduleAtNextAnimationFrame","_state","_smoothScrolling","validateScrollPosition","newState","_setState","Boolean","acceptScrollDimensions","getFutureScrollPosition","to","setScrollPositionSmooth","validTarget","newSmoothScrolling","SmoothScrollingOperation","from","startTime","animationFrameDisposable","_performSmoothScrolling","hasPendingScrollAnimation","tick","isDone","oldState","SmoothScrollingUpdate","createEaseOutCubic","delta","completion","t","pow","_initAnimations","_scrollLeft","_initAnimation","_scrollTop","viewportSize","stop1","stop2","cut","_tick","newScrollLeft","newScrollTop","mouseEvent_1","horizontalScrollbar_1","verticalScrollbar_1","MouseWheelClassifierItem","score","MouseWheelClassifier","_capacity","_memory","_front","_rear","isPhysicalMouseWheel","remainingInfluence","iteration","influence","acceptStandardWheelEvent","pageZoomFactor","getZoomFactor","accept","previousItem","_computeScore","_isAlmostInt","absDeltaX","absDeltaY","absPreviousDeltaX","absPreviousDeltaY","minDeltaX","minDeltaY","maxDeltaX","maxDeltaY","INSTANCE","resolvedScrollable","ownsScrollable","flipAxes","consumeMouseWheelIfScrollbarIsNeeded","alwaysConsumeMouseWheel","scrollYToX","scrollPredominantAxis","listenOnDomNode","verticalSliderSize","resolveOptions","scrollbarHost","mouseWheelEvent","_handleMouseWheel","_handleDragStart","_handleDragEnd","_verticalScrollbar","VerticalScrollbar","_horizontalScrollbar","_domNode","_leftShadowDomNode","_topShadowDomNode","_topLeftShadowDomNode","_listenOnDomNode","_mouseWheelToDispose","_setListeningToMouseWheel","_onmouseover","_handleMouseOver","_onmouseleave","_handleMouseLeave","_hideTimeout","TimeoutTimer","_isDragging","_mouseIsOver","_revealOnScroll","updateClassName","newClassName","newOptions","_render","delegateScrollFromMouseWheelEvent","StandardWheelEvent","shouldListen","onMouseWheel","passive","defaultPrevented","classifier","didScroll","shiftConvert","futureScrollPosition","deltaScrollTop","desiredScrollTop","deltaScrollLeft","desiredScrollLeft","consumeMouseWheel","_reveal","renderNow","scrollState","enableTop","enableLeft","leftClassName","topClassName","topLeftClassName","_hide","_scheduleHide","_handleActivate","handleActivate","bgWidth","bgHeight","arrowSize","addStandardDisposableListener","_arrowPointerDown","_pointerdownRepeatTimer","_pointerdownScheduleRepeatTimer","oppositeScrollbarSize","scrollSize","_scrollbarSize","_oppositeScrollbarSize","_arrowSize","_visibleSize","_scrollSize","_scrollPosition","_computedAvailableSize","_computedIsNeeded","_computedSliderSize","_computedSliderRatio","_computedSliderPosition","_refreshComputedValues","iVisibleSize","iScrollSize","iScrollPosition","setArrowSize","iArrowSize","_computeValues","computedAvailableSize","computedRepresentableSize","computedIsNeeded","computedSliderSize","computedSliderRatio","computedSliderPosition","desiredSliderPosition","correctedOffset","visibleClassName","invisibleClassName","_visibility","_visibleClassName","_invisibleClassName","_isVisible","_isNeeded","_rawShouldBeVisible","_shouldBeVisible","_revealTimer","_updateShouldBeVisible","rawShouldBeVisible","_applyVisibilitySetting","shouldBeVisible","ensureVisibility","setIfNotSet","withFadeAway","DomUtils","mainWindow","tail","array","n","LinkedListNode","Undefined","prev","LinkedList","_first","_last","_insert","atTheEnd","newNode","oldLast","oldFirst","didRemove","_remove","Symbol","iterator","EventType","TAP","START","END","CONTEXT_MENU","Gesture","_dispatched","_targets","_ignoreTargets","_activeTouches","_handle","_lastSetTapCountTime","_handleTouchStart","_handleTouchEnd","_handleTouchMove","addTarget","isTouchDevice","None","_instance","ignoreTarget","maxTouchPoints","len","targetTouches","touch","identifier","id","initialTarget","initialTimeStamp","initialPageX","initialPageY","rollingTimestamps","rollingPageX","rollingPageY","evt","_newGestureEvent","_dispatchEvent","activeTouchCount","keys","changedTouches","hasOwnProperty","holdTime","_holdDelay","finalX","finalY","deltaT","dispatchTo","filter","_inertia","createEvent","initEvent","tapCount","currentTime","getTime","setTapCount","_clearTapCountTime","targets","depth","dispatchEvent","t1","vX","dirX","vY","dirY","deltaPosX","deltaPosY","stopped","_scrollFriction","translationX","_target","descriptor","fnKey","fn","memoizeKey","args","configurable","enumerable","writable","apply","hasArrows","_arrowScrollDelta","_setArrows","_arrowScroll","currentPosition","_arrowUp","_arrowDown","arrowDelta","_updateArrowSize","listener","StandardMouseEvent","isSelectAllActive","selectionStartLength","finalSelectionStart","areSelectionValuesReversed","finalSelectionEnd","startPlusLength","handleTrim","_onCharSizeChange","onCharSizeChange","_measureStrategy","TextMetricsMeasureStrategy","DomMeasureStrategy","BaseMeasureStategy","_result","_validateAndSet","_parentElement","_measureElement","whiteSpace","fontKerning","Number","offsetWidth","offsetHeight","metrics","fontBoundingBoxAscent","fontBoundingBoxDescent","firstCell","content","combinedData","isCombined","setFromCharData","getAsCharData","_characterJoiners","_nextCharacterJoinerId","joiner","ranges","lineStr","trimmedLength","rangeStartColumn","currentStringIndex","rangeStartStringIndex","rangeAttrFG","getFg","rangeAttrBG","getBg","_getJoinedRanges","startIndex","endIndex","allJoinedRanges","joinerRanges","_mergeRanges","_stringRangesToCellRanges","currentRangeIndex","currentRangeStarted","currentRange","getString","newRange","inRange","_window","_isFocused","_cachedIsFocused","_onDprChange","_onWindowChange","onWindowChange","_screenDprMonitor","ScreenDprMonitor","setWindow","hasFocus","queueMicrotask","_parentWindow","_windowResizeListener","_outerListener","_setDprAndFireIfDiffers","_currentDevicePixelRatio","_updateDpr","_setWindowResizeListener","clearListener","parentWindow","_resolutionMediaMatchList","removeListener","matchMedia","addListener","Keyboard_1","KittyKeyboard_1","Win32InputMode_1","Platform_1","_getWin32InputMode","_win32InputMode","Win32InputMode","_getKittyKeyboard","_kittyKeyboard","KittyKeyboard","evaluateKeyboardEvent","kittyFlags","kittyKeyboard","flags","evaluate","vtExtensions","shouldUseProtocol","providerIndex","indexOf","Mouse_1","getMouseReportCoords","col","touch_1","_mouseStateService","_lastEvent","_wheelPartialScroll","_touchScrollAccumulator","requestedEvents","mouseup","wheel","mousedrag","mousemove","eventListeners","_handleWheel","_handleMouseDrag","_altMouseCursor","AltMouseCursorController","events","_handleProtocolChange","_syncMouseModeState","_handlePassiveWheel","_handleTouchChange","_sendEvent","but","action","overrideType","allowCustomWheelEvent","_consumeWheelEvent","stripAltFromReport","_triggerMouseEvent","ctrl","shouldForceSelection","_handleTouchScrollAsWheel","_handleTouchScrollAsKeys","trunc","resetClass","logLevel","_explainEvents","_applyScrollModifier","targetWheelEventPixels","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_PAGE","_equalEvents","isPixelEncoding","restrictMouseEvent","report","encodeMouseEvent","isDefaultEncoding","triggerBinaryEvent","down","up","drag","move","pixels","ILogService","_isActive","_listeners","store","syncFromModifier","_updateClass","altHeld","RenderDebouncer_1","TaskQueue_1","_renderer","decorationService","_observerDisposable","_isPaused","_needsFullRefresh","_isNextRenderRedrawOnly","_needsSelectionRefresh","_canvasWidth","_canvasHeight","_selectionState","_onRenderedViewportChange","_onRefreshRequest","onRefreshRequest","_pausedResizeTask","DebouncedIdleTask","_renderDebouncer","RenderDebouncer","_syncOutputHandler","SynchronizedOutputHandler","_fullRefresh","_registerIntersectionObserver","observer","IntersectionObserver","_handleIntersectionChange","threshold","_intersectionObserver","disconnect","observe","entry","isIntersecting","intersectionRatio","flush","isRedrawOnly","bufferRows","buffered","_fireOnCanvasResize","renderer","_onTimeout","_start","_end","_isBuffering","_timeout","MoveToCell_1","SelectionModel_1","BufferRange_1","NON_BREAKING_SPACE_CHAR","ALL_NON_BREAKING_SPACE_REGEX","RegExp","_dragScrollAmount","_enabled","_trimListener","_mouseDownTimeStamp","_oldHasSelection","_oldSelectionStart","_oldSelectionEnd","_onLinuxMouseSelection","_onRedrawRequest","_mouseMoveListener","_mouseUpListener","onUserInput","onTrim","_handleTrim","_handleBufferActivate","_model","SelectionModel","_activeSelectionMode","_removeMouseDownListeners","rowsChanged","lineText","startRowEndCol","isLinuxMouseSelection","_refreshAnimationFrame","_refresh","_isClickInSelection","_getMouseBufferCoords","_areCoordsInSelection","isCellInSelection","_selectWordAtCursor","allowWhitespaceOnlySelection","getRangeLength","_selectWordAt","_getMouseEventScrollAmount","terminalHeight","macOptionClickForcesSelection","timeStamp","_handleIncrementalClick","_handleSingleClick","_handleDoubleClick","_handleTripleClick","_addMouseDownListeners","_dragScrollIntervalTimer","_dragScroll","hadSelection","_fireOnSelectionChange","hasWidth","_selectLineAt","previousSelectionEnd","_selectToWordAt","timeElapsed","altClickMovesCursor","coordinates","moveToCellSequence","_fireEventIfSelectionChanged","activeBuffer","_convertViewportColToCharacterIndex","charIndex","_getWordAt","followWrappedLinesAbove","followWrappedLinesBelow","charOffset","leftWideCharCount","rightWideCharCount","leftLongCharOffset","rightLongCharOffset","charAt","_isCharWordSeparator","getCodePoint","previousBufferLine","previousLineWordPosition","nextBufferLine","nextLineWordPosition","wordPosition","wordSeparator","wrappedRange","getWrappedRangeForLine","first","last","ServiceRegistry_1","createDecorator","ColorContrastCache_1","Types_1","DEFAULT_FOREGROUND","DEFAULT_BACKGROUND","DEFAULT_CURSOR","DEFAULT_CURSOR_ACCENT","DEFAULT_SELECTION","DEFAULT_OVERVIEW_RULER_BORDER","_colors","_contrastCache","ColorContrastCache","_halfContrastCache","_onChangeColors","selectionBackgroundTransparent","blend","selectionInactiveBackgroundTransparent","opacity","_updateRestoreColors","_setTheme","theme","parseColor","selectionBackground","selectionInactiveBackground","NULL_COLOR","isOpaque","black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite","extendedAnsi","colorCount","slot","_restoreColor","_restoreColors","cssString","fallback","millis","Promise","resolve","timeout","timer","_token","_isDisposed","_isScheduled","_disposable","context","handle","CircularList","_maxLength","onDeleteEmitter","onDelete","onInsertEmitter","onInsert","onTrimEmitter","_array","Array","_startIndex","_length","maxLength","newMaxLength","newArray","_getCyclicIndex","newLength","recycle","isFull","deleteCount","items","countToTrim","trimStart","shiftElements","expandListBy","$r","$g","$b","$a","toPaddedHex","s","contrastRatio","l1","l2","color_1","toChannels","fgR","fgG","fgB","bgR","bgG","bgB","rgbaColor","factor","css_1","$ctx","$litmusColor","willReadFrequently","globalCompositeOperation","createLinearGradient","rgbaMatch","parseFloat","getImageData","rgb_1","relativeLuminance2","rs","gs","bs","reduceLuminance","bgRgba","fgRgba","cr","increaseLuminance","bgL","fgL","resultA","resultARatio","resultB","InstantiationService_1","LogService_1","BufferService_1","OptionsService_1","CoreService_1","MouseStateService_1","UnicodeV6_1","UnicodeService_1","CharsetService_1","WindowsMode_1","WriteBuffer_1","OscLinkService_1","hasWriteSyncWarnHappened","_onScrollApi","_windowsWrappingHeuristics","_onBinary","_onData","_onLineFeed","_onResize","_onWriteParsed","InstantiationService","OptionsService","LogService","BufferService","CoreService","MouseStateService","unicodeService","UnicodeService","UnicodeV6","IUnicodeService","_charsetService","CharsetService","ICharsetService","OscLinkService","InputHandler","onRequestScrollToBottom","_writeBuffer","handleUserInput","_handleWindowsPtyOptionChange","markRangeDirty","scrollBottom","WriteBuffer","promiseResult","parse","writeSync","maxSubsequentCalls","LogLevelEnum","WARN","flushSync","scroll","eraseAttr","registerEscHandler","registerDcsHandler","registerCsiHandler","registerOscHandler","registerApcHandler","windowsPty","backend","buildNumber","_enableWindowsWrappingHeuristics","disposables","updateWindowsModeWrappedState","final","_disposed","_event","thisArgs","idx","isArray","call","listeners","initial","Charsets_1","EscapeSequenceParser_1","TextDecoder_1","OscParser_1","DcsParser_1","ApcParser_1","Version_1","GLEVEL","paramToWindowOption","setWinLines","restoreWin","minimizeWin","setWinPosition","setWinSizePixels","raiseWin","lowerWin","refreshWin","setWinSizeChars","maximizeWin","fullscreenWin","getWinState","getWinPosition","getWinSizePixels","getScreenSizePixels","getCellSizePixels","getWinSizeChars","getScreenSizeChars","getIconTitle","getWinTitle","pushTitle","popTitle","$temp","getAttrData","_curAttrData","_unicodeService","EscapeSequenceParser","_parseBuffer","Uint32Array","_stringDecoder","StringToUtf32","_utf8Decoder","Utf8ToUtf32","_windowTitle","_iconName","_windowTitleStack","_iconNameStack","_eraseAttrDataInternal","_onRequestBell","_onRequestRefreshRows","_onRequestReset","_onRequestSendFocus","_onRequestSyncScrollBar","onRequestSyncScrollBar","_onRequestWindowsOptionsReport","_onA11yChar","_onA11yTab","_onColor","_onRequestColorSchemeQuery","_parseStack","paused","cursorStartX","cursorStartY","decodedLength","_specialColors","_dirtyRowTracker","DirtyRowTracker","_activeBuffer","setCsiHandlerFallback","params","identToString","toArray","setEscHandlerFallback","setExecuteHandlerFallback","code","setOscHandlerFallback","setDcsHandlerFallback","payload","setApcHandlerFallback","setPrintHandler","print","insertChars","intermediates","cursorUp","scrollRight","cursorDown","cursorForward","cursorBackward","cursorNextLine","cursorPrecedingLine","cursorCharAbsolute","cursorPosition","cursorForwardTab","eraseInDisplay","prefix","eraseInLine","insertLines","deleteLines","deleteChars","scrollUp","scrollDown","eraseChars","cursorBackwardTab","charPosAbsolute","hPositionRelative","repeatPrecedingCharacter","sendDeviceAttributesPrimary","sendDeviceAttributesSecondary","linePosAbsolute","vPositionRelative","hVPosition","tabClear","setMode","setModePrivate","resetMode","resetModePrivate","charAttributes","deviceStatus","deviceStatusPrivate","softReset","sendXtVersion","setCursorStyle","setScrollRegion","saveCursor","windowOptions","restoreCursor","insertColumns","deleteColumns","selectProtected","requestMode","kittyKeyboardSet","kittyKeyboardQuery","kittyKeyboardPush","kittyKeyboardPop","setExecuteHandler","bell","lineFeed","carriageReturn","backspace","tab","shiftOut","shiftIn","tabSet","OscHandler","setTitle","setIconName","setOrReportIndexedColor","setHyperlink","setOrReportFgColor","setOrReportBgColor","setOrReportCursorColor","restoreIndexedColor","restoreFgColor","restoreBgColor","restoreCursorColor","reverseIndex","keypadApplicationMode","keypadNumericMode","fullReset","setgLevel","selectDefaultCharset","flag","CHARSETS","selectCharset","screenAlignmentPattern","setErrorHandler","DcsHandler","requestStatusString","_preserveStack","_logSlowResolvingAsync","p","slowTimeout","slowPromise","_res","rej","race","then","err","_getCurrentLinkId","wasPaused","DEBUG","prototype","TRACE","trace","split","clearRange","decode","subarray","viewportEnd","viewportStart","chWidth","charset","curAttr","bufferRow","markDirty","setCellFromCodepoint","precedingJoinState","ch","currentInfo","charProperties","extractWidth","shouldJoin","extractShouldJoin","stringFromCodePoint","addLineToLink","oldRow","oldCol","_eraseAttrData","BufferLine","copyCellsFrom","addCodepointToCell","insertCells","getNullCell","NULL_CELL_CODE","NULL_CELL_WIDTH","ApcHandler","convertEol","_restrictCursor","originalX","nextStop","maxCol","_setCursor","_moveCursor","diffToTop","diffToBottom","param","tabs","prevStop","_eraseInBufferLine","clearWrap","respectProtect","replaceCells","_resetBufferLine","clearMarkers","scrollOnEraseInDisplay","scrollBackSize","scrollBottomRowsOffset","scrollBottomAbsolute","deleteCells","joinState","idata","itext","codePointAt","tlength","copyWithin","_is","XTERM_VERSION","term","termName","startsWith","setgCharset","DEFAULT_CHARSET","quirks","allowSetCursorBlink","activeEncoding","mainFlags","altFlags","activateAltBuffer","colorSchemeQuery","activateNormalBuffer","dm","mouseProtocol","mouseEncoding","cs","f","b2v","_updateAttrColor","mode","c1","c2","c3","fromColorRGB","_extractColor","attr","accu","cSpace","advance","hasSubParams","subparams","getSubParams","underlineColor","_processUnderline","updateExtended","_processSGR0","l","kittySgrBoldFaintControl","savedX","savedY","savedCurAttrData","savedCharset","isBlinking","second","savedCharsets","charsets","savedGlevel","glevel","savedOriginMode","savedWraparoundMode","slots","spec","exec","isValidColorIndex","_createHyperlink","_finishHyperlink","parsedParams","idParamIndex","findIndex","registerLink","_setOrReportSpecialColor","collectAndFlag","scrollRegionHeight","level","yOffset","markAllDirty","isProtected","block","bar","stack","altStack","mainStack","arg","_disposables","o","_value","_data","third","fourth","_targetWindow","majorVersion","isNode","process","isLegacyEdge","_getKey","logService","_insertedValues","_isFlushingInserted","_deletedIndices","_isFlushingDeleted","_flushInsertedTask","IdleTaskQueue","_flushDeletedTask","insert","_flushCleanupDeleted","enqueue","_flushInserted","sortedAddedValues","sortedAddedValuesIndex","arrayIndex","newArrayIndex","_flushCleanupInserted","_search","_flushDeleted","sortedDeletedIndices","sortedDeletedIndicesIndex","getKeyIterator","forEachByKey","mid","midKey","StringBuilder","_chunks","append","chunk","_limit","_builder","limit","TaskQueue","_tasks","_i","task","_idleCallback","_cancelCallback","_requestCallback","_process","deadline","taskDuration","deadlineRemaining","longestTask","lastDeadlineRemaining","timeRemaining","PriorityTaskQueue","_createDeadline","requestIdleCallback","cancelIdleCallback","_queue","lastChar","CHAR_DATA_CODE_INDEX","WHITESPACE_CELL_CODE","ExtendedAttrs","newObj","isFgRGB","isBgRGB","isFgPalette","isBgPalette","isFgDefault","isBgDefault","isAttributeDefault","isEmpty","getUnderlineColorMode","isUnderlineColorPalette","getUnderlineStyle","getUnderlineVariantOffset","underlineVariantOffset","_urlId","_ext","val","CircularList_1","BufferLineStringCache_1","BufferReflow_1","Marker_1","MAX_BUFFER_SIZE","Buffer","_hasScrollback","_nullCell","fromCharData","NULL_CELL_CHAR","_whitespaceCell","WHITESPACE_CELL_WIDTH","_isClearing","_memoryCleanupPosition","_cols","_rows","_getCorrectBufferLength","setupTabStops","_memoryCleanupQueue","_stringCache","BufferLineStringCache","getWhitespaceCell","relativeY","correctBufferLength","scrollback","fillViewportRows","fillAttr","newCols","newRows","nullCell","dirtyMemoryLines","addToY","amountToTrim","_isReflowEnabled","_reflow","_batchedMemoryCleanup","normalRun","counted","cleanupMemory","_reflowLarger","_reflowSmaller","reflowCursorLine","toRemove","reflowLargerGetLinesToRemove","newLayoutResult","reflowLargerCreateNewLayout","reflowLargerApplyNewLayout","layout","_reflowLargerAdjustViewport","countRemoved","viewportAdjustments","toInsert","countToInsert","wrappedLines","absoluteY","lastLineLength","destLineLengths","reflowSmallerGetNewLineLengths","linesToAdd","trimmedLines","newLines","newLine","destLineIndex","destCol","srcLineIndex","srcCol","cellsToCopy","wrappedLinesIndex","getWrappedLineTrimmedLength","setCell","insertEvents","originalLines","originalLinesLength","originalLineIndex","nextToInsertIndex","nextToInsert","countInsertedSoFar","nextI","insertCountEmitted","lineIndex","trimRight","tabStopWidth","Marker","_removeMarker","StringBuilder_1","$startIndex","$workCell","$translateToStringBuilder","fillCellData","_combined","_extendedAttrs","_invalidateStringCache","CHAR_DATA_ATTR_INDEX","CHAR_DATA_CHAR_INDEX","CHAR_DATA_WIDTH_INDEX","codePoint","attrs","byteLength","uint32Cells","extKeys","copyFrom","_copySparseMapsFrom","src","applyInReverse","srcData","_copyCellMapsFrom","outColumns","isCanonicalRequest","stringCacheEntry","_getStringCacheEntry","isTrimmed","trimEnd","cacheEntry","createIfNeeded","cachedEntry","_stringCacheEntryRef","generation","allocateEntry","srcStart","_clearTimeout","_lastAccessTimestamp","_scheduleClear","_scheduleClearTimeout","timeoutMs","disposableTimeout","bufferCols","endsInNull","followingLineStartsWithWide","oldCols","bufferAbsoluteY","srcTrimmedTineLength","srcRemainingCells","destRemainingCells","countToRemove","nextToRemoveIndex","nextToRemoveStart","countRemovedSoFar","newLayout","newLayoutLines","newLineLengths","cellsNeeded","srcLine","cellsAvailable","oldTrimmedLength","endsWithWide","Buffer_1","BufferSet","_normalBuffer","_altBuffer","_onBufferActivate","_normal","_alt","inactiveBuffer","obj","combined","attributesEquals","thisDefault","otherDefault","DEFAULT_COLOR","DEFAULT_ATTR","DEFAULT_EXT","_id","_nextId","_onDispose","h","k","q","u","A","B","C","R","Q","K","Y","E","Z","H","_","applicationCursorMode","modifiers","keyMapping","KEYCODE_KEY_MAPPINGS","keyString","toUpperCase","toLowerCase","_functionalKeyCodes","Escape","Enter","Tab","Backspace","CapsLock","ScrollLock","NumLock","PrintScreen","Pause","ContextMenu","F13","F14","F15","F16","F17","F18","F19","F20","F21","F22","F23","F24","F25","KP_0","KP_1","KP_2","KP_3","KP_4","KP_5","KP_6","KP_7","KP_8","KP_9","KP_Decimal","KP_Divide","KP_Multiply","KP_Subtract","KP_Add","KP_Enter","KP_Equal","ShiftLeft","ShiftRight","ControlLeft","ControlRight","AltLeft","AltRight","MetaLeft","MetaRight","MediaPlayPause","MediaStop","MediaTrackNext","MediaTrackPrevious","AudioVolumeDown","AudioVolumeUp","AudioVolumeMute","_csiTildeKeys","Insert","Delete","PageUp","PageDown","F5","F6","F7","F8","F9","F10","F11","F12","_csiLetterKeys","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Home","End","_ss3FunctionKeys","F1","F2","F3","F4","_getNumpadKeyCode","suffix","_getModifierKeyCode","_encodeModifiers","mods","_getKeyCode","macOptionAsAlt","numpadCode","modifierCode","funcCode","digit","_isModifierKey","_isLockKey","_buildCsiLetterSequence","letter","reportEventTypes","needsEventType","seq","_buildSs3Sequence","_buildCsiTildeSequence","number","_buildCsiUSequence","isFunc","isMod","shiftedKey","textCode","csiLetter","ss3Letter","tildeCode","specialKey","legacyByte","_interim","startPos","interim","Uint8Array","byte1","byte2","byte3","byte4","discardInterim","tmp","missing","fourStop","BMP_COMBINING","HIGH_COMBINING","table","version","wcwidth","num","ucs","bisearch","preceding","createPropertyValue","_codeToVk","KeyA","KeyB","KeyC","KeyD","KeyE","KeyF","KeyG","KeyH","KeyI","KeyJ","KeyK","KeyL","KeyM","KeyN","KeyO","KeyP","KeyQ","KeyR","KeyS","KeyT","KeyU","KeyV","KeyW","KeyX","KeyY","KeyZ","Digit0","Digit1","Digit2","Digit3","Digit4","Digit5","Digit6","Digit7","Digit8","Digit9","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","NumpadMultiply","NumpadAdd","NumpadSeparator","NumpadSubtract","NumpadDecimal","NumpadDivide","NumpadEnter","Space","Semicolon","Equal","Comma","Minus","Period","Slash","Backquote","BracketLeft","Backslash","BracketRight","Quote","IntlBackslash","_codeToScancode","_enhancedKeyCodes","_keyToControlChar","_getVirtualKeyCode","vk","_getScanCode","_getUnicodeChar","controlChar","_getControlKeyState","isKeyDown","_action","_callbacks","_pendingData","_bufferOffset","_isSyncWriting","_syncCalls","_didUserInput","_innerWriteTimer","didProcess","_innerWrite","_scheduleInnerWrite","lastTime","continuation","catch","low","RGB_REX","base","HASH_REX","adv","bits","pad","s2","EMPTY_HANDLERS","_handlers","create","_active","_ident","_handlerFb","_stack","loopPosition","fallThrough","registerHandler","handlerList","handlerIndex","clearHandler","setHandlerFallback","put","utf32ToString","success","handlerResult","LimitedStringBuilder","_payloadLimit","_hitLimit","ret","res","Params_1","unhook","hook","EMPTY_PARAMS","Params","addParam","_params","TransitionTable","Uint16Array","setDefault","addMany","codes","NON_ASCII_PRINTABLE","VT500_TRANSITION_TABLE","blueprint","unused","PRINTABLES","EXECUTABLES","states","_transitions","handlers","handlerPos","transition","chunkPos","initialState","currentState","_collect","_printHandlerFb","_executeHandlerFb","_csiHandlerFb","_escHandlerFb","_errorHandlerFb","_printHandler","_executeHandlers","_executeHandlersArr","_csiHandlers","_escHandlers","_oscParser","OscParser","_dcsParser","DcsParser","_apcParser","ApcParser","_errorHandler","_identifier","finalRange","intermediate","finalCode","reverse","clearPrintHandler","clearEscHandler","clearExecuteHandler","clearCsiHandler","clearDcsHandler","clearOscHandler","clearApcHandler","clearErrorHandler","resetZdm","csiDone","addDigit","addSubParam","l4","collect","abort","handlersEsc","jj","_put","fromArray","maxSubParamsLength","Int32Array","_subParams","_subParamsLength","_subParamsIdx","_rejectDigits","_rejectSubDigits","_digitIsSub","newParams","getSubParamsAll","cur","_addons","instance","loadedAddon","_wrappedAddonDispose","BufferLineApiView_1","init","baseY","getLine","BufferLineApiView","_line","getCell","startColumn","endColumn","BufferApiView_1","_onBufferChange","onBufferChange","BufferApiView","_alternate","alternate","addCsiHandler","addDcsHandler","addEscHandler","addOscHandler","provider","versions","activeVersion","BufferSet_1","isUserScrolling","colsChanged","_cachedBlankLine","topRow","bottomRow","willBufferBeTrimmed","oldYdisp","_charsets","DEFAULT_MODES","DEFAULT_DEC_PRIVATE_MODES","_onUserInput","_onRequestScrollToBottom","showCursorImmediately","structuredClone","SortedList_1","$xmin","$xmax","_decorations","_lineCache","DecorationLineCache","_onDecorationRegistered","_onDecorationRemoved","SortedList","attachToBufferLines","Decoration","markerDispose","getDecorationsAtCell","bucket","getDecorationsOnLine","_decorationsByLine","_bufferLineListeners","_lineIndexSyncTimer","MicrotaskTimer","_lineIndexSyncCallbacks","_addToLineBuckets","_removeFromLineBuckets","_handleBufferLinesTrim","_handleBufferLinesInsert","_handleBufferLinesDelete","_getDecorationHeight","_indexedStartLine","_reindexDecoration","_scheduleLineIndexSync","callbacks","newMap","_mergeLineBucket","_applyBufferLinesInsert","_applyBufferLinesDelete","existing","spanCrossers","deleteEnd","toReindex","_cachedBg","_cachedFg","foregroundColor","ServiceCollection","_entries","service","_services","getService","ctor","serviceDependencies","getServiceDependencies","serviceArgs","dependency","firstServiceArgPos","optionsKeyToLogLevel","info","INFO","ERROR","off","OFF","_logLevel","_updateLogLevel","_evalLazyOptionalParams","optionalParams","_log","message","logger","log","DEFAULT_PROTOCOLS","NONE","restrict","X10","VT200","DRAG","ANY","eventCode","isSGR","S","DEFAULT_ENCODINGS","DEFAULT","SGR","SGR_PIXELS","_protocols","_encodings","_activeProtocol","_activeEncoding","_onProtocolChange","addProtocol","addEncoding","encoding","_customWheelEventHandler","DEFAULT_OPTIONS","rescaleOverlappingGlyphs","FONT_WEIGHT_OPTIONS","_onOptionChange","defaultOptions","_sanitizeAndValidateOption","_setupOptions","eventKey","isCursorStyle","_entriesWithId","_dataByLinkId","_removeMarkerFromLink","castData","_getEntryIdKey","every","linkData","serviceRegistry","decorator","arguments","storeServiceDependency","_providers","_onChange","onChange","extractCharKind","_activeProvider","getStringCellWidth","precedingInfo","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__"],"sourceRoot":""} \ No newline at end of file -+{"version":3,"file":"xterm.js","mappings":"CAAA,SAAAA,EAAAC,GACA,oBAAAC,SAAA,iBAAAC,OACAA,OAAAD,QAAAD,SACA,sBAAAG,QAAAA,OAAAC,IACAD,OAAA,GAAAH,OACA,CACA,IAAAK,EAAAL,IACA,QAAAM,KAAAD,GAAA,iBAAAJ,QAAAA,QAAAF,GAAAO,GAAAD,EAAAC,EACA,CACC,CATD,CASCC,WAAA,szCCJD,MAAYC,EAAOC,EAAAC,EAAA,OAEnBC,EAAAD,EAAA,MACAE,EAAAF,EAAA,MACAG,EAAAH,EAAA,MAEAI,EAAAJ,EAAA,MACAK,EAAAL,EAAA,MAeO,IAAMM,EAAN,cAAmCJ,EAAAK,WA4BxC,WAAAC,CACmBC,EACMC,EACeC,EACLC,GAEjCC,QALiBC,KAAAL,UAAAA,EAEqBK,KAAAH,oBAAAA,EACLG,KAAAF,eAAAA,EA1B3BE,KAAAC,YAA8C,IAAIC,QAGlDF,KAAAG,qBAA+B,EAe/BH,KAAAI,gBAA4B,GAE5BJ,KAAAK,iBAA2B,GASjC,MAAMC,EAAMN,KAAKH,oBAAoBU,aACrCP,KAAKQ,wBAA0BF,EAAIG,cAAc,OACjDT,KAAKQ,wBAAwBE,UAAUC,IAAI,uBAE3CX,KAAKY,cAAgBN,EAAIG,cAAc,OACvCT,KAAKY,cAAcC,aAAa,OAAQ,QACxCb,KAAKY,cAAcF,UAAUC,IAAI,4BACjCX,KAAKc,aAAe,GACpB,IAAK,IAAIhC,EAAI,EAAGA,EAAIkB,KAAKL,UAAUoB,KAAMjC,IACvCkB,KAAKc,aAAahC,GAAKkB,KAAKgB,+BAC5BhB,KAAKY,cAAcK,YAAYjB,KAAKc,aAAahC,IAgBnD,GAbAkB,KAAKkB,0BAA4BC,GAAKnB,KAAKoB,qBAAqBD,EAAC,GACjEnB,KAAKqB,6BAA+BF,GAAKnB,KAAKoB,qBAAqBD,EAAC,GACpEnB,KAAKc,aAAa,GAAGQ,iBAAiB,QAAStB,KAAKkB,2BACpDlB,KAAKc,aAAad,KAAKc,aAAaS,OAAS,GAAGD,iBAAiB,QAAStB,KAAKqB,8BAE/ErB,KAAKQ,wBAAwBS,YAAYjB,KAAKY,eAE9CZ,KAAKwB,YAAclB,EAAIG,cAAc,OACrCT,KAAKwB,YAAYd,UAAUC,IAAI,eAC/BX,KAAKwB,YAAYX,aAAa,YAAa,aAC3Cb,KAAKQ,wBAAwBS,YAAYjB,KAAKwB,aAC9CxB,KAAKyB,qBAAuBzB,KAAK0B,UAAU,IAAIvC,EAAAwC,mBAAmB3B,KAAK4B,YAAYC,KAAK7B,SAEnFA,KAAKL,UAAUmC,QAClB,MAAM,IAAIC,MAAM,oDAiBhB/B,KAAKL,UAAUmC,QAAQE,sBAAsB,aAAchC,KAAKQ,yBAGlER,KAAK0B,UAAU1B,KAAKL,UAAUsC,SAASd,GAAKnB,KAAKkC,cAAcf,EAAEJ,QACjEf,KAAK0B,UAAU1B,KAAKL,UAAUwC,SAAShB,GAAKnB,KAAKoC,aAAajB,EAAEkB,MAAOlB,EAAEmB,OACzEtC,KAAK0B,UAAU1B,KAAKL,UAAU4C,SAAS,IAAMvC,KAAKoC,iBAElDpC,KAAK0B,UAAU1B,KAAKL,UAAU6C,WAAWC,GAAQzC,KAAK0C,YAAYD,KAClEzC,KAAK0B,UAAU1B,KAAKL,UAAUgD,WAAW,IAAM3C,KAAK0C,YAAY,QAChE1C,KAAK0B,UAAU1B,KAAKL,UAAUiD,UAAUC,GAAc7C,KAAK8C,WAAWD,KACtE7C,KAAK0B,UAAU1B,KAAKL,UAAUoD,MAAM5B,GAAKnB,KAAKgD,WAAW7B,EAAE8B,OAC3DjD,KAAK0B,UAAU1B,KAAKL,UAAUuD,OAAO,IAAMlD,KAAKmD,qBAChDnD,KAAK0B,UAAU1B,KAAKF,eAAesD,mBAAmB,IAAMpD,KAAKqD,2BACjErD,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBhD,EAAK,kBAAmB,IAAMN,KAAKuD,2BACxEvD,KAAK0B,UAAU1B,KAAKH,oBAAoB2D,YAAY,IAAMxD,KAAKqD,2BAE/DrD,KAAKqD,yBACLrD,KAAKoC,eACLpC,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAIxBzD,KAAKQ,wBAAwBkD,SAE/B1D,KAAKc,aAAaS,OAAS,IAE/B,CAEQ,UAAAuB,CAAWD,GACjB,IAAK,IAAI/D,EAAI,EAAGA,EAAI+D,EAAY/D,IAC9BkB,KAAK0C,YAAY,IAErB,CAEQ,WAAAA,CAAYD,GACdzC,KAAKG,qBAAuB,KAC1BH,KAAKI,gBAAgBmB,OAAS,EAEZvB,KAAKI,gBAAgBuD,UACrBlB,IAClBzC,KAAKK,kBAAoBoC,GAG3BzC,KAAKK,kBAAoBoC,EAGd,OAATA,IACFzC,KAAKG,uBAC6B,KAA9BH,KAAKG,uBACPH,KAAKwB,YAAYoC,YAAc5E,EAAQ6E,cAAcC,QAI7D,CAEQ,gBAAAX,GACNnD,KAAKwB,YAAYoC,YAAc,GAC/B5D,KAAKG,qBAAuB,CAC9B,CAEQ,UAAA6C,CAAWe,GACjB/D,KAAKmD,mBAEA,eAAea,KAAKD,IACvB/D,KAAKI,gBAAgB6D,KAAKF,EAE9B,CAEQ,YAAA3B,CAAaC,EAAgBC,GACnCtC,KAAKyB,qBAAqByC,QAAQ7B,EAAOC,EAAKtC,KAAKL,UAAUoB,KAC/D,CAEQ,WAAAa,CAAYS,EAAeC,GACjC,MAAM6B,EAAkBnE,KAAKL,UAAUwE,OACjCC,EAAUD,EAAOE,MAAM9C,OAAO+C,WACpC,IAAK,IAAIxF,EAAIuD,EAAOvD,GAAKwD,EAAKxD,IAAK,CACjC,MAAMyF,EAAOJ,EAAOE,MAAMP,IAAIK,EAAOK,MAAQ1F,GACvC2F,EAAoB,GACpBC,EAAWH,GAAMI,mBAAkB,OAAMC,OAAWA,EAAWH,IAAY,GAC3EI,GAAYV,EAAOK,MAAQ1F,EAAI,GAAGwF,WAClCxC,EAAU9B,KAAKc,aAAahC,GAC9BgD,IACsB,IAApB4C,EAASnD,QACXO,EAAQ8B,YAAc,IACtB5D,KAAKC,YAAY6E,IAAIhD,EAAS,CAAC,EAAG,MAElCA,EAAQ8B,YAAcc,EACtB1E,KAAKC,YAAY6E,IAAIhD,EAAS2C,IAEhC3C,EAAQjB,aAAa,gBAAiBgE,GACtC/C,EAAQjB,aAAa,eAAgBuD,GACrCpE,KAAK+E,eAAejD,GAExB,CACA9B,KAAKgF,qBACP,CAEQ,mBAAAA,GAC+B,IAAjChF,KAAKK,iBAAiBkB,SAGtBvB,KAAKwB,YAAYoC,cAAgB5E,EAAQ6E,cAAcC,OACzD9D,KAAKmD,mBAEPnD,KAAKwB,YAAYoC,aAAe5D,KAAKK,iBACrCL,KAAKK,iBAAmB,GAC1B,CAEQ,oBAAAe,CAAqBD,EAAe8D,GAC1C,MAAMC,EAAkB/D,EAAEgE,OACpBC,EAAwBpF,KAAKc,aAAqB,IAARmE,EAAoC,EAAIjF,KAAKc,aAAaS,OAAS,GAKnH,GAFiB2D,EAAgBG,aAAa,oBACnB,IAARJ,EAAoC,IAAM,GAAGjF,KAAKL,UAAUwE,OAAOE,MAAM9C,UAE1F,OAKF,GAAIJ,EAAEmE,gBAAkBF,EACtB,OAIF,IAAIG,EACAC,EAgBJ,GAfY,IAARP,GACFM,EAAqBL,EACrBM,EAAwBxF,KAAKc,aAAa2E,MAC1CzF,KAAKY,cAAc8E,YAAYF,KAE/BD,EAAqBvF,KAAKc,aAAa6C,QACvC6B,EAAwBN,EACxBlF,KAAKY,cAAc8E,YAAYH,IAIjCA,EAAmBI,oBAAoB,QAAS3F,KAAKkB,2BACrDsE,EAAsBG,oBAAoB,QAAS3F,KAAKqB,8BAG5C,IAAR4D,EAAmC,CACrC,MAAMW,EAAa5F,KAAKgB,+BACxBhB,KAAKc,aAAa+E,QAAQD,GAC1B5F,KAAKY,cAAcoB,sBAAsB,aAAc4D,EACzD,KAAO,CACL,MAAMA,EAAa5F,KAAKgB,+BACxBhB,KAAKc,aAAamD,KAAK2B,GACvB5F,KAAKY,cAAcK,YAAY2E,EACjC,CAGA5F,KAAKc,aAAa,GAAGQ,iBAAiB,QAAStB,KAAKkB,2BACpDlB,KAAKc,aAAad,KAAKc,aAAaS,OAAS,GAAGD,iBAAiB,QAAStB,KAAKqB,8BAG/ErB,KAAKL,UAAUmG,YAAoB,IAARb,GAAqC,EAAI,GAGpEjF,KAAKc,aAAqB,IAARmE,EAAoC,EAAIjF,KAAKc,aAAaS,OAAS,GAAGwE,QAGxF5E,EAAE6E,iBACF7E,EAAE8E,0BACJ,CAEQ,sBAAA1C,GACN,GAAiC,IAA7BvD,KAAKc,aAAaS,OACpB,OAGF,MAAM2E,EAAYlG,KAAKH,oBAAoBU,aAAa4F,eACxD,IAAKD,EACH,OAGF,GAAIA,EAAUE,YAOZ,YAHIpG,KAAKY,cAAcyF,SAASH,EAAUI,aACxCtG,KAAKL,UAAU4G,kBAKnB,IAAKL,EAAUI,aAAeJ,EAAUM,UAEtC,YADAC,QAAQC,MAAM,wCAKhB,IAAIC,EAAQ,CAAEC,KAAMV,EAAUI,WAAYO,OAAQX,EAAUY,cACxDxE,EAAM,CAAEsE,KAAMV,EAAUM,UAAWK,OAAQX,EAAUa,aASzD,IARKJ,EAAMC,KAAKI,wBAAwB1E,EAAIsE,MAAQK,KAAKC,6BAAiCP,EAAMC,OAAStE,EAAIsE,MAAQD,EAAME,OAASvE,EAAIuE,WACrIF,EAAOrE,GAAO,CAACA,EAAKqE,IAInBA,EAAMC,KAAKI,wBAAwBhH,KAAKc,aAAa,KAAOmG,KAAKE,+BAAiCF,KAAKG,+BACzGT,EAAQ,CAAEC,KAAM5G,KAAKc,aAAa,GAAGuG,WAAW,GAAIR,OAAQ,KAEzD7G,KAAKY,cAAcyF,SAASM,EAAMC,MAErC,OAEF,MAAMU,EAAiBtH,KAAKc,aAAayG,OAAO,GAAG,GAOnD,GANIjF,EAAIsE,KAAKI,wBAAwBM,IAAmBL,KAAKE,+BAAiCF,KAAKC,+BACjG5E,EAAM,CACJsE,KAAMU,EACNT,OAAQS,EAAe1D,aAAarC,QAAU,KAG7CvB,KAAKY,cAAcyF,SAAS/D,EAAIsE,MAEnC,OAGF,MAAMY,EAAc,EAAGZ,OAAMC,aAE3B,MAAMY,EAAkBb,aAAgBc,KAAOd,EAAKe,WAAaf,EACjE,IAAIgB,EAAMC,SAASJ,GAAYpC,aAAa,iBAAkB,IAAM,EACpE,GAAIyC,MAAMF,GAER,OADAnB,QAAQsB,KAAK,mCACN,KAGT,MAAMtD,EAAUzE,KAAKC,YAAY6D,IAAI2D,GACrC,IAAKhD,EAEH,OADAgC,QAAQsB,KAAK,oCACN,KAGT,IAAIC,EAASnB,EAASpC,EAAQlD,OAASkD,EAAQoC,GAAUpC,EAAQ8C,OAAO,GAAG,GAAK,EAKhF,OAJIS,GAAUhI,KAAKL,UAAUsI,SACzBL,EACFI,EAAS,GAEJ,CACLJ,MACAI,WAIEE,EAAiBV,EAAYb,GAC7BwB,EAAeX,EAAYlF,GAEjC,GAAK4F,GAAmBC,EAAxB,CAIA,GAAID,EAAeN,IAAMO,EAAaP,KAAQM,EAAeN,MAAQO,EAAaP,KAAOM,EAAeF,QAAUG,EAAaH,OAE7H,MAAM,IAAIjG,MAAM,iBAGlB/B,KAAKL,UAAUyI,OACbF,EAAeF,OACfE,EAAeN,KACdO,EAAaP,IAAMM,EAAeN,KAAO5H,KAAKL,UAAUsI,KAAOC,EAAeF,OAASG,EAAaH,OAVvG,CAYF,CAEQ,aAAA9F,CAAcnB,GAEpBf,KAAKc,aAAad,KAAKc,aAAaS,OAAS,GAAGoE,oBAAoB,QAAS3F,KAAKqB,8BAGlF,IAAK,IAAIvC,EAAIkB,KAAKY,cAAcyH,SAAS9G,OAAQzC,EAAIkB,KAAKL,UAAUoB,KAAMjC,IACxEkB,KAAKc,aAAahC,GAAKkB,KAAKgB,+BAC5BhB,KAAKY,cAAcK,YAAYjB,KAAKc,aAAahC,IAGnD,KAAOkB,KAAKc,aAAaS,OAASR,GAChCf,KAAKY,cAAc8E,YAAY1F,KAAKc,aAAa2E,OAInDzF,KAAKc,aAAad,KAAKc,aAAaS,OAAS,GAAGD,iBAAiB,QAAStB,KAAKqB,8BAE/ErB,KAAKqD,wBACP,CAEQ,4BAAArC,GACN,MAAMc,EAAU9B,KAAKH,oBAAoBU,aAAaE,cAAc,OAIpE,OAHAqB,EAAQjB,aAAa,OAAQ,YAC7BiB,EAAQwG,UAAY,EACpBtI,KAAKuI,sBAAsBzG,GACpBA,CACT,CAEQ,sBAAAuB,GACN,GAAKrD,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAA7C,CAGAC,OAAOC,OAAO7I,KAAKQ,wBAAwBsI,MAAO,CAChDC,MAAO,GAAG/I,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOD,UACpDE,SAAU,GAAGjJ,KAAKL,UAAUuJ,QAAQD,eAElCjJ,KAAKc,aAAaS,SAAWvB,KAAKL,UAAUoB,MAC9Cf,KAAKkC,cAAclC,KAAKL,UAAUoB,MAEpC,IAAK,IAAIjC,EAAI,EAAGA,EAAIkB,KAAKL,UAAUoB,KAAMjC,IACvCkB,KAAKuI,sBAAsBvI,KAAKc,aAAahC,IAC7CkB,KAAK+E,eAAe/E,KAAKc,aAAahC,GAVxC,CAYF,CAEQ,qBAAAyJ,CAAsBzG,GAC5BA,EAAQgH,MAAMH,OAAS,GAAG3I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,UACpE,CAWQ,cAAA5D,CAAejD,GACrBA,EAAQgH,MAAMK,UAAY,GAC1B,MAAMJ,EAAQjH,EAAQsH,wBAAwBL,MACxCM,EAAarJ,KAAKC,YAAY6D,IAAIhC,IAAUyF,OAAO,KAAK,GAC9D,IAAK8B,EACH,OAEF,MAAMC,EAAcD,EAAarJ,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MACzEjH,EAAQgH,MAAMK,UAAY,UAAUG,EAAcP,IACpD,mDA3ZWvJ,EAAoB+J,EAAA,CA8B5BC,EAAA,EAAAlK,EAAAmK,uBACAD,EAAA,EAAAnK,EAAAqK,qBACAF,EAAA,EAAAnK,EAAAsK,iBAhCQnK,cCfb,SAAAoK,EAAuCC,GACrC,OAAOA,EAAKC,QAAQ,SAAU,KAChC,CAMA,SAAAC,EAAoCF,EAAcG,GAChD,OAAKA,EAME,SADeH,EAAKC,QAAQ,QAAS,aAJnCD,CAMX,CAyBA,SAAAI,EAAsBJ,EAAcK,EAA+BC,EAA2BC,GAE5FP,EAAOE,EADPF,EAAOD,EAAuBC,GACGM,EAAYE,gBAAgBL,qBAA6E,IAAvDI,EAAeE,WAAWC,0BAC7GJ,EAAYK,iBAAiBX,GAAM,GACnCK,EAASO,MAAQ,EACnB,CAOA,SAAAC,EAA6CC,EAAgBT,EAA+BU,GAG1F,MAAMC,EAAMD,EAAcxB,wBACpB0B,EAAOH,EAAGI,QAAUF,EAAIC,KAAO,GAC/BE,EAAML,EAAGM,QAAUJ,EAAIG,IAAM,GAGnCd,EAASpB,MAAMC,MAAQ,OACvBmB,EAASpB,MAAMH,OAAS,OACxBuB,EAASpB,MAAMgC,KAAO,GAAGA,MACzBZ,EAASpB,MAAMkC,IAAM,GAAGA,MACxBd,EAASpB,MAAMoC,OAAS,OAExBhB,EAASnE,OACX,mHA9CA,SAA4B4E,EAAoBQ,GAC1CR,EAAGS,eACLT,EAAGS,cAAcC,QAAQ,aAAcF,EAAiBG,eAG1DX,EAAG3E,gBACL,qBAKA,SAAiC2E,EAAoBT,EAA+BC,EAA2BC,GAC7GO,EAAGY,kBACCZ,EAAGS,eAELnB,EADaU,EAAGS,cAAcI,QAAQ,cAC1BtB,EAAUC,EAAaC,EAEvC,iEAkCA,SAAkCO,EAAgBT,EAA+BU,EAA4BO,EAAqCM,GAChJf,EAA6BC,EAAIT,EAAUU,GAEvCa,GACFN,EAAiBO,iBAAiBf,GAIpCT,EAASO,MAAQU,EAAiBG,cAClCpB,EAAS9B,QACX,4FCxFA,MAAAuD,EAAAzM,EAAA,2BAEA,iBAAAQ,GACUM,KAAA4L,OAAmE,IAAID,EAAAE,UACvE7L,KAAA8L,KAAiE,IAAIH,EAAAE,SAsB/E,CApBS,MAAAE,CAAOC,EAAYC,EAAYxB,GACpCzK,KAAK8L,KAAKhH,IAAIkH,EAAIC,EAAIxB,EACxB,CAEO,MAAAyB,CAAOF,EAAYC,GACxB,OAAOjM,KAAK8L,KAAKhI,IAAIkI,EAAIC,EAC3B,CAEO,QAAAE,CAASH,EAAYC,EAAYxB,GACtCzK,KAAK4L,OAAO9G,IAAIkH,EAAIC,EAAIxB,EAC1B,CAEO,QAAA2B,CAASJ,EAAYC,GAC1B,OAAOjM,KAAK4L,OAAO9H,IAAIkI,EAAIC,EAC7B,CAEO,KAAAI,GACLrM,KAAK4L,OAAOS,QACZrM,KAAK8L,KAAKO,OACZ,03BCRF,MAAAC,EAAApN,EAAA,MACYF,EAAOC,EAAAC,EAAA,OACnBqN,EAAArN,EAAA,MAEAsN,EAAAtN,EAAA,MACAuN,EAAAvN,EAAA,MACAwN,EAAAxN,EAAA,MACAyN,EAAAzN,EAAA,MACA0N,EAAA1N,EAAA,MAEA2N,EAAA3N,EAAA,MACA4N,EAAA5N,EAAA,KACA6N,EAAA7N,EAAA,MACA8N,EAAA9N,EAAA,MACA+N,EAAA/N,EAAA,MACAgO,EAAAhO,EAAA,MACAiO,EAAAjO,EAAA,MACAkO,EAAAlO,EAAA,MACAG,EAAAH,EAAA,MACAmO,EAAAnO,EAAA,MACAoO,EAAApO,EAAA,MACAqO,EAAArO,EAAA,MACAsO,EAAAtO,EAAA,MACYuO,EAAOxO,EAAAC,EAAA,MAEnBwO,EAAAxO,EAAA,MAGAyO,EAAAzO,EAAA,MACA0O,EAAA1O,EAAA,MACAI,EAAAJ,EAAA,MACA2O,EAAA3O,EAAA,MACA4O,EAAA5O,EAAA,MACA6O,EAAA7O,EAAA,MACA8O,EAAA9O,EAAA,MACAK,EAAAL,EAAA,MACAE,EAAAF,EAAA,MAEA,MAAA+O,UAAyCT,EAAAU,aAWvC,aAAWC,GAAuC,OAAOnO,KAAKoO,WAAW3D,KAAO,CAiEhF,WAAW4D,GAA0B,OAAOrO,KAAKsO,SAASC,KAAO,CAEjE,UAAWrL,GAAyB,OAAOlD,KAAKwO,QAAQD,KAAO,CAE/D,cAAW/L,GAA+B,OAAOxC,KAAKyO,mBAAmBF,KAAO,CAEhF,aAAW3L,GAA8B,OAAO5C,KAAK0O,kBAAkBH,KAAO,CAE9E,cAAWI,GAAoC,OAAO3O,KAAK4O,YAAYL,KAAO,CAI9E,cAAW/F,GACT,IAAKxI,KAAKF,eACR,OAEF,MAAM0I,EAAaxI,KAAKF,eAAe0I,WACvC,MAAO,CACLC,IAAK,CACHO,OAAQ,IAAKR,EAAWC,IAAIO,QAC5BN,KAAM,IAAKF,EAAWC,IAAIC,OAE5BmG,OAAQ,CACN7F,OAAQ,IAAKR,EAAWqG,OAAO7F,QAC/BN,KAAM,IAAKF,EAAWqG,OAAOnG,MAC7BjG,KAAM,IAAK+F,EAAWqG,OAAOpM,OAGnC,CAEA,WAAA/C,CACEwJ,EAAqC,IAErCnJ,MAAMmJ,GAnGSlJ,KAAAoO,WAA6CpO,KAAK0B,UAAU,IAAItC,EAAA0P,mBAK1E9O,KAAA+O,QAAoBtB,EAwBnBzN,KAAAgP,iBAA2B,EAM3BhP,KAAAiP,cAAwB,EAOxBjP,KAAAkP,kBAA4B,EAO5BlP,KAAAmP,qBAA+B,EAG/BnP,KAAAoP,sBAAiEpP,KAAK0B,UAAU,IAAItC,EAAA0P,mBAE3E9O,KAAAqP,cAAgBrP,KAAK0B,UAAU,IAAIsM,EAAAsB,SACpCtP,KAAAuP,aAAevP,KAAKqP,cAAcd,MACjCvO,KAAAwP,OAASxP,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC7BtP,KAAA+C,MAAQ/C,KAAKwP,OAAOjB,MACnBvO,KAAAyP,mBAAqBzP,KAAK0B,UAAU,IAAIsM,EAAAsB,SACzCtP,KAAA0P,kBAAoB1P,KAAKyP,mBAAmBlB,MAC3CvO,KAAA2P,eAAiB3P,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAA4P,cAAgB5P,KAAK2P,eAAepB,MACnCvO,KAAA6P,QAAU7P,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC9BtP,KAAA8P,OAAS9P,KAAK6P,QAAQtB,MAE9BvO,KAAAsO,SAAWtO,KAAK0B,UAAU,IAAIsM,EAAAsB,SAE9BtP,KAAAwO,QAAUxO,KAAK0B,UAAU,IAAIsM,EAAAsB,SAE7BtP,KAAAyO,mBAAqBzO,KAAK0B,UAAU,IAAIsM,EAAAsB,SAExCtP,KAAA0O,kBAAoB1O,KAAK0B,UAAU,IAAIsM,EAAAsB,SAEvCtP,KAAA4O,YAAc5O,KAAK0B,UAAU,IAAIsM,EAAAsB,SAExBtP,KAAA+P,oBAAsB/P,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC1CtP,KAAAoD,mBAAqBpD,KAAK+P,oBAAoBxB,MAyB5DvO,KAAKgQ,SAELhQ,KAAKiQ,mBAAqBjQ,KAAKkQ,sBAAsBC,eAAevC,EAAAwC,mBACpEpQ,KAAKkQ,sBAAsBG,WAAW/Q,EAAAgR,mBAAoBtQ,KAAKiQ,oBAC/DjQ,KAAKuQ,iBAAmBvQ,KAAKkQ,sBAAsBC,eAAe7C,EAAAkD,iBAClExQ,KAAKkQ,sBAAsBG,WAAWhR,EAAAoR,iBAAkBzQ,KAAKuQ,kBAC7DvQ,KAAK0Q,qBAAuB1Q,KAAKkQ,sBAAsBC,eAAenD,EAAA2D,qBACtE3Q,KAAKkQ,sBAAsBG,WAAWhR,EAAAuR,qBAAsB5Q,KAAK0Q,sBACjE1Q,KAAK0Q,qBAAqBG,qBAAqB7Q,KAAKkQ,sBAAsBC,eAAe5D,EAAAuE,kBAGzF9Q,KAAK0B,UAAU1B,KAAK+Q,cAAcC,cAAc,IAAMhR,KAAK6P,QAAQoB,SACnEjR,KAAK0B,UAAU1B,KAAK+Q,cAAcG,qBAAsB/P,GAAMnB,KAAKkE,QAAQ/C,GAAGkB,OAAS,EAAGlB,GAAGmB,KAAQtC,KAAKe,KAAO,KACjHf,KAAK0B,UAAU1B,KAAK+Q,cAAcI,mBAAmB,IAAMnR,KAAKoR,iBAChEpR,KAAK0B,UAAU1B,KAAK+Q,cAAcM,eAAe,IAAMrR,KAAKsR,UAC5DtR,KAAK0B,UAAU1B,KAAK+Q,cAAcQ,8BAA8BC,GAAQxR,KAAKyR,sBAAsBD,KACnGxR,KAAK0B,UAAU1B,KAAK+Q,cAAcW,QAASnD,GAAUvO,KAAK2R,kBAAkBpD,KAC5EvO,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+Q,cAAcxB,aAAcvP,KAAKqP,gBACxErP,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+Q,cAAcnB,cAAe5P,KAAK2P,iBACzE3P,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+Q,cAAcvO,WAAYxC,KAAKyO,qBACtEzO,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+Q,cAAcnO,UAAW5C,KAAK0O,oBAGrE1O,KAAK0B,UAAU1B,KAAK8R,eAAe7P,SAASd,GAAKnB,KAAK+R,aAAa5Q,EAAE8G,KAAM9G,EAAEJ,QAE7Ef,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKgS,4BAAyBpN,EAC9B5E,KAAK8B,SAAS6F,YAAYjC,YAAY1F,KAAK8B,WAE/C,CAQQ,iBAAA6P,CAAkBpD,GACxB,GAAKvO,KAAKiS,cACV,IAAK,MAAMC,KAAO3D,EAAO,CACvB,IAAI4D,EACAC,EACJ,OAAQF,EAAIG,OACV,SACEF,EAAM,aACNC,EAAQ,KACR,MACF,SACED,EAAM,aACNC,EAAQ,KACR,MACF,SACED,EAAM,SACNC,EAAQ,KACR,MACF,QAEED,EAAM,OACNC,EAAQ,KAAOF,EAAIG,MAEvB,OAAQH,EAAIV,MACV,OACE,MAAMc,EAAW/E,EAAAgF,MAAMC,WAAmB,SAARL,EAC9BnS,KAAKiS,cAAcQ,OAAOC,KAAKR,EAAIG,OACnCrS,KAAKiS,cAAcQ,OAAON,IAC9BnS,KAAKmK,YAAYK,iBAAiB,KAAa4H,MAAS,EAAAzE,EAAAgF,aAAYL,SACpE,MACF,OACE,GAAY,SAARH,EACFnS,KAAKiS,cAAcW,aAAaH,GAAUA,EAAOC,KAAKR,EAAIG,OAAS9E,EAAAsF,SAASC,WAAWZ,EAAIK,YACtF,CACL,MAAMQ,EAAcZ,EACpBnS,KAAKiS,cAAcW,aAAaH,GAAUA,EAAOM,GAAexF,EAAAsF,SAASC,WAAWZ,EAAIK,OAC1F,CACA,MACF,OACEvS,KAAKiS,cAAce,aAAad,EAAIG,OAG1C,CACF,CAOQ,kBAAAY,GACN,IAAKjT,KAAKiS,cAAe,OACzB,MAGMiB,EAHc3F,EAAA4F,IAAIC,kBAAkBpT,KAAKiS,cAAcQ,OAAOY,WAAWC,MAAQ,GACnE/F,EAAA4F,IAAIC,kBAAkBpT,KAAKiS,cAAcQ,OAAOc,WAAWD,MAAQ,GAEnC,EAAI,EACxDtT,KAAKmK,YAAYK,iBAAiB,UAAkB0I,KACtD,CAEU,MAAAlD,GACRjQ,MAAMiQ,SAENhQ,KAAKgS,4BAAyBpN,CAChC,CAKA,UAAWT,GACT,OAAOnE,KAAKwT,QAAQC,MACtB,CAKO,KAAA1N,GACD/F,KAAKkK,UACPlK,KAAKkK,SAASnE,MAAM,CAAE2N,eAAe,GAEzC,CAEQ,mCAAAC,CAAoClJ,GACtCA,GACGzK,KAAKoP,sBAAsB3E,OAASzK,KAAKF,iBAC5CE,KAAKoP,sBAAsB3E,MAAQzK,KAAKkQ,sBAAsBC,eAAerC,EAAAtO,qBAAsBQ,OAGrGA,KAAKoP,sBAAsB/C,OAE/B,CAKQ,oBAAAuH,CAAqBjJ,GACvB3K,KAAKmK,YAAYE,gBAAgBwJ,WACnC7T,KAAKmK,YAAYK,iBAAiB,OAEpCxK,KAAK8B,QAASpB,UAAUC,IAAI,SAC5BX,KAAK8T,cACL9T,KAAKsO,SAAS2C,MAChB,CAMO,IAAA8C,GACL,OAAO/T,KAAKkK,UAAU6J,MACxB,CAKQ,mBAAAC,GAGFhU,KAAKiU,8BAA8BtH,EAAAuH,mBACrClU,KAAKiU,mBAAmBF,OAE1B/T,KAAKkK,SAAUO,MAAQ,GACvBzK,KAAKkE,QAAQlE,KAAKmE,OAAOgQ,EAAGnU,KAAKmE,OAAOgQ,GACpCnU,KAAKmK,YAAYE,gBAAgBwJ,WACnC7T,KAAKmK,YAAYK,iBAAiB,OAEpCxK,KAAK8B,QAASpB,UAAUgD,OAAO,SAC/B1D,KAAKwO,QAAQyC,MACf,CAEQ,aAAAmD,GACN,IAAKpU,KAAKkK,WAAalK,KAAKmE,OAAOkQ,oBAAsBrU,KAAKiU,mBAAoBK,cAAgBtU,KAAKF,eACrG,OAEF,MAAMyU,EAAUvU,KAAKmE,OAAOqQ,MAAQxU,KAAKmE,OAAOgQ,EAC1CM,EAAazU,KAAKmE,OAAOE,MAAMP,IAAIyQ,GACzC,IAAKE,EACH,OAEF,MAAMC,EAAUC,KAAKC,IAAI5U,KAAKmE,OAAO0Q,EAAG7U,KAAKiI,KAAO,GAC9C6M,EAAa9U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OACrDI,EAAQ0L,EAAWM,SAASL,GAC5BM,EAAYhV,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAAQA,EAC5DkM,EAAYjV,KAAKmE,OAAOgQ,EAAInU,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OACpEuM,EAAaR,EAAU1U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAIrE/I,KAAKkK,SAASpB,MAAMgC,KAAOoK,EAAa,KACxClV,KAAKkK,SAASpB,MAAMkC,IAAMiK,EAAY,KACtCjV,KAAKkK,SAASpB,MAAMC,MAAQiM,EAAY,KACxChV,KAAKkK,SAASpB,MAAMH,OAASmM,EAAa,KAC1C9U,KAAKkK,SAASpB,MAAMqM,WAAaL,EAAa,KAC9C9U,KAAKkK,SAASpB,MAAMoC,OAAS,IAC/B,CAKQ,WAAAkK,GACNpV,KAAKqV,YAGLrV,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAU,OAASyM,IAGtDvO,KAAKsV,iBAGV,EAAAhJ,EAAAiJ,aAAYhH,EAAOvO,KAAKwV,sBAE1B,MAAMC,EAAuBlH,IAAgC,EAAAjC,EAAAoJ,kBAAiBnH,EAAOvO,KAAKkK,SAAWlK,KAAKmK,YAAanK,KAAKoK,gBAC5HpK,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,QAASuL,IAC9DzV,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAU,QAAS2T,IAGzDhI,EAAQkI,UAEV3V,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAU,YAAcyM,IAC3C,IAAjBA,EAAMqH,SACR,EAAAtJ,EAAAuJ,mBAAkBtH,EAAOvO,KAAKkK,SAAWlK,KAAK4K,cAAgB5K,KAAKwV,kBAAoBxV,KAAKkJ,QAAQ4M,0BAIxG9V,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAU,cAAgByM,KAClE,EAAAjC,EAAAuJ,mBAAkBtH,EAAOvO,KAAKkK,SAAWlK,KAAK4K,cAAgB5K,KAAKwV,kBAAoBxV,KAAKkJ,QAAQ4M,0BAOpGrI,EAAQsI,SAGV/V,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAU,WAAayM,IAC1C,IAAjBA,EAAMqH,SACR,EAAAtJ,EAAA5B,8BAA6B6D,EAAOvO,KAAKkK,SAAWlK,KAAK4K,iBAIjE,CAKQ,SAAAyK,GACNrV,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,QAAUS,GAAsB3K,KAAKgW,OAAOrL,IAAK,IACtG3K,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,UAAYS,GAAsB3K,KAAKiW,SAAStL,IAAK,IAC1G3K,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,WAAaS,GAAsB3K,KAAKkW,UAAUvL,IAAK,IAC5G3K,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,mBAAoB,KAMvElK,KAAKoU,gBACLpU,KAAKiU,mBAAoBkC,mBACzBnW,KAAKiU,mBAAoBmC,+BAE3BpW,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,oBAAsB/I,GAAwBnB,KAAKiU,mBAAoBoC,kBAAkBlV,KAC9InB,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,iBAAmB/I,IAClEnB,KAAKiU,8BAA8BtH,EAAAuH,kBACjClU,KAAKiU,mBAAmBqC,eAAenV,IACzCnB,KAAKkK,SAAUqM,cAAc,IAAIC,YAC/B,yCACA,CAAEC,SAAS,KAIfzW,KAAKiU,mBAAoBqC,oBAG7BtW,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAW,QAAUS,GAAmB3K,KAAK0W,YAAY/L,IAAK,IACxG3K,KAAK0B,UAAU1B,KAAKmC,SAAS,IAAMnC,KAAKiU,mBAAoBmC,6BAC9D,CAOO,IAAAO,CAAKC,GACV,IAAKA,EACH,MAAM,IAAI7U,MAAM,uCAQlB,GALK6U,EAAOC,aACV7W,KAAK8W,YAAYC,MAAM,2EAIrB/W,KAAK8B,SAASkV,cAAcC,aAAejX,KAAKH,oBAKlD,YAHIG,KAAK8B,QAAQkV,cAAcC,cAAgBjX,KAAKH,oBAAoBqX,SACtElX,KAAKH,oBAAoBqX,OAASlX,KAAK8B,QAAQkV,cAAcC,cAKjEjX,KAAKmX,UAAYP,EAAOI,cACpBhX,KAAKkJ,QAAQkO,kBAAoBpX,KAAKkJ,QAAQkO,4BAA4BC,WAC5ErX,KAAKmX,UAAYnX,KAAKoK,eAAeE,WAAW8M,kBAIlDpX,KAAK8B,QAAU9B,KAAKmX,UAAU1W,cAAc,OAC5CT,KAAK8B,QAAQwV,IAAM,MACnBtX,KAAK8B,QAAQpB,UAAUC,IAAI,YAC3BX,KAAK8B,QAAQpB,UAAUC,IAAI,SAC3BX,KAAK8B,QAAQpB,UAAU6W,OAAO,qBAAsBvX,KAAKkJ,QAAQsO,mBACjExX,KAAK0B,UAAU1B,KAAKoK,eAAeqN,uBAAuB,oBAAqBhN,GAASzK,KAAK8B,QAASpB,UAAU6W,OAAO,qBAAsB9M,KAC7ImM,EAAO3V,YAAYjB,KAAK8B,SAIxB,MAAM4V,EAAW1X,KAAKmX,UAAUQ,yBAChC3X,KAAK4X,iBAAmB5X,KAAKmX,UAAU1W,cAAc,OACrDT,KAAK4X,iBAAiBlX,UAAUC,IAAI,kBACpC+W,EAASzW,YAAYjB,KAAK4X,kBAE1B5X,KAAK4K,cAAgB5K,KAAKmX,UAAU1W,cAAc,OAClDT,KAAK4K,cAAclK,UAAUC,IAAI,gBACjCX,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK4K,cAAe,YAAcD,GAAmB3K,KAAK6X,kBAAkBlN,KAGjH3K,KAAK8X,iBAAmB9X,KAAKmX,UAAU1W,cAAc,OACrDT,KAAK8X,iBAAiBpX,UAAUC,IAAI,iBACpCX,KAAK4K,cAAc3J,YAAYjB,KAAK8X,kBACpCJ,EAASzW,YAAYjB,KAAK4K,eAE1B,MAAMV,EAAWlK,KAAKkK,SAAWlK,KAAKmX,UAAU1W,cAAc,YAC9DT,KAAKkK,SAASxJ,UAAUC,IAAI,yBAC5BX,KAAKkK,SAASrJ,aAAa,aAAc7B,EAAQ+Y,YAAYjU,OACxD2J,EAAQuK,YAGXhY,KAAKkK,SAASrJ,aAAa,iBAAkB,SAE/Cb,KAAKkK,SAASrJ,aAAa,cAAe,OAC1Cb,KAAKkK,SAASrJ,aAAa,iBAAkB,OAC7Cb,KAAKkK,SAASrJ,aAAa,aAAc,SACzCb,KAAKkK,SAAS5B,SAAW,EACzBtI,KAAK0B,UAAU1B,KAAKoK,eAAeqN,uBAAuB,eAAgB,IAAMvN,EAAS+N,SAAWjY,KAAKoK,eAAeE,WAAW4N,eACnIlY,KAAKkK,SAAS+N,SAAWjY,KAAKoK,eAAeE,WAAW4N,aAIxDlY,KAAKH,oBAAsBG,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAepD,EAAAoL,mBAClFnY,KAAKkK,SACL0M,EAAOI,cAAcC,aAAeC,OAEpClX,KAAKmX,YAAiC,oBAAXD,OAA0BA,OAAOkB,SAAW,QAEzEpY,KAAKkQ,sBAAsBG,WAAWhR,EAAAqK,oBAAqB1J,KAAKH,qBAEhEG,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAU,QAAUS,GAAmB3K,KAAK4T,qBAAqBjJ,KAC3G3K,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKkK,SAAU,OAAQ,IAAMlK,KAAKgU,wBACvEhU,KAAK8X,iBAAiB7W,YAAYjB,KAAKkK,UAEvClK,KAAKqY,iBAAmBrY,KAAKkQ,sBAAsBC,eAAetD,EAAAyL,gBAAiBtY,KAAKmX,UAAWnX,KAAK8X,kBACxG9X,KAAKkQ,sBAAsBG,WAAWhR,EAAAkZ,iBAAkBvY,KAAKqY,kBAE7DrY,KAAKiS,cAAgBjS,KAAKkQ,sBAAsBC,eAAe9C,EAAAmL,cAC/DxY,KAAKkQ,sBAAsBG,WAAWhR,EAAAoZ,cAAezY,KAAKiS,eAG1DjS,KAAK0B,UAAU1B,KAAK+Q,cAAc2H,0BAA0B,IAAM1Y,KAAKiT,uBAGvEjT,KAAK0B,UAAU1B,KAAKiS,cAAc0G,eAAe,KAC3C3Y,KAAKmK,YAAYE,gBAAgBuO,oBACnC5Y,KAAKiT,wBAITjT,KAAK6Y,wBAA0B7Y,KAAKkQ,sBAAsBC,eAAerD,EAAAgM,wBACzE9Y,KAAKkQ,sBAAsBG,WAAWhR,EAAA0Z,wBAAyB/Y,KAAK6Y,yBAEpE7Y,KAAKF,eAAiBE,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAehD,EAAA6L,cAAehZ,KAAKe,KAAMf,KAAK4K,gBAC9G5K,KAAKkQ,sBAAsBG,WAAWhR,EAAAsK,eAAgB3J,KAAKF,gBAC3DE,KAAK0B,UAAU1B,KAAKF,eAAemZ,yBAAyB9X,GAAKnB,KAAKkZ,UAAUjI,KAAK9P,KACrFnB,KAAK0B,UAAU1B,KAAKF,eAAesD,mBAAmBjC,GAAKnB,KAAK+P,oBAAoBkB,KAAK,CACvFxI,IAAK,CACHO,OAAQ,IAAK7H,EAAEsH,IAAIO,QACnBN,KAAM,IAAKvH,EAAEsH,IAAIC,OAEnBmG,OAAQ,CACN7F,OAAQ,IAAK7H,EAAE0N,OAAO7F,QACtBN,KAAM,IAAKvH,EAAE0N,OAAOnG,MACpBjG,KAAM,IAAKtB,EAAE0N,OAAOpM,WAGxBzC,KAAKiC,SAASd,GAAKnB,KAAKF,eAAgBqZ,OAAOhY,EAAE8G,KAAM9G,EAAEJ,OAEzDf,KAAKoZ,iBAAmBpZ,KAAKmX,UAAU1W,cAAc,OACrDT,KAAKoZ,iBAAiB1Y,UAAUC,IAAI,oBACpCX,KAAKiU,mBAAqBjU,KAAKkQ,sBAAsBC,eAAexD,EAAAuH,kBAAmBlU,KAAKkK,SAAUlK,KAAKoZ,kBAC3GpZ,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KACtBzD,KAAKiU,8BAA8BtH,EAAAuH,mBACrClU,KAAKiU,mBAAmBoF,aAG5BrZ,KAAK8X,iBAAiB7W,YAAYjB,KAAKoZ,kBAEvCpZ,KAAKsZ,oBAAsBtZ,KAAKkQ,sBAAsBC,eAAelD,EAAAsM,oBACrEvZ,KAAKkQ,sBAAsBG,WAAWhR,EAAAma,oBAAqBxZ,KAAKsZ,qBAEhE,MAAMnL,EAAYnO,KAAKoO,WAAW3D,MAAQzK,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAepC,EAAA0L,UAAWzZ,KAAK4K,gBAGnH5K,KAAK8B,QAAQb,YAAYyW,GAEzB,IACE1X,KAAK4O,YAAYqC,KAAKjR,KAAK8B,QAC7B,CAAE,MAAOX,GACPnB,KAAK8W,YAAYpQ,MAAM,wCAAyCvF,EAClE,CACKnB,KAAKF,eAAe4Z,eACvB1Z,KAAKF,eAAe6Z,YAAY3Z,KAAK4Z,mBAGvC5Z,KAAK0B,UAAU1B,KAAKuP,aAAa,KAC/BvP,KAAKF,eAAgB+Z,mBACrB7Z,KAAKoU,mBAEPpU,KAAK0B,UAAU1B,KAAKiC,SAAS,KAC3BjC,KAAKF,eAAgBga,aAAa9Z,KAAKiI,KAAMjI,KAAKe,MAClDf,KAAKoU,mBAEPpU,KAAK0B,UAAU1B,KAAKkD,OAAO,IAAMlD,KAAKF,eAAgBia,eACtD/Z,KAAK0B,UAAU1B,KAAKqO,QAAQ,IAAMrO,KAAKF,eAAgBka,gBAEvDha,KAAKia,UAAYja,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAe3D,EAAA0N,SAAUla,KAAK8B,QAAS9B,KAAK4K,gBACvG5K,KAAK0B,UAAU1B,KAAKia,UAAUE,qBAAqBhZ,IACjDpB,MAAM+F,YAAY3E,GAAG,GACrBnB,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,MAG9Bf,KAAKwV,kBAAoBxV,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAe/C,EAAAgN,iBAChFpa,KAAK8B,QACL9B,KAAK4K,cACLuD,IAEFnO,KAAKkQ,sBAAsBG,WAAWhR,EAAAgb,kBAAmBra,KAAKwV,mBAC9DxV,KAAKsa,cAAgBta,KAAKkQ,sBAAsBC,eAAejD,EAAAqN,cAC/Dva,KAAKkQ,sBAAsBG,WAAWhR,EAAAmb,cAAexa,KAAKsa,eAC1Dta,KAAK0B,UAAU1B,KAAKwV,kBAAkB2E,qBAAqBhZ,GAAKnB,KAAK8F,YAAY3E,EAAEsZ,OAAQtZ,EAAEuZ,uBAC7F1a,KAAK0B,UAAU1B,KAAKwV,kBAAkB9F,kBAAkB,IAAM1P,KAAKyP,mBAAmBwB,SACtFjR,KAAK0B,UAAU1B,KAAKwV,kBAAkBmF,gBAAgBxZ,GAAKnB,KAAKF,eAAgB8a,uBAAuBzZ,EAAEkB,MAAOlB,EAAEmB,IAAKnB,EAAE0Z,oBACzH7a,KAAK0B,UAAU1B,KAAKwV,kBAAkBsF,sBAAsBjR,IAI1D7J,KAAKkK,SAAUO,MAAQZ,EACvB7J,KAAKkK,SAAUnE,QACf/F,KAAKkK,SAAU9B,YAEjBpI,KAAK0B,UAAUsM,EAAA4D,WAAWmJ,IACxB/a,KAAKgb,UAAUzM,MACfvO,KAAK+Q,cAAcxO,SAFNyL,CAGb,KACAhO,KAAKwV,kBAAmBtR,UACxBlE,KAAKia,WAAWgB,eAGlBjb,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAe1D,EAAAyO,yBAA0Blb,KAAK4K,gBACxF5K,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK8B,QAAS,YAAcX,GAAkBnB,KAAKwV,kBAAmB2F,gBAAgBha,KAGvHnB,KAAKob,kBAAkBC,uBAAyBrb,KAAKkJ,QAAQoS,uBAC/Dtb,KAAKwV,kBAAkB+F,UACvBvb,KAAK8B,QAAQpB,UAAUC,IAAG,yBAE1BX,KAAKwV,kBAAkBgG,SACvBxb,KAAK8B,QAAQpB,UAAUgD,OAAM,wBAG3B1D,KAAKkJ,QAAQuS,mBAGfzb,KAAKoP,sBAAsB3E,MAAQzK,KAAKkQ,sBAAsBC,eAAerC,EAAAtO,qBAAsBQ,OAErGA,KAAK0B,UAAU1B,KAAKoK,eAAeqN,uBAAuB,mBAAoBtW,GAAKnB,KAAK2T,oCAAoCxS,KAE5H,MAAMua,EAAgB1b,KAAKkJ,QAAQyS,WAAWD,gBAAiB,EACzDE,EAAqB5b,KAAKkJ,QAAQyS,WAAW5S,MAC/C2S,GAAiBE,IACnB5b,KAAK6b,uBAAyB7b,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAezD,EAAAoP,sBAAuB9b,KAAK4X,iBAAkB5X,KAAK4K,iBAE5I5K,KAAKoK,eAAeqN,uBAAuB,YAAahN,IACtD,MAAMsR,GAActR,GAAOiR,gBAAiB,MAAWjR,GAAO1B,OACzD/I,KAAK6b,wBAA0BE,GAAc/b,KAAK4X,kBAAoB5X,KAAK4K,gBAC9E5K,KAAK6b,uBAAyB7b,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAezD,EAAAoP,sBAAuB9b,KAAK4X,iBAAkB5X,KAAK4K,mBAI9I5K,KAAKqY,iBAAiB2D,UAGtBhc,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,GAG5Bf,KAAKoV,cAILpV,KAAKsa,cAAc2B,UAAU,CAC3Bna,QAAS9B,KAAK8B,QACd8I,cAAe5K,KAAK4K,cACpBwN,SAAUpY,KAAKmX,UACf+E,kBAAmBzB,GAAUza,KAAKia,WAAWiC,kBAAkBzB,IAC9D0B,GAAcnc,KAAK0B,UAAUya,GAAa,IAAMnc,KAAK+F,QAC1D,CAEQ,eAAA6T,GACN,OAAO5Z,KAAKkQ,sBAAsBC,eAAevD,EAAAwP,YAAapc,KAAMA,KAAKmX,UAAYnX,KAAK8B,QAAU9B,KAAK4K,cAAgB5K,KAAK4X,iBAAmB5X,KAAK8X,iBAAmB9X,KAAKmO,UAChL,CAQO,OAAAjK,CAAQ7B,EAAeC,EAAa+Z,GAAgB,GACzDrc,KAAKF,gBAAgBwc,YAAYja,EAAOC,EAAK+Z,EAC/C,CAKO,iBAAAxE,CAAkBlN,GACnB3K,KAAKwV,mBAAmB+G,mBAAmB5R,GAC7C3K,KAAK8B,QAASpB,UAAUC,IAAI,iBAE5BX,KAAK8B,QAASpB,UAAUgD,OAAO,gBAEnC,CAKQ,WAAAoQ,GACD9T,KAAKmK,YAAYqS,sBACpBxc,KAAKmK,YAAYqS,qBAAsB,EACvCxc,KAAKkE,QAAQlE,KAAKmE,OAAOgQ,EAAGnU,KAAKmE,OAAOgQ,GAE5C,CAEO,WAAArO,CAAY2W,EAAc/B,GAE3B1a,KAAKia,UACPja,KAAKia,UAAUnU,YAAY2W,GAE3B1c,MAAM+F,YAAY2W,EAAM/B,GAE1B1a,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,EAC9B,CAEO,WAAA2b,CAAYC,GACjB3c,KAAK8F,YAAY6W,GAAa3c,KAAKe,KAAO,GAC5C,CAEO,WAAA6b,GACL5c,KAAK8F,aAAa9F,KAAK8R,eAAe3N,OAAOK,MAC/C,CAEO,cAAAqY,CAAeC,GAChBA,GAAuB9c,KAAKia,UAC9Bja,KAAKia,UAAU8C,aAAa/c,KAAKmE,OAAOqQ,OAAO,GAE/CxU,KAAK8F,YAAY9F,KAAK8R,eAAe3N,OAAOqQ,MAAQxU,KAAK8R,eAAe3N,OAAOK,MAEnF,CAEO,YAAAuY,CAAaxY,GAClB,MAAMyY,EAAezY,EAAOvE,KAAK8R,eAAe3N,OAAOK,MAClC,IAAjBwY,GACFhd,KAAK8F,YAAYkX,EAErB,CAEO,KAAA/S,CAAMgT,IACX,EAAA3Q,EAAArC,OAAMgT,EAAMjd,KAAKkK,SAAWlK,KAAKmK,YAAanK,KAAKoK,eACrD,CAEO,2BAAA8S,CAA4BC,GACjCnd,KAAKgS,uBAAyBmL,CAChC,CAEO,6BAAAC,CAA8BC,GACnCrd,KAAKob,kBAAkBkC,2BAA2BD,EACpD,CAEO,oBAAAxM,CAAqB0M,GAC1B,OAAOvd,KAAK0Q,qBAAqBG,qBAAqB0M,EACxD,CAEO,uBAAAC,CAAwBC,GAC7B,IAAKzd,KAAK6Y,wBACR,MAAM,IAAI9W,MAAM,iCAElB,MAAM2b,EAAW1d,KAAK6Y,wBAAwB8E,SAASF,GAEvD,OADAzd,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,GACrB2c,CACT,CAEO,yBAAAE,CAA0BF,GAC/B,IAAK1d,KAAK6Y,wBACR,MAAM,IAAI9W,MAAM,iCAEd/B,KAAK6Y,wBAAwBgF,WAAWH,IAC1C1d,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,EAEhC,CAEA,WAAW+c,GACT,OAAO9d,KAAKmE,OAAO2Z,OACrB,CAEO,cAAAC,CAAeC,GACpB,OAAOhe,KAAKmE,OAAO8Z,UAAUje,KAAKmE,OAAOqQ,MAAQxU,KAAKmE,OAAOgQ,EAAI6J,EACnE,CAEO,kBAAAE,CAAmBC,GACxB,OAAOne,KAAKiQ,mBAAmBiO,mBAAmBC,EACpD,CAKO,YAAA7I,GACL,QAAOtV,KAAKwV,mBAAoBxV,KAAKwV,kBAAkBF,YACzD,CAQO,MAAAlN,CAAOJ,EAAgBJ,EAAarG,GACzCvB,KAAKwV,kBAAmB4I,aAAapW,EAAQJ,EAAKrG,EACpD,CAMO,YAAA4E,GACL,OAAOnG,KAAKwV,kBAAoBxV,KAAKwV,kBAAkBlK,cAAgB,EACzE,CAEO,oBAAA+S,GACL,GAAKre,KAAKwV,mBAAsBxV,KAAKwV,kBAAkBF,aAIvD,MAAO,CACLjT,MAAO,CACLwS,EAAG7U,KAAKwV,kBAAkB8I,eAAgB,GAC1CnK,EAAGnU,KAAKwV,kBAAkB8I,eAAgB,IAE5Chc,IAAK,CACHuS,EAAG7U,KAAKwV,kBAAkB+I,aAAc,GACxCpK,EAAGnU,KAAKwV,kBAAkB+I,aAAc,IAG9C,CAKO,cAAAhY,GACLvG,KAAKwV,mBAAmBjP,gBAC1B,CAKO,SAAAiY,GACLxe,KAAKwV,mBAAmBgJ,WAC1B,CAEO,WAAAC,CAAYpc,EAAeC,GAChCtC,KAAKwV,mBAAmBiJ,YAAYpc,EAAOC,EAC7C,CAOU,QAAA2T,CAAS1H,GAIjB,GAHAvO,KAAKgP,iBAAkB,EACvBhP,KAAKiP,cAAe,EAEhBjP,KAAKgS,yBAAiE,IAAvChS,KAAKgS,uBAAuBzD,GAC7D,OAAO,EAIT,MAAMmQ,EAA0B1e,KAAK+O,QAAQ4P,OAAS3e,KAAKkJ,QAAQ0V,iBAAmBrQ,EAAMsQ,OAE5F,IAAKH,IAA4B1e,KAAKiU,mBAAoB6K,QAAQvQ,GAIhE,OAHIvO,KAAKkJ,QAAQ6V,mBAAqB/e,KAAKmE,OAAOqQ,QAAUxU,KAAKmE,OAAOK,OACtExE,KAAK6c,gBAAe,IAEf,EAGJ6B,GAA0C,SAAdnQ,EAAMtL,KAAgC,aAAdsL,EAAMtL,MAC7DjD,KAAKmP,qBAAsB,GAG7B,MAAM6P,EAAShf,KAAKuQ,iBAAiB0O,gBAAgB1Q,GAIrD,GAFAvO,KAAK6X,kBAAkBtJ,GAER,IAAXyQ,EAAOxN,MAAoD,IAAXwN,EAAOxN,KAAqC,CAC9F,MAAM0N,EAAclf,KAAKe,KAAO,EAIhC,OAHAf,KAAK8F,YAAuB,IAAXkZ,EAAOxN,MAAuC0N,EAAcA,GAC7E3Q,EAAMvI,iBACNuI,EAAMhD,mBACC,CACT,CAMA,GAJe,IAAXyT,EAAOxN,MACTxR,KAAKwe,YAGHxe,KAAKmf,mBAAmBnf,KAAK+O,QAASR,GACxC,OAAO,EAST,GANIyQ,EAAOI,SAET7Q,EAAMvI,iBACNuI,EAAMhD,oBAGHyT,EAAO/b,IACV,OAAO,EAMT,IAAKjD,KAAKuQ,iBAAiB8O,WAAarf,KAAKuQ,iBAAiB+O,mBAAqB/Q,EAAMtL,MAAQsL,EAAMgR,UAAYhR,EAAMsQ,SAAWtQ,EAAMiR,SAAgC,IAArBjR,EAAMtL,IAAI1B,QACzJgN,EAAMtL,IAAIwc,WAAW,IAAM,IAAMlR,EAAMtL,IAAIwc,WAAW,IAAM,GAC9D,OAAO,EAIX,GAAIzf,KAAKmP,oBAEP,OADAnP,KAAKmP,qBAAsB,GACpB,EAMK,MAAV6P,EAAO/b,KAA4B,OAAV+b,EAAO/b,MAClCjD,KAAKkK,SAAUO,MAAQ,IAGzB,MAAMiV,EAAkB1f,KAAKuQ,iBAAiB+O,mBAAqBK,EAAwBpR,GAS3F,GARAvO,KAAKwP,OAAOyB,KAAK,CAAEhO,IAAK+b,EAAO/b,IAAK2c,SAAUrR,IAC9CvO,KAAK8T,cACL9T,KAAKmK,YAAYK,iBAAiBwU,EAAO/b,KAAMyc,IAM1C1f,KAAKoK,eAAeE,WAAWmR,kBAAoBlN,EAAMsQ,QAAUtQ,EAAMgR,QAG5E,OAFAhR,EAAMvI,iBACNuI,EAAMhD,mBACC,EAGTvL,KAAKgP,iBAAkB,CACzB,CAEQ,kBAAAmQ,CAAmBpQ,EAAmBpE,GAC5C,MAAMkV,EACH9Q,EAAQ4P,QAAU3e,KAAKkJ,QAAQ0V,iBAAmBjU,EAAGkU,SAAWlU,EAAG4U,UAAY5U,EAAG6U,SAClFzQ,EAAQ+Q,WAAanV,EAAGkU,QAAUlU,EAAG4U,UAAY5U,EAAG6U,SACpDzQ,EAAQ+Q,WAAanV,EAAGoV,iBAAiB,YAE5C,MAAgB,aAAZpV,EAAG6G,KACEqO,EAIFA,KAAmBlV,EAAGqV,SAAWrV,EAAGqV,QAAU,GACvD,CAEU,MAAAhK,CAAOrL,GAGf,GAFA3K,KAAKiP,cAAe,EAEhBjP,KAAKgS,yBAA8D,IAApChS,KAAKgS,uBAAuBrH,GAC7D,OAGGgV,EAAwBhV,IAC3B3K,KAAK+F,QAIP,MAAMiZ,EAAShf,KAAKuQ,iBAAiB0P,cAActV,GACnD,GAAIqU,GAAQ/b,IAAK,CACf,MAAMyc,EAAkB1f,KAAKuQ,iBAAiB+O,mBAAqBK,EAAwBhV,GAC3F3K,KAAKmK,YAAYK,iBAAiBwU,EAAO/b,KAAMyc,EACjD,CAEA1f,KAAK6X,kBAAkBlN,GACvB3K,KAAKkP,kBAAmB,CAC1B,CAQU,SAAAgH,CAAUvL,GAClB,IAAI1H,EAIJ,GAFAjD,KAAKkP,kBAAmB,EAEpBlP,KAAKgP,gBACP,OAAO,EAGT,GAAIhP,KAAKgS,yBAA8D,IAApChS,KAAKgS,uBAAuBrH,GAC7D,OAAO,EAGT,GAAIA,EAAGuV,SACLjd,EAAM0H,EAAGuV,cACJ,GAAiB,OAAbvV,EAAGwV,YAA+Bvb,IAAb+F,EAAGwV,MACjCld,EAAM0H,EAAGqV,YACJ,IAAiB,IAAbrV,EAAGwV,OAA+B,IAAhBxV,EAAGuV,SAG9B,OAAO,EAFPjd,EAAM0H,EAAGwV,KAGX,CAEA,SAAKld,IACF0H,EAAGkU,QAAUlU,EAAG4U,SAAW5U,EAAG6U,WAAaxf,KAAKmf,mBAAmBnf,KAAK+O,QAASpE,KAKpF1H,EAAMmd,OAAOC,aAAapd,GAE1BjD,KAAKwP,OAAOyB,KAAK,CAAEhO,MAAK2c,SAAUjV,IAClC3K,KAAK8T,cACA9T,KAAKiU,mBAAoBqM,WAAWrd,IACvCjD,KAAKmK,YAAYK,iBAAiBvH,GAAK,GAGzCjD,KAAKkP,kBAAmB,EAIxBlP,KAAKmP,qBAAsB,EAEpB,GACT,CAQU,WAAAuH,CAAY/L,GACpB,GACEA,EAAGsS,MACc,eAAjBtS,EAAG4V,YACFvgB,KAAKoK,eAAeE,WAAWmR,kBAChCzb,KAAKiU,8BAA8BtH,EAAAuH,mBACnClU,KAAKiU,mBAAmBuM,MAAM7V,EAAGsS,MAEjC,OAAO,EAKT,GAAItS,EAAGsS,MAAyB,eAAjBtS,EAAG4V,aAAgC5V,EAAG8V,WAAazgB,KAAKiP,gBAAkBjP,KAAKoK,eAAeE,WAAWmR,iBAAkB,CACxI,GAAIzb,KAAKkP,iBACP,OAAO,EAKTlP,KAAKmP,qBAAsB,EAE3B,MAAMtF,EAAOc,EAAGsS,KAEhB,OADAjd,KAAKmK,YAAYK,iBAAiBX,GAAM,IACjC,CACT,CAEA,OAAO,CACT,CAQO,MAAAsP,CAAOtE,EAAWV,GACnBU,IAAM7U,KAAKiI,MAAQkM,IAAMnU,KAAKe,KAQlChB,MAAMoZ,OAAOtE,EAAGV,GANVnU,KAAKqY,mBAAqBrY,KAAKqY,iBAAiBqI,cAClD1gB,KAAKqY,iBAAiB2D,SAM5B,CAEQ,YAAAjK,CAAa8C,EAAWV,GAC9BnU,KAAKqY,kBAAkB2D,SACzB,CAKO,KAAA3P,GACLrM,KAAKmE,OAAOwc,kBACZ3gB,KAAKmE,OAAOE,MAAMS,IAAI,EAAG9E,KAAKmE,OAAOE,MAAMP,IAAI9D,KAAKmE,OAAOqQ,MAAQxU,KAAKmE,OAAOgQ,IAC/EnU,KAAKmE,OAAOE,MAAM9C,OAAS,EAC3BvB,KAAKmE,OAAOK,MAAQ,EACpBxE,KAAKmE,OAAOqQ,MAAQ,EACpBxU,KAAKmE,OAAOgQ,EAAI,EAChB,IAAK,IAAIrV,EAAI,EAAGA,EAAIkB,KAAKe,KAAMjC,IAC7BkB,KAAKmE,OAAOE,MAAMJ,KAAKjE,KAAKmE,OAAOyc,aAAalT,EAAAmT,oBAIlD7gB,KAAKgb,UAAU/J,KAAK,CAAEhM,SAAUjF,KAAKmE,OAAOK,QAC5CxE,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,EAC9B,CAUO,KAAAuQ,GAKLtR,KAAKkJ,QAAQnI,KAAOf,KAAKe,KACzBf,KAAKkJ,QAAQjB,KAAOjI,KAAKiI,KACzB,MAAMkV,EAAwBnd,KAAKgS,uBAEnChS,KAAKgQ,SACLjQ,MAAMuR,QACNtR,KAAKsa,eAAehJ,QACpBtR,KAAKwV,mBAAmBlE,QACxBtR,KAAKiQ,mBAAmBqB,QAGxBtR,KAAKgS,uBAAyBmL,EAG9Bnd,KAAKkE,QAAQ,EAAGlE,KAAKe,KAAO,GAAG,EACjC,CAEO,iBAAA+f,GACL9gB,KAAKF,gBAAgBghB,mBACvB,CAEQ,YAAA1P,GACFpR,KAAK8B,SAASpB,UAAU2F,SAAS,SACnCrG,KAAKmK,YAAYK,iBAAiB,OAElCxK,KAAKmK,YAAYK,iBAAiB,MAEtC,CAEQ,qBAAAiH,CAAsBD,GAC5B,GAAKxR,KAAKF,eAIV,OAAQ0R,GACN,KAAK3D,EAAAkT,yBAAyBC,oBAC5B,MAAMC,EAAcjhB,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOD,MAAMmY,QAAQ,GACtEC,EAAenhB,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOL,OAAOuY,QAAQ,GAC9ElhB,KAAKmK,YAAYK,iBAAiB,OAAe2W,KAAgBF,MACjE,MACF,KAAKpT,EAAAkT,yBAAyBK,qBAC5B,MAAMpM,EAAYhV,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAAMmY,QAAQ,GAClEpM,EAAa9U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAAOuY,QAAQ,GAC1ElhB,KAAKmK,YAAYK,iBAAiB,OAAesK,KAAcE,MAGrE,EAQF,SAAS2K,EAAwBhV,GAC/B,OAAsB,KAAfA,EAAGqV,SACO,KAAfrV,EAAGqV,SACY,KAAfrV,EAAGqV,SACY,KAAfrV,EAAGqV,SACY,KAAfrV,EAAGqV,SACY,KAAfrV,EAAGqV,SACY,MAAfrV,EAAGqV,SACQ,SAAXrV,EAAG1H,GACP,wMCpnCA,SAA8C2D,EAAmB4K,EAAciM,EAA+B4D,GAC5G,OAAO/d,EAAsBsD,EAAM4K,EAAMiM,EAAS4D,EACpD,2BAoBA,SAAuCC,GACrC,MAAMC,EAAKD,EAAQlY,wBACboY,EAAMC,EAAUH,GACtB,MAAO,CACLxW,KAAMyW,EAAGzW,KAAO0W,EAAIE,QACpB1W,IAAKuW,EAAGvW,IAAMwW,EAAIG,QAClB5Y,MAAOwY,EAAGxY,MACVJ,OAAQ4Y,EAAG5Y,OAEf,iCAmEA,SAA6CiZ,EAAsBC,EAAoBC,EAAmB,GACxG,MAAMC,EAAQC,EAAuBJ,GAC/BK,EAAO,IAAIC,EAAwBL,EAAQC,GAQjD,OAPAC,EAAMI,KAAKle,KAAKge,GAEXF,EAAMK,qBACTL,EAAMK,oBAAqB,EAC3BR,EAAaS,sBAAsB,IAvBvC,SAA8BT,GAC5B,MAAMG,EAAQC,EAAuBJ,GAOrC,IANAG,EAAMK,oBAAqB,EAE3BL,EAAMO,QAAUP,EAAMI,KACtBJ,EAAMI,KAAO,GAEbJ,EAAMQ,wBAAyB,EACxBR,EAAMO,QAAQ/gB,OAAS,GAC5BwgB,EAAMO,QAAQE,KAAKN,EAAwBM,MAC/BT,EAAMO,QAAQ3e,QACtB8e,UAENV,EAAMQ,wBAAyB,CACjC,CAS6CG,CAAqBd,KAGzDK,CACT,EA7JA,MAAAU,EAAAzjB,EAAA,MAGA,SAAAuiB,EAA0BtgB,GACxB,MAAMyhB,EAAgBzhB,EACtB,GAAIyhB,GAAe5L,eAAeC,YAChC,OAAO2L,EAAc5L,cAAcC,YAGrC,MAAM4L,EAAiB1hB,EACvB,OAAI0hB,GAAgBC,KACXD,EAAeC,KAGjB5L,MACT,CAEA,MAAM6L,EAMJ,WAAArjB,CAAYkH,EAAmB4K,EAAciM,EAA2BvU,GACtElJ,KAAKgjB,MAAQpc,EACb5G,KAAKijB,MAAQzR,EACbxR,KAAKkjB,SAAWzF,EAChBzd,KAAKmjB,SAAWja,EAChBtC,EAAKtF,iBAAiBkQ,EAAMiM,EAASvU,EACvC,CAEO,OAAAmQ,GACArZ,KAAKgjB,OAAUhjB,KAAKkjB,WAGzBljB,KAAKgjB,MAAMrd,oBAAoB3F,KAAKijB,MAAOjjB,KAAKkjB,SAAUljB,KAAKmjB,UAC/DnjB,KAAKgjB,MAAQ,KACbhjB,KAAKkjB,SAAW,KAClB,EAMF,SAAA5f,EAAsCsD,EAAmB4K,EAAciM,EAA+B2F,GACpG,OAAO,IAAIL,EAAYnc,EAAM4K,EAAMiM,EAAS2F,EAC9C,CAMa3kB,EAAA4kB,UAAY,CACvBC,MAAO,QACPC,WAAY,YACZC,WAAY,YACZC,YAAa,aACbC,SAAU,UACVC,OAAQ,QACRC,MAAO,QACPC,KAAM,OACNC,MAAO,QACPC,OAAQ,SACRC,aAAc,cACdC,aAAc,cACdC,WAAY,YACZC,YAAa,QACbC,MAAO,SAcT,MAAMlC,EAGJ,WAAAxiB,CAA6B2kB,EAA4BvC,GAA5B9hB,KAAAqkB,QAAAA,EAA4BrkB,KAAA8hB,SAAAA,EAFjD9hB,KAAAskB,WAAY,CAGpB,CAEO,OAAAjL,GACLrZ,KAAKskB,WAAY,CACnB,CAEO,OAAA7B,GACL,IAAIziB,KAAKskB,UAGT,IACEtkB,KAAKqkB,SACP,CAAE,MAAOljB,GACPsF,QAAQC,MAAMvF,EAChB,CACF,CAEO,WAAOqhB,CAAK3jB,EAA4B0lB,GAC7C,OAAOA,EAAEzC,SAAWjjB,EAAEijB,QACxB,EAUF,MAAM0C,EAAsB,IAAIC,IAEhC,SAASzC,EAAuBJ,GAC9B,IAAIG,EAAQyC,EAAoB1gB,IAAI8d,GAUpC,OATKG,IACHA,EAAQ,CACNI,KAAM,GACNG,QAAS,GACTF,oBAAoB,EACpBG,wBAAwB,GAE1BiC,EAAoB1f,IAAI8c,EAAcG,IAEjCA,CACT,CA+BA,MAAA2C,UAAyC/B,EAAAgC,cAGvC,WAAAjlB,CAAYkH,GACV7G,QACAC,KAAK4kB,eAAiBhe,EAAO6a,EAAU7a,QAAQhC,CACjD,CAEO,YAAAigB,CAAahD,EAAoBiD,EAAkBlD,GACxD7hB,MAAM8kB,aAAahD,EAAQiD,EAAUlD,GAAgB5hB,KAAK4kB,gBAAkB1N,OAC9E,ghBC1KF,MAAA9X,EAAAF,EAAA,MAEAG,EAAAH,EAAA,MACAI,EAAAJ,EAAA,MACA8O,EAAA9O,EAAA,MACAK,EAAAL,EAAA,MAEO,IAAMua,EAAN,cAAwBra,EAAAK,WAC7B,eAAWslB,GAA4C,OAAO/kB,KAAKglB,YAAc,CAgBjF,WAAAtlB,CACmBulB,EACqB3L,EACLxZ,EACAgS,EACMpB,GAEvC3Q,QANiBC,KAAAilB,SAAAA,EACqBjlB,KAAAsZ,oBAAAA,EACLtZ,KAAAF,eAAAA,EACAE,KAAA8R,eAAAA,EACM9R,KAAA0Q,qBAAAA,EAjBjC1Q,KAAAklB,sBAAuC,GAEvCllB,KAAAmlB,aAAuB,EACvBnlB,KAAAolB,aAAuB,EAEvBplB,KAAAqlB,aAAuB,EAEdrlB,KAAAslB,qBAAuBtlB,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC3CtP,KAAAulB,oBAAsBvlB,KAAKslB,qBAAqB/W,MAC/CvO,KAAAwlB,qBAAuBxlB,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC3CtP,KAAAylB,oBAAsBzlB,KAAKwlB,qBAAqBjX,MAU9DvO,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,MAC1B,EAAArE,EAAAia,SAAQrZ,KAAKklB,uBACbllB,KAAKklB,sBAAsB3jB,OAAS,EACpCvB,KAAK0lB,qBAAkB9gB,EAEvB5E,KAAK2lB,wBAAwBtZ,WAG/BrM,KAAK0B,UAAU1B,KAAK8R,eAAe7P,SAAS,KAC1CjC,KAAK4lB,oBACL5lB,KAAKolB,aAAc,KAErBplB,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKilB,SAAU,aAAc,KAChEjlB,KAAKmlB,aAAc,EACnBnlB,KAAK4lB,uBAEP5lB,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKilB,SAAU,YAAajlB,KAAK6lB,iBAAiBhkB,KAAK7B,QAC5FA,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKilB,SAAU,YAAajlB,KAAK8lB,iBAAiBjkB,KAAK7B,QAC5FA,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKilB,SAAU,UAAWjlB,KAAK+lB,eAAelkB,KAAK7B,OAC1F,CAEQ,gBAAA6lB,CAAiBtX,GACvBvO,KAAK0lB,gBAAkBnX,EAEvB,MAAMtJ,EAAWjF,KAAKgmB,wBAAwBzX,EAAOvO,KAAKilB,UAC1D,IAAKhgB,EACH,OAEFjF,KAAKmlB,aAAc,EAGnB,MAAMc,EAAe1X,EAAM0X,eAC3B,IAAK,IAAInnB,EAAI,EAAGA,EAAImnB,EAAa1kB,OAAQzC,IAAK,CAC5C,MAAMqG,EAAS8gB,EAAannB,GAE5B,GAAIqG,EAAOzE,UAAU2F,SAAS,SAC5B,MAGF,GAAIlB,EAAOzE,UAAU2F,SAAS,eAC5B,MAEJ,CAEKrG,KAAKkmB,iBAAoBjhB,EAAS4P,IAAM7U,KAAKkmB,gBAAgBrR,GAAK5P,EAASkP,IAAMnU,KAAKkmB,gBAAgB/R,IACzGnU,KAAKmmB,aAAalhB,GAClBjF,KAAKkmB,gBAAkBjhB,EAE3B,CAEQ,YAAAkhB,CAAalhB,GAInB,GAAIjF,KAAKqlB,cAAgBpgB,EAASkP,GAAKnU,KAAKolB,YAI1C,OAHAplB,KAAK4lB,oBACL5lB,KAAKomB,YAAYnhB,GAAU,QAC3BjF,KAAKolB,aAAc,GAKWplB,KAAKglB,cAAgBhlB,KAAKqmB,gBAAgBrmB,KAAKglB,aAAasB,KAAMrhB,KAEhGjF,KAAK4lB,oBACL5lB,KAAKomB,YAAYnhB,GAAU,GAE/B,CAEQ,WAAAmhB,CAAYnhB,EAA+BshB,GAC5CvmB,KAAK2lB,wBAA2BY,IACnCvmB,KAAK2lB,wBAAwBa,QAAQC,IACnCA,GAAOD,QAAQE,IACTA,EAAcJ,KAAKjN,SACrBqN,EAAcJ,KAAKjN,cAIzBrZ,KAAK2lB,uBAAyB,IAAIlB,IAClCzkB,KAAKqlB,YAAcpgB,EAASkP,GAE9B,IAAIwS,GAAe,EAGnB,IAAK,MAAO7nB,EAAGye,KAAiBvd,KAAK0Q,qBAAqBkW,cAAcC,UACtE,GAAIN,EAAc,CAChB,MAAMO,EAAgB9mB,KAAK2lB,wBAAwB7hB,IAAIhF,GAMnDgoB,IACFH,EAAe3mB,KAAK+mB,yBAAyBjoB,EAAGmG,EAAU0hB,GAE9D,MACEpJ,EAAayJ,aAAa/hB,EAASkP,EAAI8S,IACrC,GAAIjnB,KAAKmlB,YACP,OAEF,MAAM+B,EAA+CD,GAAOE,IAAIb,IAAS,CAAGA,UAC5EtmB,KAAK2lB,wBAAwB7gB,IAAIhG,EAAGooB,GACpCP,EAAe3mB,KAAK+mB,yBAAyBjoB,EAAGmG,EAAU0hB,GAItD3mB,KAAK2lB,wBAAwByB,OAASpnB,KAAK0Q,qBAAqBkW,cAAcrlB,QAChFvB,KAAKqnB,yBAAyBpiB,EAASkP,EAAGnU,KAAK2lB,yBAKzD,CAEQ,wBAAA0B,CAAyBlT,EAAWmT,GAC1C,MAAMC,EAAgB,IAAIC,IAC1B,IAAK,IAAI1oB,EAAI,EAAGA,EAAIwoB,EAAQF,KAAMtoB,IAAK,CACrC,MAAM2oB,EAAgBH,EAAQxjB,IAAIhF,GAClC,GAAK2oB,EAGL,IAAK,IAAI3oB,EAAI,EAAGA,EAAI2oB,EAAclmB,OAAQzC,IAAK,CAC7C,MAAM4nB,EAAgBe,EAAc3oB,GAC9B4oB,EAAShB,EAAcJ,KAAKqB,MAAMtlB,MAAM8R,EAAIA,EAAI,EAAIuS,EAAcJ,KAAKqB,MAAMtlB,MAAMwS,EACnF+S,EAAOlB,EAAcJ,KAAKqB,MAAMrlB,IAAI6R,EAAIA,EAAInU,KAAK8R,eAAe7J,KAAOye,EAAcJ,KAAKqB,MAAMrlB,IAAIuS,EAC1G,IAAK,IAAIA,EAAI6S,EAAQ7S,GAAK+S,EAAM/S,IAAK,CACnC,GAAI0S,EAAcM,IAAIhT,GAAI,CACxB4S,EAAcK,OAAOhpB,IAAK,GAC1B,KACF,CACAyoB,EAAc5mB,IAAIkU,EACpB,CACF,CACF,CACF,CAEQ,wBAAAkS,CAAyB1U,EAAepN,EAA+B0hB,GAC7E,IAAK3mB,KAAK2lB,uBACR,OAAOgB,EAGT,MAAMM,EAAQjnB,KAAK2lB,uBAAuB7hB,IAAIuO,GAG9C,IAAI0V,GAAgB,EACpB,IAAK,IAAIC,EAAI,EAAGA,EAAI3V,EAAO2V,IACpBhoB,KAAK2lB,uBAAuBkC,IAAIG,KAAMhoB,KAAK2lB,uBAAuB7hB,IAAIkkB,KACzED,GAAgB,GAMpB,IAAKA,GAAiBd,EAAO,CAC3B,MAAMgB,EAAiBhB,EAAMiB,KAAK5B,GAAQtmB,KAAKqmB,gBAAgBC,EAAKA,KAAMrhB,IACtEgjB,IACFtB,GAAe,EACf3mB,KAAKmoB,eAAeF,GAExB,CAGA,GAAIjoB,KAAK2lB,uBAAuByB,OAASpnB,KAAK0Q,qBAAqBkW,cAAcrlB,SAAWolB,EAE1F,IAAK,IAAIqB,EAAI,EAAGA,EAAIhoB,KAAK2lB,uBAAuByB,KAAMY,IAAK,CACzD,MAAMjD,EAAc/kB,KAAK2lB,uBAAuB7hB,IAAIkkB,IAAIE,KAAK5B,GAAQtmB,KAAKqmB,gBAAgBC,EAAKA,KAAMrhB,IACrG,GAAI8f,EAAa,CACf4B,GAAe,EACf3mB,KAAKmoB,eAAepD,GACpB,KACF,CACF,CAGF,OAAO4B,CACT,CAEQ,gBAAAb,GACN9lB,KAAKooB,eAAiBpoB,KAAKglB,YAC7B,CAEQ,cAAAe,CAAexX,GACrB,IAAKvO,KAAKglB,aACR,OAGF,MAAM/f,EAAWjF,KAAKgmB,wBAAwBzX,EAAOvO,KAAKilB,UA0K9D,IAAoBpmB,EAAU0lB,EAzKrBtf,GAIDjF,KAAKooB,iBAqKOvpB,EArKsBmB,KAAKooB,eAAe9B,KAqKhC/B,EArKsCvkB,KAAKglB,aAAasB,KAuKlFznB,EAAEgL,OAAS0a,EAAE1a,MACbhL,EAAE8oB,MAAMtlB,MAAMwS,IAAM0P,EAAEoD,MAAMtlB,MAAMwS,GAClChW,EAAE8oB,MAAMtlB,MAAM8R,IAAMoQ,EAAEoD,MAAMtlB,MAAM8R,GAClCtV,EAAE8oB,MAAMrlB,IAAIuS,IAAM0P,EAAEoD,MAAMrlB,IAAIuS,GAC9BhW,EAAE8oB,MAAMrlB,IAAI6R,IAAMoQ,EAAEoD,MAAMrlB,IAAI6R,IA3K6DnU,KAAKqmB,gBAAgBrmB,KAAKglB,aAAasB,KAAMrhB,IACtIjF,KAAKglB,aAAasB,KAAK+B,SAAS9Z,EAAOvO,KAAKglB,aAAasB,KAAKzc,KAElE,CAEQ,iBAAA+b,CAAkB0C,EAAmBC,GACtCvoB,KAAKglB,cAAiBhlB,KAAK0lB,mBAK3B4C,IAAaC,GAAWvoB,KAAKglB,aAAasB,KAAKqB,MAAMtlB,MAAM8R,GAAKmU,GAAYtoB,KAAKglB,aAAasB,KAAKqB,MAAMrlB,IAAI6R,GAAKoU,KACrHvoB,KAAKwoB,WAAWxoB,KAAKilB,SAAUjlB,KAAKglB,aAAasB,KAAMtmB,KAAK0lB,iBAC5D1lB,KAAKglB,kBAAepgB,GACpB,EAAAxF,EAAAia,SAAQrZ,KAAKklB,uBACbllB,KAAKklB,sBAAsB3jB,OAAS,EAExC,CAEQ,cAAA4mB,CAAezB,GACrB,IAAK1mB,KAAK0lB,gBACR,OAGF,MAAMzgB,EAAWjF,KAAKgmB,wBAAwBhmB,KAAK0lB,gBAAiB1lB,KAAKilB,UAEpEhgB,GAKDjF,KAAKqmB,gBAAgBK,EAAcJ,KAAMrhB,KAC3CjF,KAAKglB,aAAe0B,EACpB1mB,KAAKglB,aAAajD,MAAQ,CACxB0G,YAAa,CACXC,eAA8C9jB,IAAnC8hB,EAAcJ,KAAKmC,aAAmC/B,EAAcJ,KAAKmC,YAAYC,UAChGC,mBAAkD/jB,IAAnC8hB,EAAcJ,KAAKmC,aAAmC/B,EAAcJ,KAAKmC,YAAYE,eAEtGC,WAAW,GAEb5oB,KAAK6oB,WAAW7oB,KAAKilB,SAAUyB,EAAcJ,KAAMtmB,KAAK0lB,iBAGxDgB,EAAcJ,KAAKmC,YAAc,GACjC7f,OAAOkgB,iBAAiBpC,EAAcJ,KAAKmC,YAAa,CACtDE,cAAe,CACb7kB,IAAK,IAAM9D,KAAKglB,cAAcjD,OAAO0G,YAAYE,cACjD7jB,IAAKikB,IACC/oB,KAAKglB,cAAcjD,OAAS/hB,KAAKglB,aAAajD,MAAM0G,YAAYE,gBAAkBI,IACpF/oB,KAAKglB,aAAajD,MAAM0G,YAAYE,cAAgBI,EAChD/oB,KAAKglB,aAAajD,MAAM6G,WAC1B5oB,KAAKilB,SAASvkB,UAAU6W,OAAO,uBAAwBwR,MAK/DL,UAAW,CACT5kB,IAAK,IAAM9D,KAAKglB,cAAcjD,OAAO0G,YAAYC,UACjD5jB,IAAKikB,IACC/oB,KAAKglB,cAAcjD,OAAS/hB,KAAKglB,cAAcjD,OAAO0G,YAAYC,YAAcK,IAClF/oB,KAAKglB,aAAajD,MAAM0G,YAAYC,UAAYK,EAC5C/oB,KAAKglB,aAAajD,MAAM6G,WAC1B5oB,KAAKgpB,oBAAoBtC,EAAcJ,KAAMyC,QASvD/oB,KAAKklB,sBAAsBjhB,KAAKjE,KAAKF,eAAemZ,yBAAyB9X,IAE3E,IAAKnB,KAAKglB,aACR,OAIF,MAAM3iB,EAAoB,IAAZlB,EAAEkB,MAAc,EAAIlB,EAAEkB,MAAQ,EAAIrC,KAAK8R,eAAe3N,OAAOK,MACrElC,EAAMtC,KAAK8R,eAAe3N,OAAOK,MAAQ,EAAIrD,EAAEmB,IAErD,GAAItC,KAAKglB,aAAasB,KAAKqB,MAAMtlB,MAAM8R,GAAK9R,GAASrC,KAAKglB,aAAasB,KAAKqB,MAAMrlB,IAAI6R,GAAK7R,IACzFtC,KAAK4lB,kBAAkBvjB,EAAOC,GAC1BtC,KAAK0lB,iBAAiB,CAExB,MAAMzgB,EAAWjF,KAAKgmB,wBAAwBhmB,KAAK0lB,gBAAiB1lB,KAAKilB,UACrEhgB,GACFjF,KAAKomB,YAAYnhB,GAAU,EAE/B,KAIR,CAEU,UAAA4jB,CAAW/mB,EAAsBwkB,EAAa/X,GAClDvO,KAAKglB,cAAcjD,QACrB/hB,KAAKglB,aAAajD,MAAM6G,WAAY,EAChC5oB,KAAKglB,aAAajD,MAAM0G,YAAYC,WACtC1oB,KAAKgpB,oBAAoB1C,GAAM,GAE7BtmB,KAAKglB,aAAajD,MAAM0G,YAAYE,eACtC7mB,EAAQpB,UAAUC,IAAI,yBAItB2lB,EAAK2C,OACP3C,EAAK2C,MAAM1a,EAAO+X,EAAKzc,KAE3B,CAEQ,mBAAAmf,CAAoB1C,EAAa4C,GACvC,MAAMvB,EAAQrB,EAAKqB,MACbwB,EAAenpB,KAAK8R,eAAe3N,OAAOK,MAC1C+J,EAAQvO,KAAKopB,0BAA0BzB,EAAMtlB,MAAMwS,EAAI,EAAG8S,EAAMtlB,MAAM8R,EAAIgV,EAAe,EAAGxB,EAAMrlB,IAAIuS,EAAG8S,EAAMrlB,IAAI6R,EAAIgV,EAAe,OAAGvkB,IAC/HskB,EAAYlpB,KAAKslB,qBAAuBtlB,KAAKwlB,sBACrDvU,KAAK1C,EACf,CAEU,UAAAia,CAAW1mB,EAAsBwkB,EAAa/X,GAClDvO,KAAKglB,cAAcjD,QACrB/hB,KAAKglB,aAAajD,MAAM6G,WAAY,EAChC5oB,KAAKglB,aAAajD,MAAM0G,YAAYC,WACtC1oB,KAAKgpB,oBAAoB1C,GAAM,GAE7BtmB,KAAKglB,aAAajD,MAAM0G,YAAYE,eACtC7mB,EAAQpB,UAAUgD,OAAO,yBAIzB4iB,EAAK+C,OACP/C,EAAK+C,MAAM9a,EAAO+X,EAAKzc,KAE3B,CAOQ,eAAAwc,CAAgBC,EAAarhB,GACnC,MAAMqkB,EAAQhD,EAAKqB,MAAMtlB,MAAM8R,EAAInU,KAAK8R,eAAe7J,KAAOqe,EAAKqB,MAAMtlB,MAAMwS,EACzE0U,EAAQjD,EAAKqB,MAAMrlB,IAAI6R,EAAInU,KAAK8R,eAAe7J,KAAOqe,EAAKqB,MAAMrlB,IAAIuS,EACrEyN,EAAUrd,EAASkP,EAAInU,KAAK8R,eAAe7J,KAAOhD,EAAS4P,EACjE,OAAQyU,GAAShH,GAAWA,GAAWiH,CACzC,CAMQ,uBAAAvD,CAAwBzX,EAAmBzM,GACjD,MAAM0nB,EAASxpB,KAAKsZ,oBAAoBmQ,UAAUlb,EAAOzM,EAAS9B,KAAK8R,eAAe7J,KAAMjI,KAAK8R,eAAe/Q,MAChH,GAAKyoB,EAIL,MAAO,CAAE3U,EAAG2U,EAAO,GAAIrV,EAAGqV,EAAO,GAAKxpB,KAAK8R,eAAe3N,OAAOK,MACnE,CAEQ,yBAAA4kB,CAA0BM,EAAYC,EAAYC,EAAYC,EAAY5d,GAChF,MAAO,CAAEyd,KAAIC,KAAIC,KAAIC,KAAI5hB,KAAMjI,KAAK8R,eAAe7J,KAAMgE,KAC3D,6BA1XWwN,EAASlQ,EAAA,CAmBjBC,EAAA,EAAAlK,EAAAka,qBACAhQ,EAAA,EAAAlK,EAAAqK,gBACAH,EAAA,EAAAnK,EAAAyqB,gBACAtgB,EAAA,EAAAlK,EAAAsR,uBAtBQ6I,oGCNb,IAAIsQ,EAAsB,iBAC1B,MAAMhS,EAAc,CAClBjU,IAAK,IAAMimB,EACXjlB,IAAM2F,GAAkBsf,EAAsBtf,iBAUnCsN,EAPb,IAAIiS,EAAwB,iEAC5B,MAAMnmB,EAAgB,CACpBC,IAAK,IAAMkmB,EACXllB,IAAM2F,GAAkBuf,EAAwBvf,mBAKnC5G,8fCdf,MAAAomB,EAAA/qB,EAAA,MAEAG,EAAAH,EAAA,MAEO,IAAM4R,EAAN,MAGL,WAAApR,CACmCoS,EACCoY,EACAC,GAFDnqB,KAAA8R,eAAAA,EACC9R,KAAAkqB,gBAAAA,EACAlqB,KAAAmqB,gBAAAA,EALnBnqB,KAAAoqB,UAAY,IAAIH,EAAAI,QAOjC,CAEO,YAAArD,CAAa7S,EAAWmW,GAC7B,MAAM/lB,EAAOvE,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAIqQ,EAAI,GACtD,IAAK5P,EAEH,YADA+lB,OAAS1lB,GAIX,MAAMoa,EAAkB,GAClBuL,EAAcvqB,KAAKkqB,gBAAgB5f,WAAWigB,YAC9C7hB,EAAO1I,KAAKoqB,UACZI,EAAajmB,EAAKkmB,mBACxB,IAAIC,GAAiB,EACjBC,GAAgB,EAChBC,GAAa,EACjB,IAAK,IAAI/V,EAAI,EAAGA,EAAI2V,EAAY3V,IAG9B,IAAsB,IAAlB8V,GAAwBpmB,EAAKsmB,WAAWhW,GAA5C,CAKA,GADAtQ,EAAKumB,SAASjW,EAAGnM,GACbA,EAAKqiB,oBAAsBriB,EAAKsiB,SAASC,MAAO,CAClD,IAAsB,IAAlBN,EAAqB,CACvBA,EAAe9V,EACf6V,EAAgBhiB,EAAKsiB,SAASC,MAC9B,QACF,CACEL,EAAaliB,EAAKsiB,SAASC,QAAUP,CAEzC,MACwB,IAAlBC,IACFC,GAAa,GAIjB,GAAIA,IAAiC,IAAlBD,GAAuB9V,IAAM2V,EAAa,EAAI,CAC/D,MAAM3gB,EAAO7J,KAAKmqB,gBAAgBe,YAAYR,IAAgBS,IAC9D,GAAIthB,EAAM,CACR,MAAM+d,EAAO/S,GAAM+V,GAAc/V,IAAM2V,EAAa,EAAQ,EAAJ,GAClD7C,EAAQ3nB,KAAKorB,sBAAsBjX,EAAGwW,EAAc/C,EAAM8C,GAChE,IAAIW,GAAa,EACjB,IAAKd,GAAae,sBAChB,IACE,MAAMC,EAAS,IAAIC,IAAI3hB,GAClB,CAAC,QAAS,UAAU4hB,SAASF,EAAOG,YACvCL,GAAa,EAEjB,CAAE,MAEAA,GAAa,CACf,CAGGA,GAEHrM,EAAO/a,KAAK,CACV4F,OACA8d,QACAU,SAAU,CAAClnB,EAAG0I,IAAU0gB,EAAcA,EAAYlC,SAASlnB,EAAG0I,EAAM8d,GAASgE,EAAgBxqB,EAAG0I,GAChGof,MAAO,CAAC9nB,EAAG0I,IAAS0gB,GAAatB,QAAQ9nB,EAAG0I,EAAM8d,GAClD0B,MAAO,CAACloB,EAAG0I,IAAS0gB,GAAalB,QAAQloB,EAAG0I,EAAM8d,IAGxD,CACAiD,GAAa,EAGTliB,EAAKqiB,oBAAsBriB,EAAKsiB,SAASC,OAC3CN,EAAe9V,EACf6V,EAAgBhiB,EAAKsiB,SAASC,QAE9BN,GAAgB,EAChBD,GAAiB,EAErB,CAxDA,CA6DFJ,EAAStL,EACX,CAKQ,qBAAAoM,CAAsBjX,EAAWuT,EAAgBE,EAAcgE,GACrE,IAAIC,EAAS1X,EACT2X,EAAcpE,EACdqE,EAAO5X,EACP6X,EAAYpE,EAGhB,KAAuB,IAAhBkE,GAAmB,CACxB,MAAMG,EAAcjsB,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAI+nB,EAAS,GAClE,IAAKI,GAAaC,UAChB,MAEF,MAAMC,EAAensB,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAI+nB,EAAS,GACnE,IAAKM,EACH,MAEF,MAAMC,EAAqBD,EAAa1B,mBACxC,GAA2B,IAAvB2B,IAA6BpsB,KAAKqsB,UAAUF,EAAcC,EAAqB,EAAGR,GACpF,MAEF,IAAIU,EAAiBF,EAAqB,EAC1C,KAAOE,EAAiB,GAAKtsB,KAAKqsB,UAAUF,EAAcG,EAAiB,EAAGV,IAC5EU,IAEFT,IACAC,EAAcQ,CAChB,CAGA,OAAa,CACX,MAAML,EAAcjsB,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAIioB,EAAO,GAChE,IAAKE,EACH,MAGF,GAAID,IADsBC,EAAYxB,mBAEpC,MAEF,MAAM8B,EAAWvsB,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAIioB,GACtD,IAAKQ,GAAUL,UACb,MAEF,MAAMM,EAAiBD,EAAS9B,mBAChC,GAAuB,IAAnB+B,IAAyBxsB,KAAKqsB,UAAUE,EAAU,EAAGX,GACvD,MAEF,IAAIa,EAAW,EACf,KAAOA,EAAWD,GAAkBxsB,KAAKqsB,UAAUE,EAAUE,EAAUb,IACrEa,IAEFV,IACAC,EAAYS,CACd,CAGA,MAAO,CACLpqB,MAAO,CACLwS,EAAGiX,EAAc,EACjB3X,EAAG0X,GAELvpB,IAAK,CACHuS,EAAGmX,EACH7X,EAAG4X,GAGT,CAEQ,SAAAM,CAAU9nB,EAAmBsQ,EAAW+W,GAC9C,MAAMljB,EAAO1I,KAAKoqB,UAElB,OADA7lB,EAAKumB,SAASjW,EAAGnM,KACRA,EAAKqiB,oBAAsBriB,EAAKsiB,SAASC,QAAUW,CAC9D,GAGF,SAASD,EAAgBxqB,EAAegqB,GAEtC,GADeuB,QAAQ,8BAA8BvB,2DACzC,CACV,MAAMwB,EAAYzV,OAAOP,OACzB,GAAIgW,EAAW,CACb,IACEA,EAAUC,OAAS,IACrB,CAAE,MAEF,CACAD,EAAUE,SAASC,KAAO3B,CAC5B,MACE1kB,QAAQsB,KAAK,sDAEjB,CACF,uCAzLa+I,EAAevH,EAAA,CAIvBC,EAAA,EAAAnK,EAAAyqB,gBACAtgB,EAAA,EAAAnK,EAAA0tB,iBACAvjB,EAAA,EAAAnK,EAAA2tB,kBANQlc,0GCAb,MAOE,WAAApR,CACUutB,EACSptB,GADTG,KAAAitB,gBAAAA,EACSjtB,KAAAH,oBAAAA,EAJXG,KAAAktB,kBAA4C,EAMpD,CAEO,OAAA7T,QACwBzU,IAAzB5E,KAAKmtB,kBACPntB,KAAKH,oBAAoBqX,OAAOkW,qBAAqBptB,KAAKmtB,iBAC1DntB,KAAKmtB,qBAAkBvoB,EAE3B,CAEO,kBAAAyoB,CAAmB/C,GAGxB,OAFAtqB,KAAKktB,kBAAkBjpB,KAAKqmB,GAC5BtqB,KAAKmtB,kBAAoBntB,KAAKH,oBAAoBqX,OAAOmL,sBAAsB,IAAMriB,KAAKstB,iBACnFttB,KAAKmtB,eACd,CAEO,OAAAjpB,CAAQqpB,EAA8BC,EAA4BC,GACvEztB,KAAK0tB,UAAYD,EAEjBF,EAAWA,GAAY,EACvBC,EAASA,GAAUxtB,KAAK0tB,UAAY,EAEpC1tB,KAAK2tB,eAA+B/oB,IAAnB5E,KAAK2tB,UAA0BhZ,KAAKC,IAAI5U,KAAK2tB,UAAWJ,GAAYA,EACrFvtB,KAAK4tB,aAA2BhpB,IAAjB5E,KAAK4tB,QAAwBjZ,KAAKkZ,IAAI7tB,KAAK4tB,QAASJ,GAAUA,OAEhD5oB,IAAzB5E,KAAKmtB,kBAITntB,KAAKmtB,gBAAkBntB,KAAKH,oBAAoBqX,OAAOmL,sBAAsB,IAAMriB,KAAKstB,iBAC1F,CAEQ,aAAAA,GAIN,GAHAttB,KAAKmtB,qBAAkBvoB,OAGAA,IAAnB5E,KAAK2tB,gBAA4C/oB,IAAjB5E,KAAK4tB,cAA4ChpB,IAAnB5E,KAAK0tB,UAErE,YADA1tB,KAAK8tB,uBAKP,MAAMzrB,EAAQsS,KAAKkZ,IAAI7tB,KAAK2tB,UAAW,GACjCrrB,EAAMqS,KAAKC,IAAI5U,KAAK4tB,QAAS5tB,KAAK0tB,UAAY,GAGpD1tB,KAAK2tB,eAAY/oB,EACjB5E,KAAK4tB,aAAUhpB,EAGf5E,KAAKitB,gBAAgB5qB,EAAOC,GAC5BtC,KAAK8tB,sBACP,CAEQ,oBAAAA,GACN,IAAK,MAAMxD,KAAYtqB,KAAKktB,kBAC1B5C,EAAS,GAEXtqB,KAAKktB,kBAAoB,EAC3B,gHCpEF,MAYE,WAAAxtB,CACUutB,EACSc,EAnBgB,KAkBzB/tB,KAAAitB,gBAAAA,EACSjtB,KAAA+tB,qBAAAA,EARX/tB,KAAAguB,eAAiB,EAEjBhuB,KAAAiuB,6BAA8B,CAQtC,CAEO,OAAA5U,GACDrZ,KAAKkuB,oBACPC,aAAanuB,KAAKkuB,mBAClBluB,KAAKkuB,uBAAoBtpB,GAE3B5E,KAAKiuB,6BAA8B,CACrC,CAEO,OAAA/pB,CAAQqpB,EAA8BC,EAA4BC,GACvEztB,KAAK0tB,UAAYD,EAEjBF,EAAWA,GAAY,EACvBC,EAASA,GAAUxtB,KAAK0tB,UAAY,EAEpC1tB,KAAK2tB,eAA+B/oB,IAAnB5E,KAAK2tB,UAA0BhZ,KAAKC,IAAI5U,KAAK2tB,UAAWJ,GAAYA,EACrFvtB,KAAK4tB,aAA2BhpB,IAAjB5E,KAAK4tB,QAAwBjZ,KAAKkZ,IAAI7tB,KAAK4tB,QAASJ,GAAUA,EAI7E,MAAMY,EAA6BC,YAAYC,MAC/C,GAAIF,EAAqBpuB,KAAKguB,gBAAkBhuB,KAAK+tB,0BAEpBnpB,IAA3B5E,KAAKkuB,oBACPC,aAAanuB,KAAKkuB,mBAClBluB,KAAKkuB,uBAAoBtpB,EACzB5E,KAAKiuB,6BAA8B,GAErCjuB,KAAKguB,eAAiBI,EACtBpuB,KAAKstB,qBACA,IAAKttB,KAAKiuB,4BAA6B,CAE5C,MAAMM,EAAUH,EAAqBpuB,KAAKguB,eACpCQ,EAAkCxuB,KAAK+tB,qBAAuBQ,EACpEvuB,KAAKiuB,6BAA8B,EAEnCjuB,KAAKkuB,kBAAoBhX,OAAOuX,WAAW,KACzCzuB,KAAKguB,eAAiBK,YAAYC,MAClCtuB,KAAKstB,gBACLttB,KAAKiuB,6BAA8B,EACnCjuB,KAAKkuB,uBAAoBtpB,GACxB4pB,EACL,CACF,CAEQ,aAAAlB,GAEN,QAAuB1oB,IAAnB5E,KAAK2tB,gBAA4C/oB,IAAjB5E,KAAK4tB,cAA4ChpB,IAAnB5E,KAAK0tB,UACrE,OAIF,MAAMrrB,EAAQsS,KAAKkZ,IAAI7tB,KAAK2tB,UAAW,GACjCrrB,EAAMqS,KAAKC,IAAI5U,KAAK4tB,QAAS5tB,KAAK0tB,UAAY,GAGpD1tB,KAAK2tB,eAAY/oB,EACjB5E,KAAK4tB,aAAUhpB,EAGf5E,KAAKitB,gBAAgB5qB,EAAOC,EAC9B,8FCjFF,MAAAiL,EAAArO,EAAA,MA8KaT,EAAAiwB,oBAAsB9lB,OAAO+lB,OAAO,MAC/C,MAAMlc,EAAS,CAEblF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WAEZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,WACZvF,EAAA9E,IAAIqK,QAAQ,YAKRiW,EAAI,CAAC,EAAM,GAAM,IAAM,IAAM,IAAM,KACzC,IAAK,IAAIjqB,EAAI,EAAGA,EAAI,IAAKA,IAAK,CAC5B,MAAM8vB,EAAI7F,EAAGjqB,EAAI,GAAM,EAAI,GACrB+vB,EAAI9F,EAAGjqB,EAAI,EAAK,EAAI,GACpBylB,EAAIwE,EAAEjqB,EAAI,GAChB2T,EAAOxO,KAAK,CACVwE,IAAK8E,EAAAsF,SAASic,MAAMF,EAAGC,EAAGtK,GAC1BjR,KAAM/F,EAAAsF,SAASkc,OAAOH,EAAGC,EAAGtK,IAEhC,CAGA,IAAK,IAAIzlB,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,MAAMkwB,EAAI,EAAQ,GAAJlwB,EACd2T,EAAOxO,KAAK,CACVwE,IAAK8E,EAAAsF,SAASic,MAAME,EAAGA,EAAGA,GAC1B1b,KAAM/F,EAAAsF,SAASkc,OAAOC,EAAGA,EAAGA,IAEhC,CAEA,OAAOvc,CACR,EA7CgD,yfClLjD,MAAApT,EAAAH,EAAA,MAEAE,EAAAF,EAAA,MACAI,EAAAJ,EAAA,MAEAK,EAAAL,EAAA,MACA+vB,EAAA/vB,EAAA,MAEA8O,EAAA9O,EAAA,MACAgwB,EAAAhwB,EAAA,MAEO,IAAMgb,EAAN,cAAuB9a,EAAAK,WAe5B,WAAAC,CACEoC,EACA8I,EACiCkH,EACZqd,EACUC,EACXhU,EACLiU,EACmBnF,EACDpqB,GAEjCC,QARiCC,KAAA8R,eAAAA,EAEF9R,KAAAovB,aAAAA,EAGGpvB,KAAAkqB,gBAAAA,EACDlqB,KAAAF,eAAAA,EAtBzBE,KAAAsvB,sBAAwBtvB,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAAma,qBAAuBna,KAAKsvB,sBAAsB/gB,MAO1DvO,KAAAuvB,YAAsB,EACtBvvB,KAAAwvB,mBAA6B,EAC7BxvB,KAAAyvB,0BAAoC,EACpCzvB,KAAA0vB,oBAA8B,EAepC,MAAMC,EAAa3vB,KAAK0B,UAAU,IAAIwtB,EAAAU,WAAW,CAC/CC,oBAAoB,EACpBC,qBAAsB9vB,KAAKkqB,gBAAgB5f,WAAWwlB,qBAEtDC,6BAA8BC,IAAM,EAAAzwB,EAAAwwB,8BAA6BZ,EAAmBjY,OAAQ8Y,MAE9FhwB,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,uBAAwB,KACjFkY,EAAWM,wBAAwBjwB,KAAKkqB,gBAAgB5f,WAAWwlB,yBAGrE9vB,KAAKkwB,mBAAqBlwB,KAAK0B,UAAU,IAAIutB,EAAAkB,wBAAwBvlB,EAAe,CAClFwlB,SAAQ,EACRC,WAAU,EACVC,YAAY,EACZC,wBAAwB,EACxBC,kBAAmBxwB,KAAKkqB,gBAAgB5f,WAAWqR,WAAW8U,aAAc,KACzEzwB,KAAK0wB,qBACPf,IACH3vB,KAAK0B,UAAU1B,KAAKkqB,gBAAgByG,uBAAuB,CACzD,oBACA,wBACA,aACC,IAAM3wB,KAAKkwB,mBAAmBU,cAAc5wB,KAAK0wB,uBAEpD1wB,KAAK0B,UAAU0Z,EAAkByV,iBAAiBrf,IAChDxR,KAAKkwB,mBAAmBU,cAAc,CACpCE,mBAAwB,GAAJtf,QAIxBxR,KAAKkwB,mBAAmBa,oBAAoB,CAAEpoB,OAAQ,EAAGqoB,aAAc,IACvEhxB,KAAK0B,UAAUsM,EAAA4D,WAAWqf,gBAAgB5B,EAAa1W,eAAgB,KACrE7W,EAAQgH,MAAMooB,gBAAkB7B,EAAa5c,OAAOY,WAAW5K,IAC/DzI,KAAKkwB,mBAAmBiB,aAAaroB,MAAMooB,gBAAkB7B,EAAa5c,OAAOY,WAAW5K,OAE9F3G,EAAQb,YAAYjB,KAAKkwB,mBAAmBiB,cAC5CnxB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKkwB,mBAAmBiB,aAAaztB,WAEvE1D,KAAKoxB,cAAgBjC,EAAmB5uB,aAAaE,cAAc,SACnEmK,EAAc3J,YAAYjB,KAAKoxB,eAC/BpxB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKoxB,cAAc1tB,WACrD1D,KAAK0B,UAAUsM,EAAA4D,WAAWqf,gBAAgB5B,EAAa1W,eAAgB,KACrE3Y,KAAKoxB,cAAcxtB,YAAc,CAC/B,wEACA,iBAAiByrB,EAAa5c,OAAO4e,0BAA0B5oB,OAC/D,IACA,8EACA,iBAAiB4mB,EAAa5c,OAAO6e,+BAA+B7oB,OACpE,IACA,qFACA,iBAAiB4mB,EAAa5c,OAAO8e,gCAAgC9oB,OACrE,KACA+oB,KAAK,SAGTxxB,KAAK0B,UAAU1B,KAAK8R,eAAe7P,SAAS,IAAMjC,KAAKib,cACvDjb,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiB,KAG1DzxB,KAAK0xB,kBAAe9sB,EACpB5E,KAAKib,eAEPjb,KAAK0B,UAAU1B,KAAK8R,eAAevP,SAAS,IAAMvC,KAAK2xB,UAKvD3xB,KAAK0B,UAAU1B,KAAKF,eAAeqC,SAAS,KACtCnC,KAAK0vB,qBACP1vB,KAAK0vB,oBAAqB,EAC1B1vB,KAAK2xB,YAIT3xB,KAAK0B,UAAU1B,KAAKkwB,mBAAmB3tB,SAASpB,GAAKnB,KAAK4xB,cAAczwB,IAE1E,CAEO,WAAA2E,CAAY2W,GACjB,MAAM5R,EAAM7K,KAAKkwB,mBAAmB2B,oBACpC7xB,KAAKkwB,mBAAmB4B,kBAAkB,CACxCC,gBAAgB,EAChBC,UAAWnnB,EAAImnB,UAAYvV,EAAOzc,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,QAE9E,CAEO,YAAAoU,CAAaxY,EAAcuY,GAC5BA,IACF9c,KAAK0xB,aAAentB,GAEtBvE,KAAKkwB,mBAAmB4B,kBAAkB,CACxCC,gBAAiBjV,EACjBkV,UAAWztB,EAAOvE,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,QAE9D,CAEQ,iBAAA+nB,GACN,MAAMhV,EAAgB1b,KAAKkqB,gBAAgB5f,WAAWqR,WAAWD,gBAAiB,EAC5E+U,EAAazwB,KAAKkqB,gBAAgB5f,WAAWqR,WAAW8U,aAAc,EACtEwB,EAAwBvW,EACzB1b,KAAKkqB,gBAAgB5f,WAAWqR,WAAW5S,OAAK,GACjD,EACJ,MAAO,CACLmpB,4BAA6BlyB,KAAKkqB,gBAAgB5f,WAAW6nB,kBAC7DC,sBAAuBpyB,KAAKkqB,gBAAgB5f,WAAW8nB,sBACvDhC,SAAU1U,EAAe,EAA2B,EACpDuW,wBACAzB,kBAAmBC,EAEvB,CAEO,SAAAxV,CAAUzW,QAEDI,IAAVJ,IACFxE,KAAK0xB,aAAeltB,QAIaI,IAA/B5E,KAAKqyB,wBAGTryB,KAAKqyB,sBAAwBryB,KAAKF,eAAeutB,mBAAmB,KAClErtB,KAAKqyB,2BAAwBztB,EAC7B5E,KAAK2xB,MAAM3xB,KAAK0xB,gBAEpB,CAEQ,KAAAC,CAAMntB,EAAgBxE,KAAK8R,eAAe3N,OAAOK,OAClDxE,KAAKF,iBAAkBE,KAAKuvB,aAK7BvvB,KAAKovB,aAAa/kB,gBAAgBioB,mBACpCtyB,KAAK0vB,oBAAqB,GAG5B1vB,KAAKuvB,YAAa,EAIlBvvB,KAAKyvB,0BAA2B,EAChCzvB,KAAKkwB,mBAAmBa,oBAAoB,CAC1CpoB,OAAQ3I,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOL,OAClDqoB,aAAchxB,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAAS3I,KAAK8R,eAAe3N,OAAOE,MAAM9C,SAElGvB,KAAKyvB,0BAA2B,EAI5BjrB,IAAUxE,KAAK0xB,cACjB1xB,KAAKkwB,mBAAmB4B,kBAAkB,CACxCE,UAAWxtB,EAAQxE,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,SAI/D3I,KAAKuvB,YAAa,GACpB,CAEQ,aAAAqC,CAAczwB,GACpB,IAAKnB,KAAKF,eACR,OAEF,GAAIE,KAAKwvB,mBAAqBxvB,KAAKyvB,yBACjC,OAEFzvB,KAAKwvB,mBAAoB,EACzB,MAAM+C,EAAS5d,KAAK6d,MAAMrxB,EAAE6wB,UAAYhyB,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,QAC1E8pB,EAAOF,EAASvyB,KAAK8R,eAAe3N,OAAOK,MACpC,IAATiuB,IACFzyB,KAAK0xB,aAAea,EACpBvyB,KAAKsvB,sBAAsBre,KAAKwhB,IAElCzyB,KAAKwvB,mBAAoB,CAC3B,CAEO,iBAAAtT,CAAkBwW,GACvB,MAAM7nB,EAAM7K,KAAKkwB,mBAAmB2B,oBACpC7xB,KAAKkwB,mBAAmB4B,kBAAkB,CACxCE,UAAWnnB,EAAImnB,UAAYU,GAE/B,2BAjNWxY,EAAQ3Q,EAAA,CAkBhBC,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAnK,EAAAqK,qBACAF,EAAA,EAAAlK,EAAAqzB,cACAnpB,EAAA,EAAAlK,EAAAszB,oBACAppB,EAAA,EAAAnK,EAAAoZ,eACAjP,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,EAAAnK,EAAAsK,iBAxBQuQ,wgBCXb,MAAA7a,EAAAH,EAAA,MACAE,EAAAF,EAAA,MACAI,EAAAJ,EAAA,MAEO,IAAMgc,EAAN,cAAuC9b,EAAAK,WAQ5C,WAAAC,CACmBmzB,EACgB/gB,EACKjS,EACDoQ,EACJnQ,GAEjCC,QANiBC,KAAA6yB,eAAAA,EACgB7yB,KAAA8R,eAAAA,EACK9R,KAAAH,oBAAAA,EACDG,KAAAiQ,mBAAAA,EACJjQ,KAAAF,eAAAA,EAXlBE,KAAA8yB,oBAA6D,IAAIrO,IAG1EzkB,KAAA+yB,oBAA8B,EAC9B/yB,KAAAgzB,oBAA8B,EAWpChzB,KAAKizB,WAAa7a,SAAS3X,cAAc,OACzCT,KAAKizB,WAAWvyB,UAAUC,IAAI,8BAC9BX,KAAK6yB,eAAe5xB,YAAYjB,KAAKizB,YAErCjzB,KAAK0B,UAAU1B,KAAKF,eAAemZ,yBAAyB,IAAMjZ,KAAKkzB,0BACvElzB,KAAK0B,UAAU1B,KAAKF,eAAesD,mBAAmB,KACpDpD,KAAKgzB,oBAAqB,EAC1BhzB,KAAKmzB,mBAEPnzB,KAAK0B,UAAU1B,KAAKH,oBAAoB2D,YAAY,IAAMxD,KAAKmzB,kBAC/DnzB,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiB,KAC1DzxB,KAAK+yB,mBAAqB/yB,KAAK8R,eAAe3N,SAAWnE,KAAK8R,eAAe0B,QAAQ4f,OAEvFpzB,KAAK0B,UAAU1B,KAAKiQ,mBAAmBojB,uBAAuB,IAAMrzB,KAAKmzB,kBACzEnzB,KAAK0B,UAAU1B,KAAKiQ,mBAAmBqjB,oBAAoBC,GAAcvzB,KAAKwzB,kBAAkBD,KAChGvzB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKizB,WAAWvvB,SAChB1D,KAAK8yB,oBAAoBzmB,UAE7B,CAEQ,aAAA8mB,QACuBvuB,IAAzB5E,KAAKmtB,kBAGTntB,KAAKmtB,gBAAkBntB,KAAKF,eAAeutB,mBAAmB,KAC5DrtB,KAAKkzB,wBACLlzB,KAAKmtB,qBAAkBvoB,IAE3B,CAEQ,qBAAAsuB,GACN,IAAK,MAAMK,KAAcvzB,KAAKiQ,mBAAmBwY,YAC/CzoB,KAAKyzB,kBAAkBF,GAEzBvzB,KAAKgzB,oBAAqB,CAC5B,CAEQ,iBAAAS,CAAkBF,GACxBvzB,KAAK0zB,cAAcH,GACfvzB,KAAKgzB,oBACPhzB,KAAK2zB,kBAAkBJ,EAE3B,CAEQ,cAAAK,CAAeL,GACrB,MAAMzxB,EAAU9B,KAAKH,oBAAoBU,aAAaE,cAAc,OACpEqB,EAAQpB,UAAUC,IAAI,oBACtBmB,EAAQpB,UAAU6W,OAAO,6BAA6D,QAA/Bgc,GAAYrqB,SAAS2qB,OAC5E/xB,EAAQgH,MAAMC,MAAQ,GAAG4L,KAAK6d,OAAOe,EAAWrqB,QAAQH,OAAS,GAAK/I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,WAC9GjH,EAAQgH,MAAMH,QAAa4qB,EAAWrqB,QAAQP,QAAU,GAAK3I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAA9E,KACvB7G,EAAQgH,MAAMkC,KAAUuoB,EAAWO,OAAOvvB,KAAOvE,KAAK8R,eAAe0B,QAAQC,OAAOjP,OAASxE,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAAjH,KACpB7G,EAAQgH,MAAMqM,WAAa,GAAGnV,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,WAEtE,MAAMkM,EAAI0e,EAAWrqB,QAAQ2L,GAAK,EAOlC,OANIA,GAAKA,EAAI7U,KAAK8R,eAAe7J,OAE/BnG,EAAQgH,MAAMirB,QAAU,QAE1B/zB,KAAK2zB,kBAAkBJ,EAAYzxB,GAE5BA,CACT,CAEQ,aAAA4xB,CAAcH,GACpB,MAAMhvB,EAAOgvB,EAAWO,OAAOvvB,KAAOvE,KAAK8R,eAAe0B,QAAQC,OAAOjP,MACzE,GAAID,EAAO,GAAKA,GAAQvE,KAAK8R,eAAe/Q,KAEtCwyB,EAAWzxB,UACbyxB,EAAWzxB,QAAQgH,MAAMirB,QAAU,OACnCR,EAAWS,gBAAgB/iB,KAAKsiB,EAAWzxB,cAExC,CACL,IAAIA,EAAU9B,KAAK8yB,oBAAoBhvB,IAAIyvB,GACtCzxB,IACHA,EAAU9B,KAAK4zB,eAAeL,GAC9BA,EAAWzxB,QAAUA,EACrB9B,KAAK8yB,oBAAoBhuB,IAAIyuB,EAAYzxB,GACzC9B,KAAKizB,WAAWhyB,YAAYa,GAC5ByxB,EAAWU,UAAU,KACnBj0B,KAAK8yB,oBAAoBoB,OAAOX,GAChCzxB,EAAS4B,YAGb5B,EAAQgH,MAAMirB,QAAU/zB,KAAK+yB,mBAAqB,OAAS,QACtD/yB,KAAK+yB,qBACRjxB,EAAQgH,MAAMC,MAAQ,GAAG4L,KAAK6d,OAAOe,EAAWrqB,QAAQH,OAAS,GAAK/I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,WAC9GjH,EAAQgH,MAAMH,QAAa4qB,EAAWrqB,QAAQP,QAAU,GAAK3I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAA9E,KACvB7G,EAAQgH,MAAMkC,IAASzG,EAAOvE,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OAAlD,KACpB7G,EAAQgH,MAAMqM,WAAa,GAAGnV,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,YAExE4qB,EAAWS,gBAAgB/iB,KAAKnP,EAClC,CACF,CAEQ,iBAAA6xB,CAAkBJ,EAAiCzxB,EAAmCyxB,EAAWzxB,SACvG,IAAKA,EACH,OAEF,MAAM+S,EAAI0e,EAAWrqB,QAAQ2L,GAAK,EACY,WAAzC0e,EAAWrqB,QAAQirB,QAAU,QAChCryB,EAAQgH,MAAMsrB,MAAQvf,EAAOA,EAAI7U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAA/C,KAA2D,GAErFjH,EAAQgH,MAAMgC,KAAO+J,EAAOA,EAAI7U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAA/C,KAA2D,EAExF,CAEQ,iBAAAyqB,CAAkBD,GACxBvzB,KAAK8yB,oBAAoBhvB,IAAIyvB,IAAa7vB,SAC1C1D,KAAK8yB,oBAAoBoB,OAAOX,GAChCA,EAAWla,SACb,2DAhIW6B,EAAwB3R,EAAA,CAUhCC,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAnK,EAAAqK,qBACAF,EAAA,EAAAlK,EAAAgR,oBACA9G,EAAA,EAAAnK,EAAAsK,iBAbQuR,uGCsBb,iBAAAxb,GACUM,KAAAq0B,OAAuB,GAKvBr0B,KAAAs0B,UAA0B,GAC1Bt0B,KAAAu0B,eAAiB,EAEjBv0B,KAAAw0B,aAA+C,CACrDC,KAAM,EACN3pB,KAAM,EACN4pB,OAAQ,EACRN,MAAO,EAwEX,CArEE,SAAWO,GAGT,OADA30B,KAAKs0B,UAAU/yB,OAASoT,KAAKC,IAAI5U,KAAKs0B,UAAU/yB,OAAQvB,KAAKq0B,OAAO9yB,QAC7DvB,KAAKq0B,MACd,CAEO,KAAAhoB,GACLrM,KAAKq0B,OAAO9yB,OAAS,EACrBvB,KAAKu0B,eAAiB,CACxB,CAEO,aAAAK,CAAcrB,GACnB,GAAKA,EAAWrqB,QAAQ2rB,qBAAxB,CAGA,IAAK,MAAMC,KAAK90B,KAAKq0B,OACnB,GAAIS,EAAEviB,QAAUghB,EAAWrqB,QAAQ2rB,qBAAqBtiB,OACpDuiB,EAAE7vB,WAAasuB,EAAWrqB,QAAQ2rB,qBAAqB5vB,SAAU,CACnE,GAAIjF,KAAK+0B,oBAAoBD,EAAGvB,EAAWO,OAAOvvB,MAChD,OAEF,GAAIvE,KAAKg1B,oBAAoBF,EAAGvB,EAAWO,OAAOvvB,KAAMgvB,EAAWrqB,QAAQ2rB,qBAAqB5vB,UAE9F,YADAjF,KAAKi1B,eAAeH,EAAGvB,EAAWO,OAAOvvB,KAG7C,CAGF,GAAIvE,KAAKu0B,eAAiBv0B,KAAKs0B,UAAU/yB,OAMvC,OALAvB,KAAKs0B,UAAUt0B,KAAKu0B,gBAAgBhiB,MAAQghB,EAAWrqB,QAAQ2rB,qBAAqBtiB,MACpFvS,KAAKs0B,UAAUt0B,KAAKu0B,gBAAgBtvB,SAAWsuB,EAAWrqB,QAAQ2rB,qBAAqB5vB,SACvFjF,KAAKs0B,UAAUt0B,KAAKu0B,gBAAgBW,gBAAkB3B,EAAWO,OAAOvvB,KACxEvE,KAAKs0B,UAAUt0B,KAAKu0B,gBAAgBY,cAAgB5B,EAAWO,OAAOvvB,UACtEvE,KAAKq0B,OAAOpwB,KAAKjE,KAAKs0B,UAAUt0B,KAAKu0B,mBAIvCv0B,KAAKq0B,OAAOpwB,KAAK,CACfsO,MAAOghB,EAAWrqB,QAAQ2rB,qBAAqBtiB,MAC/CtN,SAAUsuB,EAAWrqB,QAAQ2rB,qBAAqB5vB,SAClDiwB,gBAAiB3B,EAAWO,OAAOvvB,KACnC4wB,cAAe5B,EAAWO,OAAOvvB,OAEnCvE,KAAKs0B,UAAUrwB,KAAKjE,KAAKq0B,OAAOr0B,KAAKq0B,OAAO9yB,OAAS,IACrDvB,KAAKu0B,gBA9BL,CA+BF,CAEO,UAAAa,CAAWC,GAChBr1B,KAAKw0B,aAAea,CACtB,CAEQ,mBAAAN,CAAoBO,EAAkB/wB,GAC5C,OACEA,GAAQ+wB,EAAKJ,iBACb3wB,GAAQ+wB,EAAKH,aAEjB,CAEQ,mBAAAH,CAAoBM,EAAkB/wB,EAAcU,GAC1D,OACGV,GAAQ+wB,EAAKJ,gBAAkBl1B,KAAKw0B,aAAavvB,GAAY,SAC7DV,GAAQ+wB,EAAKH,cAAgBn1B,KAAKw0B,aAAavvB,GAAY,OAEhE,CAEQ,cAAAgwB,CAAeK,EAAkB/wB,GACvC+wB,EAAKJ,gBAAkBvgB,KAAKC,IAAI0gB,EAAKJ,gBAAiB3wB,GACtD+wB,EAAKH,cAAgBxgB,KAAKkZ,IAAIyH,EAAKH,cAAe5wB,EACpD,qgBC9GF,MAAAgxB,EAAAr2B,EAAA,KACAG,EAAAH,EAAA,MACAE,EAAAF,EAAA,MACAI,EAAAJ,EAAA,MAQMs2B,EAAa,CACjBf,KAAM,EACN3pB,KAAM,EACN4pB,OAAQ,EACRN,MAAO,GAEHqB,EAAY,CAChBhB,KAAM,EACN3pB,KAAM,EACN4pB,OAAQ,EACRN,MAAO,GAEHsB,EAAQ,CACZjB,KAAM,EACN3pB,KAAM,EACN4pB,OAAQ,EACRN,MAAO,GAGF,IAAMtY,EAAN,cAAoC1c,EAAAK,WAIzC,UAAYk2B,GACV,MAAMha,EAAY3b,KAAKkqB,gBAAgB5f,WAAWqR,UAElD,OADsBA,GAAWD,eAAiB,EAI3CC,GAAW5S,OAAS,EAFlB,CAGX,CAOA,WAAArJ,CACmBkY,EACAib,EACgB/gB,EACI7B,EACJnQ,EACCoqB,EACFjY,EACMpS,GAEtCE,QATiBC,KAAA4X,iBAAAA,EACA5X,KAAA6yB,eAAAA,EACgB7yB,KAAA8R,eAAAA,EACI9R,KAAAiQ,mBAAAA,EACJjQ,KAAAF,eAAAA,EACCE,KAAAkqB,gBAAAA,EACFlqB,KAAAiS,cAAAA,EACMjS,KAAAH,oBAAAA,EAvBvBG,KAAA41B,gBAAmC,IAAIL,EAAAM,eAWhD71B,KAAA81B,yBAA+C,EAC/C91B,KAAA+1B,qBAA2C,EAC3C/1B,KAAAg2B,uBAAiC,EAavCh2B,KAAKi2B,QAAUj2B,KAAKH,oBAAoBU,aAAaE,cAAc,UACnET,KAAKi2B,QAAQv1B,UAAUC,IAAI,mCAC3BX,KAAKk2B,2BACLl2B,KAAK4X,iBAAiBue,eAAeC,aAAap2B,KAAKi2B,QAASj2B,KAAK4X,kBACrE5X,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKi2B,SAASvyB,WAEhD,MAAM2yB,EAAMr2B,KAAKi2B,QAAQK,WAAW,MACpC,IAAKD,EACH,MAAM,IAAIt0B,MAAM,sBAEhB/B,KAAKu2B,KAAOF,EAGdr2B,KAAK0B,UAAU1B,KAAKiQ,mBAAmBojB,uBAAuB,IAAMrzB,KAAKmzB,mBAAcvuB,GAAW,KAClG5E,KAAK0B,UAAU1B,KAAKiQ,mBAAmBqjB,oBAAoB,IAAMtzB,KAAKmzB,mBAAcvuB,GAAW,KAE/F5E,KAAK0B,UAAU1B,KAAKF,eAAemZ,yBAAyB,IAAMjZ,KAAKmzB,kBACvEnzB,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiB,KAC1DzxB,KAAKi2B,QAASntB,MAAMirB,QAAU/zB,KAAK8R,eAAe3N,SAAWnE,KAAK8R,eAAe0B,QAAQ4f,IAAM,OAAS,WAE1GpzB,KAAK0B,UAAU1B,KAAK8R,eAAevP,SAAS,KACtCvC,KAAKg2B,yBAA2Bh2B,KAAK8R,eAAe0B,QAAQgjB,OAAOnyB,MAAM9C,SAC3EvB,KAAKy2B,8BACLz2B,KAAK02B,+BAIT12B,KAAK0B,UAAU1B,KAAKF,eAAesD,mBAAmB,IAAMpD,KAAKmzB,eAAc,KAE/EnzB,KAAK0B,UAAU1B,KAAKH,oBAAoB2D,YAAY,IAAMxD,KAAKmzB,eAAc,KAC7EnzB,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,YAAa,IAAMzX,KAAKmzB,eAAc,KACjGnzB,KAAK0B,UAAU1B,KAAKiS,cAAc0G,eAAe,IAAM3Y,KAAKmzB,kBAC5DnzB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,UACGmB,IAAzB5E,KAAKmtB,kBACPntB,KAAKH,oBAAoBqX,OAAOkW,qBAAqBptB,KAAKmtB,iBAC1DntB,KAAKmtB,qBAAkBvoB,MAG3B5E,KAAKmzB,eAAc,EACrB,CAEQ,qBAAAwD,GAEN,MAAMC,EAAajiB,KAAKkiB,OAAO72B,KAAKi2B,QAAQltB,MAAK,GAA4C,GACvF+tB,EAAaniB,KAAKoiB,MAAM/2B,KAAKi2B,QAAQltB,MAAK,GAA4C,GAC5F0sB,EAAUhB,KAAOz0B,KAAKi2B,QAAQltB,MAC9B0sB,EAAU3qB,KAAO8rB,EACjBnB,EAAUf,OAASoC,EACnBrB,EAAUrB,MAAQwC,EAElB52B,KAAKy2B,8BAELf,EAAMjB,KAAI,EACViB,EAAM5qB,KAAI,EACV4qB,EAAMhB,OAAS,EAAwCe,EAAU3qB,KACjE4qB,EAAMtB,MAAQ,EAAwCqB,EAAU3qB,KAAO2qB,EAAUf,MACnF,CAEQ,2BAAA+B,GACNjB,EAAWf,KAAO9f,KAAK6d,MAAM,EAAIxyB,KAAKH,oBAAoBm3B,KAE1D,MAAMC,EAAgBj3B,KAAKi2B,QAAQttB,OAAS3I,KAAK8R,eAAe3N,OAAOE,MAAM9C,OAEvE21B,EAAgBviB,KAAK6d,MAAM7d,KAAKkZ,IAAIlZ,KAAKC,IAAIqiB,EAAe,IAAK,GAAKj3B,KAAKH,oBAAoBm3B,KACrGxB,EAAW1qB,KAAOosB,EAClB1B,EAAWd,OAASwC,EACpB1B,EAAWpB,MAAQ8C,CACrB,CAEQ,wBAAAR,GACN12B,KAAK41B,gBAAgBR,WAAW,CAC9BX,KAAM9f,KAAKkiB,MAAM72B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUvB,KAAKi2B,QAAQttB,OAAS,GAAK6sB,EAAWf,MAC1G3pB,KAAM6J,KAAKkiB,MAAM72B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUvB,KAAKi2B,QAAQttB,OAAS,GAAK6sB,EAAW1qB,MAC1G4pB,OAAQ/f,KAAKkiB,MAAM72B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUvB,KAAKi2B,QAAQttB,OAAS,GAAK6sB,EAAWd,QAC5GN,MAAOzf,KAAKkiB,MAAM72B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUvB,KAAKi2B,QAAQttB,OAAS,GAAK6sB,EAAWpB,SAE7Gp0B,KAAKg2B,uBAAyBh2B,KAAK8R,eAAe0B,QAAQgjB,OAAOnyB,MAAM9C,MACzE,CAEQ,wBAAA20B,GACN,GAAIl2B,KAAKm3B,OAAOC,aAAep3B,KAAKF,eAAe4Z,cACjD,OAEF,MAAM2d,EAAkBr3B,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOL,OAC5D2uB,EAAqBt3B,KAAKF,eAAe0I,WAAWqG,OAAO7F,OAAOL,OACxE3I,KAAKi2B,QAAQntB,MAAMC,MAAQ,GAAG/I,KAAK21B,WACnC31B,KAAKi2B,QAAQltB,MAAQ4L,KAAK6d,MAAMxyB,KAAK21B,OAAS31B,KAAKH,oBAAoBm3B,KACvEh3B,KAAKi2B,QAAQntB,MAAMH,OAAS,GAAG0uB,MAC/Br3B,KAAKi2B,QAAQttB,OAAS2uB,EACtBt3B,KAAK22B,wBACL32B,KAAK02B,0BACP,CAEQ,mBAAAa,GACN,GAAIv3B,KAAKm3B,OAAOC,aAAep3B,KAAKF,eAAe4Z,cACjD,OAEE1Z,KAAK81B,yBACP91B,KAAKk2B,2BAEPl2B,KAAKu2B,KAAKiB,UAAU,EAAG,EAAGx3B,KAAKi2B,QAAQltB,MAAO/I,KAAKi2B,QAAQttB,QAC3D3I,KAAK41B,gBAAgBvpB,QACrB,IAAK,MAAMknB,KAAcvzB,KAAKiQ,mBAAmBwY,YAC/CzoB,KAAK41B,gBAAgBhB,cAAcrB,GAErCvzB,KAAKu2B,KAAKkB,UAAY,EACtBz3B,KAAK03B,sBACL,MAAM/C,EAAQ30B,KAAK41B,gBAAgBjB,MACnC,IAAK,MAAMW,KAAQX,EACK,SAAlBW,EAAKrwB,UACPjF,KAAK23B,iBAAiBrC,GAG1B,IAAK,MAAMA,KAAQX,EACK,SAAlBW,EAAKrwB,UACPjF,KAAK23B,iBAAiBrC,GAG1Bt1B,KAAK81B,yBAA0B,EAC/B91B,KAAK+1B,qBAAsB,CAC7B,CAEQ,mBAAA2B,GACN13B,KAAKu2B,KAAKqB,UAAY53B,KAAKiS,cAAcQ,OAAOolB,oBAAoBpvB,IACpEzI,KAAKu2B,KAAKuB,SAAS,EAAG,EAAC,EAAyC93B,KAAKi2B,QAAQttB,QACzE3I,KAAKkqB,gBAAgB5f,WAAWqR,WAAWoc,eAAeC,eAC5Dh4B,KAAKu2B,KAAKuB,SAAQ,EAAwC,EAAG93B,KAAKi2B,QAAQltB,MAAK,EAAwC,GAErH/I,KAAKkqB,gBAAgB5f,WAAWqR,WAAWoc,eAAeE,kBAC5Dj4B,KAAKu2B,KAAKuB,SAAQ,EAAwC93B,KAAKi2B,QAAQttB,OAAM,EAA0C3I,KAAKi2B,QAAQltB,MAAK,EAA0C/I,KAAKi2B,QAAQttB,OAEpM,CAEQ,gBAAAgvB,CAAiBrC,GACvBt1B,KAAKu2B,KAAKqB,UAAYtC,EAAK/iB,MAC3BvS,KAAKu2B,KAAKuB,SACApC,EAAMJ,EAAKrwB,UAAY,QACvB0P,KAAK6d,OACVxyB,KAAKi2B,QAAQttB,OAAS,IACtB2sB,EAAKJ,gBAAkBl1B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUi0B,EAAWF,EAAKrwB,UAAY,QAAU,GAE3GwwB,EAAUH,EAAKrwB,UAAY,QAC3B0P,KAAK6d,OACVxyB,KAAKi2B,QAAQttB,OAAS,KACrB2sB,EAAKH,cAAgBG,EAAKJ,iBAAmBl1B,KAAK8R,eAAe0B,QAAQC,OAAOpP,MAAM9C,QAAUi0B,EAAWF,EAAKrwB,UAAY,SAGpI,CAEQ,aAAAkuB,CAAc+E,EAAkCC,GAClDn4B,KAAKm3B,OAAOC,aAGhBp3B,KAAK81B,wBAA0BoC,GAA0Bl4B,KAAK81B,wBAC9D91B,KAAK+1B,oBAAsBoC,GAAgBn4B,KAAK+1B,yBACnBnxB,IAAzB5E,KAAKmtB,kBAGTntB,KAAKmtB,gBAAkBntB,KAAKH,oBAAoBqX,OAAOmL,sBAAsB,KACtEriB,KAAKm3B,OAAOC,YACfp3B,KAAKu3B,sBAEPv3B,KAAKmtB,qBAAkBvoB,KAE3B,qDAjMWkX,EAAqBvS,EAAA,CAqB7BC,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAlK,EAAAgR,oBACA9G,EAAA,EAAAnK,EAAAsK,gBACAH,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,EAAAnK,EAAAoZ,eACAjP,EAAA,EAAAnK,EAAAqK,sBA1BQoS,igBC9Bb,MAAAzc,EAAAH,EAAA,MACAI,EAAAJ,EAAA,MA0BMk5B,EAAsC,gCASrC,IAAMlkB,EAAN,MAML,eAAWI,GAAyB,OAAOtU,KAAKq4B,YAAc,CAC9D,qCAAWC,GACT,YAAoC1zB,IAA7B5E,KAAKu4B,mBACd,CACA,yBAAWC,GACT,OAAOx4B,KAAKs4B,iCACd,CACA,wBAAWG,GACT,OAAOz4B,KAAKu4B,qBAAqBG,cAAgB,EACnD,CAuDA,WAAAh5B,CACmBi5B,EACAvf,EACgBtH,EACCoY,EACHkF,EACEtvB,kBALhB64B,wBACAvf,sBACgBtH,uBACCoY,oBACHkF,sBACEtvB,EAEjCE,KAAKq4B,cAAe,EACpBr4B,KAAK44B,2BAA4B,EACjC54B,KAAK64B,qBAAuB,CAAEx2B,MAAO,EAAGC,IAAK,GAC7CtC,KAAK84B,mBAAqB,GAC1B94B,KAAK+4B,iBAAmB,GACxB/4B,KAAKg5B,sBAAwB,GAC7Bh5B,KAAKi5B,qBAAuB,GAC5Bj5B,KAAKk5B,uBAAyB,GAC9Bl5B,KAAKm5B,2BAA6B,CAAE92B,MAAO,EAAGC,IAAK,GACnDtC,KAAKo5B,iCAAkC,EACvCp5B,KAAKq5B,0BAA4B,EACjCr5B,KAAKs5B,mBAAqB,IAAI9R,GAChC,CAKO,gBAAArR,GACLnW,KAAKu5B,qBAAqBv5B,KAAKw5B,2BAC/Bx5B,KAAKw5B,+BAA4B50B,EACjC5E,KAAKu5B,qBAAqBv5B,KAAKy5B,uBAC/Bz5B,KAAKy5B,2BAAwB70B,EAC7B5E,KAAKu5B,qBAAqBv5B,KAAK05B,sBAC/B15B,KAAK05B,0BAAuB90B,EACxB5E,KAAKu4B,sBACPv4B,KAAK25B,wBAAwB35B,KAAKu4B,qBAClCv4B,KAAK45B,8BAA8B55B,KAAKu4B,qBACxCv4B,KAAK65B,0BAA0B75B,KAAKu4B,2BAEJ3zB,IAA9B5E,KAAK85B,uBACP3L,aAAanuB,KAAK85B,sBAClB95B,KAAK85B,0BAAuBl1B,GAI9B,MAAMvC,EAAQrC,KAAK24B,UAAUra,gBAAkBte,KAAK24B,UAAUluB,MAAMlJ,OAC9De,EAAMtC,KAAK24B,UAAUpa,cAAgBlc,EAC3CrC,KAAK64B,qBAAqBx2B,MAAQsS,KAAKC,IAAIvS,EAAOC,GAClDtC,KAAK64B,qBAAqBv2B,IAAMqS,KAAKkZ,IAAIxrB,EAAOC,GAChDtC,KAAKk5B,uBAAyBl5B,KAAK24B,UAAUluB,MAC7CzK,KAAKm5B,2BAA6B,CAAE92B,QAAOC,OAC3CtC,KAAKo5B,iCAAkC,EACnCp5B,KAAKu4B,sBACPv4B,KAAKu4B,oBAAoBwB,qBAAuB/5B,KAAK64B,qBAAqBx2B,OAE5ErC,KAAKq5B,4BACLr5B,KAAKq4B,cAAe,EACpBr4B,KAAK44B,2BAA4B,EACjC54B,KAAK84B,mBAAqB94B,KAAK24B,UAAUluB,MAAMuvB,UAAUh6B,KAAK64B,qBAAqBv2B,KACnFtC,KAAKoZ,iBAAiBxV,YAAc,GACpC5D,KAAK+4B,iBAAmB,GACxB/4B,KAAKg5B,sBAAwB,GAC7Bh5B,KAAKi5B,qBAAuB,GAC5Bj5B,KAAKoZ,iBAAiB1Y,UAAUC,IAAI,UACpCX,KAAKi6B,iCAAiC,IAAIzjB,YA9IA,kCA8ImD,CAC3FC,SAAS,EACTyjB,OAAQ,CAAEC,GAAIn6B,KAAKq5B,6BAEvB,CAMO,iBAAAhjB,CAAkB1L,GACvB3K,KAAKu5B,qBAAqBv5B,KAAK05B,sBAC/B15B,KAAK05B,0BAAuB90B,EAC5B5E,KAAKo5B,kCAAoCp5B,KAAKo6B,0BAC1CzvB,EAAGsS,MAAM1b,OAAS,IACpBvB,KAAKi5B,qBAAuBtuB,EAAGsS,MAIjCjd,KAAKoZ,iBAAiBxV,YAAc,IAAS+G,EAAGsS,MAAQ,MACxDjd,KAAKoW,4BACL,MAAMikB,EAAgBr6B,KAAKq5B,0BAC3Br5B,KAAKu5B,qBAAqBv5B,KAAKw5B,2BAC/Bx5B,KAAKw5B,0BAA4Bx5B,KAAKs6B,OAAO,KAC3C,GAAIt6B,KAAKq4B,cAAgBr4B,KAAKq5B,4BAA8BgB,EAAe,CACzEr6B,KAAKo5B,kCAAoCp5B,KAAKo6B,0BAC9C,MAAM93B,EAAMtC,KAAK24B,UAAUpa,cAAgBve,KAAK24B,UAAUluB,MAAMlJ,OAChEvB,KAAK64B,qBAAqBv2B,IAAMqS,KAAKkZ,IAAI7tB,KAAK64B,qBAAqBx2B,MAAOC,EAC5E,GAEJ,CAMO,cAAAgU,CAAe3L,GACpB,IAAK3K,KAAK44B,0BACR,OAAO,EAET,IAAK54B,KAAKq4B,aAAc,CACtB,MAAMkC,EAAUv6B,KAAKu4B,oBAKrB,OAJIgC,GAASF,gBAAkBr6B,KAAKq5B,4BAClCkB,EAAQC,QAAU7vB,GAAIsS,MAAQ,GAC9Bjd,KAAKy6B,uCAAuCF,KAEvC,CACT,CACA,MAAMC,EAAU7vB,GAAIsS,MAAQ,GAE5B,GADAjd,KAAKo5B,kCAAoCp5B,KAAKo6B,2BACzCp6B,KAAK06B,2CAA2CF,GAAU,CAC7D,MAAMD,EAAUv6B,KAAKu4B,oBAKrB,OAJIgC,GAAWA,EAAQF,gBAAkBr6B,KAAKq5B,2BAC5Cr5B,KAAK26B,wBAAwBJ,GAE/Bv6B,KAAK46B,qBAAqBJ,IACnB,CACT,CAIA,OAHAx6B,KAAKu5B,qBAAqBv5B,KAAK05B,sBAC/B15B,KAAK05B,0BAAuB90B,EAC5B5E,KAAK66B,sBAAqB,EAAML,IACzB,CACT,CAEO,IAAAzmB,GAGL,GAFA/T,KAAKu5B,qBAAqBv5B,KAAK05B,sBAC/B15B,KAAK05B,0BAAuB90B,EACxB5E,KAAKq4B,aAAc,CACrB,MAAM/1B,EAAMtC,KAAK24B,UAAUpa,cAAgBve,KAAK24B,UAAUluB,MAAMlJ,OAChEvB,KAAK64B,qBAAqBv2B,IAAMqS,KAAKkZ,IAAI7tB,KAAK64B,qBAAqBx2B,MAAOC,EAC5E,EACItC,KAAKq4B,cAAgBr4B,KAAKs4B,oCAC5Bt4B,KAAK66B,sBAAqB,EAE9B,CAEO,OAAAxhB,QAC6BzU,IAA9B5E,KAAK85B,uBACP3L,aAAanuB,KAAK85B,sBAClB95B,KAAK85B,0BAAuBl1B,GAE9B,IAAK,MAAMk2B,KAAS96B,KAAKs5B,mBACvBnL,aAAa2M,GAEf96B,KAAKs5B,mBAAmBjtB,QACxBrM,KAAKw5B,+BAA4B50B,EACjC5E,KAAKy5B,2BAAwB70B,EAC7B5E,KAAK05B,0BAAuB90B,EAC5B5E,KAAKu4B,yBAAsB3zB,EAC3B5E,KAAK44B,2BAA4B,EACjC54B,KAAKq4B,cAAe,EACpBr4B,KAAKq5B,2BACP,CAOO,OAAAva,CAAQnU,GACb,GAAI3K,KAAK+6B,cAAcC,OAASrwB,EAAGqwB,MAAQh7B,KAAK+6B,aAAaE,YAActwB,EAAGswB,UAE5E,OADAj7B,KAAK+6B,kBAAen2B,GACb,EAET,GAAe,WAAX+F,EAAG1H,MAAqBjD,KAAKq4B,cAAgBr4B,KAAKs4B,mCAGpD,OAFAt4B,KAAK+6B,aAAe,CAAEC,KAAMrwB,EAAGqwB,KAAMC,UAAWtwB,EAAGswB,WACnDj7B,KAAKk7B,sBACE,EAET,GAAIl7B,KAAKq4B,cAAgBr4B,KAAKs4B,kCAAmC,CAC/D,GAAmB,KAAf3tB,EAAGqV,SAAiC,MAAfrV,EAAGqV,QAG1B,OAAO,EAET,GAAmB,KAAfrV,EAAGqV,SAAiC,KAAfrV,EAAGqV,SAAiC,KAAfrV,EAAGqV,QAE/C,OAAO,EAIThgB,KAAK66B,sBAAqB,EAC5B,CAEA,OAAmB,MAAflwB,EAAGqV,UAGLhgB,KAAKm7B,6BACE,EAIX,CAMO,QAAA7a,CAASzW,GACd,MAAM0wB,EAAUv6B,KAAKu4B,oBACrB,SAAKgC,IAGDA,EAAQa,+BACVb,EAAQ7B,cAAgB7uB,EACjB,GAEL0wB,EAAQc,6BAA+D,IAAhCd,EAAQ7B,aAAan3B,QAC9Dg5B,EAAQ7B,aAAe7uB,EAChB,IAET7J,KAAK26B,wBAAwBJ,GACtB,IACT,CAEO,KAAA/Z,CAAM3W,GACX,GAAI7J,KAAKq4B,aAGP,OAFAr4B,KAAKo5B,kCAAoCp5B,KAAKo6B,0BAC9Cp6B,KAAKg5B,uBAAyBnvB,GACvB,EAET,MAAM0wB,EAAUv6B,KAAKu4B,oBACrB,IAAKgC,EACH,OAAO,EAET,GAAIA,EAAQc,4BAIV,OAHAd,EAAQe,WAAazxB,EACrB0wB,EAAQc,6BAA8B,EACtCr7B,KAAK26B,wBAAwBJ,IACtB,EAET,MAAMgB,EACJ1xB,EAAKtI,OAAS,GACdvB,KAAKw7B,yBAAyBjB,KAAa1wB,GAC3C7J,KAAKw7B,yBAAyBjB,GAAS,KAAU1wB,EAKnD,OAJA7J,KAAK26B,wBAAwBJ,GACxBgB,GACHv7B,KAAKovB,aAAa5kB,iBAAiBX,GAAM,IAEpC,CACT,CAUQ,oBAAAgxB,CAAqBY,EAA6BjB,EAAkB,IAC1E,MAAMkB,EAAe17B,KAAKq4B,aAG1B,GAFAr4B,KAAKoZ,iBAAiB1Y,UAAUgD,OAAO,UACvC1D,KAAKq4B,cAAe,GAChBoD,GAAuBC,EAI3B,GAAKD,EAWE,CACDz7B,KAAKu4B,qBACPv4B,KAAK26B,wBAAwB36B,KAAKu4B,qBAEpC,MAAMgC,EAA+B,CACnCF,cAAer6B,KAAKq5B,0BACpBsC,kBAAkB,EAClBC,cAAc,EACd32B,SAAU,CACR5C,MAAOrC,KAAK64B,qBAAqBx2B,MACjCC,IAAKtC,KAAK64B,qBAAqBv2B,KAEjCu5B,OAAQ77B,KAAK84B,mBACbgD,gBAAiB97B,KAAK+4B,iBACtBgD,gBAAiB/7B,KAAKi5B,qBACtBuB,UACAc,UAAWt7B,KAAKg5B,sBAChBN,aAAc,GACd0C,8BACuC,IAArCp7B,KAAKi5B,qBAAqB13B,QAAmC,IAAnBi5B,EAAQj5B,OACpD85B,6BAA6B,GAE/Br7B,KAAKy6B,uCAAuCF,GAC5Cv6B,KAAKu4B,oBAAsBgC,EAU3BA,EAAQyB,eAAiBh8B,KAAKs6B,OAAO,KACnCC,EAAQyB,oBAAiBp3B,EACrB5E,KAAKq5B,4BAA8BkB,EAAQF,gBAC7Cr6B,KAAK44B,2BAA4B,GAE/B54B,KAAKu4B,sBAAwBgC,GAC/Bv6B,KAAK26B,wBAAwBJ,GAAS,IAG5C,MAjDE,GAHIv6B,KAAKu4B,qBACPv4B,KAAK26B,wBAAwB36B,KAAKu4B,qBAAqB,GAErDmD,EAAc,CAChB,MAAMlb,EAAQxgB,KAAKi8B,qBACjBj8B,KAAK64B,qBAAqBx2B,MAAQrC,KAAK+4B,iBAAiBx3B,OACxDvB,KAAK84B,oBAEP94B,KAAKk8B,sBAAsBl8B,KAAKq5B,0BAA2B7Y,EAC7D,CA4CJ,CAEQ,uBAAAma,CACNJ,EACA4B,GAAiC,GAEjCn8B,KAAK25B,wBAAwBY,GACzBv6B,KAAKu4B,sBAAwBgC,IAC/Bv6B,KAAKu4B,yBAAsB3zB,GAE7B,MAAMw3B,EAAgBp8B,KAAKw7B,yBAAyBjB,EAAS4B,GACvDE,EAAgBr8B,KAAKs8B,uBACzB/B,EAAQe,WAAaf,EAAQ7B,aAC7B6B,EAAQuB,iBAEJtb,EAAQxgB,KAAKu8B,uBACjBH,GAAiB7B,EAAQC,SAAWD,EAAQwB,gBAC5CM,EACA9B,EAAQa,+BAEVp7B,KAAKk8B,sBAAsB3B,EAAQF,cAAe7Z,GAAQ+Z,EAAQqB,cAClE57B,KAAK65B,0BAA0BU,EACjC,CAEQ,uBAAAZ,CAAwBY,QACC31B,IAA3B21B,EAAQyB,iBAGZ7N,aAAaoM,EAAQyB,gBACrBh8B,KAAKs5B,mBAAmBpF,OAAOqG,EAAQyB,gBACvCzB,EAAQyB,oBAAiBp3B,EAC3B,CAEQ,yBAAAi1B,CAA0BU,GAC5BA,EAAQoB,mBAGZpB,EAAQoB,kBAAmB,EAC3B37B,KAAKw8B,yCACP,CAEQ,sBAAAD,CACNE,EACAC,EACAC,GAEA,IAAKD,GAAYD,EAAUhR,SAASiR,GAClC,OAAOD,EAET,IAAKA,GAAaC,EAASjR,SAASgR,GAClC,OAAOC,EAET,GAAIC,EAAmB,CACrB,IAAIC,EAAwBjoB,KAAKC,IAAI6nB,EAAUl7B,OAAQm7B,EAASn7B,QAChE,KACEq7B,EAAwB,IACvBH,EAAUI,SAASH,EAAS1C,UAAU,EAAG4C,KAE1CA,IAEF,IAAIE,EAAuBnoB,KAAKC,IAAI6nB,EAAUl7B,OAAQm7B,EAASn7B,QAC/D,KACEu7B,EAAuB,IACtBJ,EAASG,SAASJ,EAAUzC,UAAU,EAAG8C,KAE1CA,IAEF,OAAOF,EAAwBE,EAC3BL,EAAYC,EAAS1C,UAAU4C,GAC/BF,EAAWD,EAAUzC,UAAU8C,EACrC,CACA,IAAIC,EAAUpoB,KAAKC,IAAI6nB,EAAUl7B,OAAQm7B,EAASn7B,QAClD,KAAOw7B,EAAU,IAAMN,EAAUI,SAASH,EAAS1C,UAAU,EAAG+C,KAC9DA,IAEF,OAAON,EAAYC,EAAS1C,UAAU+C,EACxC,CAEQ,sCAAAtC,CAAuCF,GAC7CA,EAAQc,6BACLd,EAAQC,QAAQj5B,OAAS,GAAKg5B,EAAQwB,gBAAgBx6B,OAAS,IACnC,IAA7Bg5B,EAAQe,UAAU/5B,QACgC,IAAlDvB,KAAKw7B,yBAAyBjB,GAASh5B,MAC3C,CAEQ,wBAAAi6B,CACNjB,EACA4B,GAAiC,GAEjC,MAAM1xB,EAAQzK,KAAK24B,UAAUluB,MACvBpI,EAAQk4B,EAAQt1B,SAAS5C,MAAQk4B,EAAQuB,gBAAgBv6B,OAC/D,QAAqCqD,IAAjC21B,EAAQR,qBACV,OAAOtvB,EAAMuvB,UAAU33B,EAAOsS,KAAKkZ,IAAIxrB,EAAOk4B,EAAQR,uBAExD,MAAMiD,EACJzC,EAAQsB,OAAOt6B,OAAS,GAAKkJ,EAAMoyB,SAAStC,EAAQsB,QAChDpxB,EAAMlJ,OAASg5B,EAAQsB,OAAOt6B,OAC9BkJ,EAAMlJ,OACN07B,GAAqB1C,EAAQC,SAAWD,EAAQwB,iBAAiBx6B,OACjE27B,EAAcf,EAChBa,EACAroB,KAAKkZ,IAAI0M,EAAQt1B,SAAS3C,IAAKD,EAAQ46B,GAC3C,OAAOxyB,EAAMuvB,UAAU33B,EAAOsS,KAAKkZ,IAAIxrB,EAAOsS,KAAKC,IAAIooB,EAAWE,IACpE,CAEQ,oBAAAjB,CAAqB55B,EAAew5B,GAC1C,MAAMpxB,EAAQzK,KAAK24B,UAAUluB,MACvB0yB,EACJtB,EAAOt6B,OAAS,GAAKkJ,EAAMoyB,SAAShB,GAAUpxB,EAAMlJ,OAASs6B,EAAOt6B,OAASkJ,EAAMlJ,OACrF,OAAOkJ,EAAMuvB,UAAU33B,EAAOsS,KAAKkZ,IAAIxrB,EAAO86B,GAChD,CAEQ,sBAAAb,CAAuB9b,EAAesb,GAC5C,OAA+B,IAA3BA,EAAgBv6B,OACXif,EAELA,EAAM4c,WAAWtB,GACZtb,EAAMwZ,UAAU8B,EAAgBv6B,QAElCu6B,EAAgBrQ,SAASjL,GAAS,GAAKA,CAChD,CAEQ,kBAAA0a,GACN,MAAMX,EAAUv6B,KAAKu4B,oBAEnBgC,GACAv6B,KAAKq4B,cACLkC,EAAQF,gBAAkBr6B,KAAKq5B,2BAE/Br5B,KAAK26B,wBAAwBJ,GAE/B,MAAMF,EAAgBr6B,KAAKq4B,aACvBr4B,KAAKq5B,0BACLr5B,KAAKu4B,qBAAqB8B,eAAiB,EACzCgD,OAA6Bz4B,IAAZ21B,GAAyBv6B,KAAKu4B,sBAAwBgC,EAC7Ev6B,KAAKu4B,yBAAsB3zB,EAC3B5E,KAAK44B,2BAA4B,EACjC54B,KAAKq4B,cAAe,EACpBr4B,KAAKoZ,iBAAiB1Y,UAAUgD,OAAO,UACvC1D,KAAK24B,UAAUluB,MACbzK,KAAK24B,UAAUluB,MAAMuvB,UAAU,EAAGh6B,KAAK64B,qBAAqBx2B,OAASrC,KAAK84B,mBAC5E94B,KAAKk8B,sBAAsB7B,EAAe,IACtCgD,GAAkB9C,GACpBv6B,KAAK65B,0BAA0BU,EAEnC,CAEQ,qBAAA2B,CACN7B,EACA7Z,EACA8c,GAA8B,GAE9B,IAAIC,GAAY,EAChB,GAAID,EAAoB,CACtB,MAAM/uB,EAAQ,IAAIiI,YAAY4hB,EAAqC,CACjE3hB,SAAS,EACT+mB,YAAY,EACZtD,OAAQ,CAAEC,GAAIE,EAAepd,KAAMuD,KAErCxgB,KAAKi6B,iCAAiC1rB,GACtCgvB,EAAYhvB,EAAMkvB,gBACpB,CACIjd,EAAMjf,OAAS,IAAMg8B,GACvBv9B,KAAKovB,aAAa5kB,iBAAiBgW,GAAO,EAE9C,CAEQ,6BAAAoZ,CAA8BW,GACpC,GAAIA,EAAQqB,aACV,OAEFrB,EAAQqB,cAAe,EACvB,MAAMpb,EACJxgB,KAAKw7B,yBAAyBjB,IAC9BA,EAAQC,SACRD,EAAQwB,gBACV/7B,KAAKi6B,iCAAiC,IAAIzjB,YACxC4hB,EACA,CACE3hB,SAAS,EACT+mB,YAAY,EACZtD,OAAQ,CACNC,GAAII,EAAQF,cACZpd,KAAMuD,EACNkd,2BAA2B,KAInC,CAEQ,gCAAAzD,CAAiC1rB,GACK,mBAAjCvO,KAAK24B,UAAUpiB,eACxBvW,KAAK24B,UAAUpiB,cAAchI,EAEjC,CAEQ,sCAAAiuB,GACNx8B,KAAKi6B,iCAAiC,IAAIzjB,YACxC,wCACA,CAAEC,SAAS,IAEf,CAEQ,oBAAAmkB,CAAqBJ,GAC3Bx6B,KAAKu5B,qBAAqBv5B,KAAK05B,sBAC/B,MAAMW,EAAgBr6B,KAAKq5B,0BACrByB,EAAQ96B,KAAKs6B,OAAO,KACxB,GACEt6B,KAAK05B,uBAAyBoB,IAC7B96B,KAAKq4B,cACNr4B,KAAKq5B,4BAA8BgB,IAClCr6B,KAAK06B,2CAA2CF,GAEjD,OAEFx6B,KAAK05B,0BAAuB90B,EAC5B5E,KAAK66B,sBAAqB,EAAML,GAChCx6B,KAAKi6B,iCAAiC,IAAIzjB,YAhmB9C,yCAkmBM,CAAEC,SAAS,KAEb,MAAM8jB,EAAUv6B,KAAKu4B,oBACjBgC,GAASF,gBAAkBA,GAC7Br6B,KAAK26B,wBAAwBJ,GAAS,KAG1Cv6B,KAAK05B,qBAAuBoB,CAC9B,CAEQ,uBAAAV,GACN,MAAM/3B,EAAQrC,KAAK24B,UAAUra,gBAAkBte,KAAK24B,UAAUluB,MAAMlJ,OAC9De,EAAMtC,KAAK24B,UAAUpa,cAAgBlc,EAC3C,OAAOrC,KAAKo5B,iCACVp5B,KAAK24B,UAAUluB,QAAUzK,KAAKk5B,wBAC9B72B,IAAUrC,KAAKm5B,2BAA2B92B,OAC1CC,IAAQtC,KAAKm5B,2BAA2B72B,GAE5C,CAEQ,0CAAAo4B,CAA2CF,GACjD,OACEx6B,KAAKo6B,2BACJI,EAAQj5B,OAAS,GAAKi5B,IAAYx6B,KAAKi5B,oBAE5C,CAEQ,MAAAqB,CAAOhQ,GACb,MAAMwQ,EAAQrM,WAAW,KACvBzuB,KAAKs5B,mBAAmBpF,OAAO4G,GAC/BxQ,KACC,GAEH,OADAtqB,KAAKs5B,mBAAmB34B,IAAIm6B,GACrBA,CACT,CAEQ,oBAAAvB,CAAqBuB,QACbl2B,IAAVk2B,IAGJ3M,aAAa2M,GACb96B,KAAKs5B,mBAAmBpF,OAAO4G,GACjC,CAQQ,yBAAAK,GACN,GAAIn7B,KAAK85B,qBACP,OAEF,MAAM6D,EAAW39B,KAAK24B,UAAUluB,MAChCzK,KAAK85B,qBAAuB5iB,OAAOuX,WAAW,KAG5C,GAFAzuB,KAAK85B,0BAAuBl1B,GAEvB5E,KAAKq4B,aAAc,CACtB,MAAMuF,EAAW59B,KAAK24B,UAAUluB,MAE1BgoB,EAAOmL,EAAS9zB,QAAQ6zB,EAAU,IAExC39B,KAAK+4B,iBAAmBtG,EAEpBmL,EAASr8B,OAASo8B,EAASp8B,OAC7BvB,KAAKovB,aAAa5kB,iBAAiBioB,GAAM,GAChCmL,EAASr8B,OAASo8B,EAASp8B,OACpCvB,KAAKovB,aAAa5kB,iBAAiB,KAAa,GACtCozB,EAASr8B,SAAWo8B,EAASp8B,QAAYq8B,IAAaD,GAChE39B,KAAKovB,aAAa5kB,iBAAiBozB,GAAU,EAGjD,GACC,EACL,CAQO,yBAAAxnB,CAA0BynB,GAC/B,GAAK79B,KAAKq4B,aAAV,CAIA,GAAIr4B,KAAK8R,eAAe3N,OAAOkQ,mBAAoB,CACjD,MAAMK,EAAUC,KAAKC,IAAI5U,KAAK8R,eAAe3N,OAAO0Q,EAAG7U,KAAK8R,eAAe7J,KAAO,GAE5E6M,EAAa9U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OACrDsM,EAAYjV,KAAK8R,eAAe3N,OAAOgQ,EAAInU,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OACnFuM,EAAaR,EAAU1U,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAErE/I,KAAKoZ,iBAAiBtQ,MAAMgC,KAAOoK,EAAa,KAChDlV,KAAKoZ,iBAAiBtQ,MAAMkC,IAAMiK,EAAY,KAC9CjV,KAAKoZ,iBAAiBtQ,MAAMH,OAASmM,EAAa,KAClD9U,KAAKoZ,iBAAiBtQ,MAAMqM,WAAaL,EAAa,KACtD9U,KAAKoZ,iBAAiBtQ,MAAMg1B,WAAa99B,KAAKkqB,gBAAgB5f,WAAWwzB,WACzE99B,KAAKoZ,iBAAiBtQ,MAAMG,SAAWjJ,KAAKkqB,gBAAgB5f,WAAWrB,SAAW,KAGlF,MAAM80B,EAAW/9B,KAAK8R,eAAe7J,KAAOjI,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MAAQmM,EAC5FlV,KAAKoZ,iBAAiBtQ,MAAMi1B,SAAWA,EAAW,KAClD/9B,KAAKoZ,iBAAiBtQ,MAAMk1B,SAAW,SACvCh+B,KAAKoZ,iBAAiBtQ,MAAMm1B,UAAY,MAGxC,MAAMC,EAAwBl+B,KAAKoZ,iBAAiBhQ,wBACpDpJ,KAAK24B,UAAU7vB,MAAMgC,KAAOoK,EAAa,KACzClV,KAAK24B,UAAU7vB,MAAMkC,IAAMiK,EAAY,KAEvCjV,KAAK24B,UAAU7vB,MAAMC,MAAQ4L,KAAKkZ,IAAIqQ,EAAsBn1B,MAAO,GAAK,KACxE/I,KAAK24B,UAAU7vB,MAAMH,OAASgM,KAAKkZ,IAAIqQ,EAAsBv1B,OAAQ,GAAK,KAC1E3I,KAAK24B,UAAU7vB,MAAMqM,WAAa+oB,EAAsBv1B,OAAS,IACnE,CAEKk1B,IACH79B,KAAKu5B,qBAAqBv5B,KAAKy5B,uBAC/Bz5B,KAAKy5B,sBAAwBz5B,KAAKs6B,OAAO,IAAMt6B,KAAKoW,2BAA0B,IAlChF,CAoCF,6CArtBWlC,EAAiB3K,EAAA,CAyEzBC,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,EAAAlK,EAAAqzB,cACAnpB,EAAA,EAAAnK,EAAAsK,iBA5EQuK,cCpCb,SAAAiqB,EAA2CjnB,EAA0C3I,EAA2CzM,GAC9H,MAAMs8B,EAAOt8B,EAAQsH,wBACfi1B,EAAennB,EAAOonB,iBAAiBx8B,GACvCy8B,EAAc12B,SAASw2B,EAAaG,iBAAiB,gBAAiB,IACtEC,EAAa52B,SAASw2B,EAAaG,iBAAiB,eAAgB,IAC1E,MAAO,CACLjwB,EAAMxD,QAAUqzB,EAAKtzB,KAAOyzB,EAC5BhwB,EAAMtD,QAAUmzB,EAAKpzB,IAAMyzB,EAE/B,6FAkBA,SAA0BvnB,EAA0C3I,EAAgDzM,EAAsB48B,EAAkBjR,EAAkBkR,EAA2BC,EAAsBC,EAAuBC,GAEpP,IAAKH,EACH,OAGF,MAAMnV,EAAS2U,EAA2BjnB,EAAQ3I,EAAOzM,GAUzD,OATA0nB,EAAO,GAAK7U,KAAKoiB,MAAMvN,EAAO,IAAMsV,EAAcF,EAAe,EAAI,IAAMA,GAC3EpV,EAAO,GAAK7U,KAAKoiB,KAAKvN,EAAO,GAAKqV,GAKlCrV,EAAO,GAAK7U,KAAKC,IAAID,KAAKkZ,IAAIrE,EAAO,GAAI,GAAIkV,GAAYI,EAAc,EAAI,IAC3EtV,EAAO,GAAK7U,KAAKC,IAAID,KAAKkZ,IAAIrE,EAAO,GAAI,GAAIiE,GAEtCjE,CACT,aC6BA,SAASuV,EAAmBlT,EAAgBmT,EAAiBC,EAA+BC,GAC1F,MAAM5W,EAAWuD,EAASsT,EAAkBtT,EAAQoT,GAC9C1W,EAASyW,EAAUG,EAAkBH,EAASC,GAE9CG,EAAazqB,KAAK0qB,IAAI/W,EAAWC,GAiCzC,SAA0BsD,EAAgBmT,EAAiBC,GACzD,IAAIK,EAAc,EAClB,MAAMhX,EAAWuD,EAASsT,EAAkBtT,EAAQoT,GAC9C1W,EAASyW,EAAUG,EAAkBH,EAASC,GAEpD,IAAK,IAAIngC,EAAI,EAAGA,EAAI6V,KAAK0qB,IAAI/W,EAAWC,GAASzpB,IAAK,CACpD,MAAMm/B,EAA8C,MAAlCsB,EAAkB1T,EAAQmT,IAA6B,EAAI,EACvEz6B,EAAO06B,EAAc96B,OAAOE,MAAMP,IAAIwkB,EAAY2V,EAAYn/B,GAChEyF,GAAM2nB,WACRoT,GAEJ,CAEA,OAAOA,CACT,CA/CmDE,CAAiB3T,EAAQmT,EAASC,GAEnF,OAAOQ,EAAOL,EAAYM,EAASH,EAAkB1T,EAAQmT,GAAUE,GACzE,CAkDA,SAASC,EAAkBQ,EAAoBV,GAC7C,IAAIxR,EAAW,EACXlpB,EAAO06B,EAAc96B,OAAOE,MAAMP,IAAI67B,GACtCC,EAAYr7B,GAAM2nB,UAEtB,KAAO0T,GAAaD,GAAc,GAAKA,EAAaV,EAAcl+B,MAChE0sB,IACAlpB,EAAO06B,EAAc96B,OAAOE,MAAMP,MAAM67B,GACxCC,EAAYr7B,GAAM2nB,UAGpB,OAAOuB,CACT,CA6BA,SAAS8R,EAAkB1T,EAAgBmT,GACzC,OAAOnT,EAASmT,EAAS,IAAe,GAC1C,CAWA,SAASvqB,EACPorB,EACAvX,EACAwX,EACAvX,EACA1W,EACAotB,GAEA,IAAIc,EAAaF,EACbF,EAAarX,EACb0X,EAAY,GAEhB,MAAQD,IAAeD,GAAUH,IAAepX,IACzCoX,GAAc,GACdA,EAAaV,EAAc96B,OAAOE,MAAM9C,QAC7Cw+B,GAAcluB,EAAU,GAAK,EAEzBA,GAAWkuB,EAAad,EAAch3B,KAAO,GAC/C+3B,GAAaf,EAAc96B,OAAO87B,4BAChCN,GAAY,EAAOE,EAAUE,GAE/BA,EAAa,EACbF,EAAW,EACXF,MACU9tB,GAAWkuB,EAAa,IAClCC,GAAaf,EAAc96B,OAAO87B,4BAChCN,GAAY,EAAO,EAAGE,EAAW,GAEnCE,EAAad,EAAch3B,KAAO,EAClC43B,EAAWE,EACXJ,KAIJ,OAAOK,EAAYf,EAAc96B,OAAO87B,4BACtCN,GAAY,EAAOE,EAAUE,EAEjC,CAMA,SAASL,EAASzB,EAAsBiB,GAEtC,MAAO,KADMA,EAAoB,IAAM,KACjBjB,CACxB,CAQA,SAASwB,EAAOS,EAAeC,GAC7BD,EAAQvrB,KAAKkiB,MAAMqJ,GACnB,IAAIE,EAAM,GACV,IAAK,IAAIthC,EAAI,EAAGA,EAAIohC,EAAOphC,IACzBshC,GAAOD,EAET,OAAOC,CACT,uEAtOA,SAAmCC,EAAiBrB,EAAiBC,EAA+BC,GAClG,MAAMxX,EAASuX,EAAc96B,OAAO0Q,EAC9BgX,EAASoT,EAAc96B,OAAOgQ,EAGpC,IAAK8qB,EAAc96B,OAAOm8B,cACxB,OAsCJ,SAA0B5Y,EAAgBmE,EAAgBwU,EAAiBrB,EAAiBC,EAA+BC,GACzH,OAAqF,IAAjFH,EAAmBlT,EAAQmT,EAASC,EAAeC,GAAmB39B,OACjE,GAEFk+B,EAAOhrB,EACZiT,EAAQmE,EAAQnE,EAChBmE,EAASsT,EAAkBtT,EAAQoT,IAAgB,EAAOA,GAC1D19B,OAAQm+B,EAAQ,IAAiBR,GACrC,CA9CWqB,CAAiB7Y,EAAQmE,EAAQwU,EAASrB,EAASC,EAAeC,GACvEH,EAAmBlT,EAAQmT,EAASC,EAAeC,GA+DzD,SAA4BxX,EAAgBmE,EAAgBwU,EAAiBrB,EAAiBC,EAA+BC,GAC3H,IAAI5W,EAEFA,EADEyW,EAAmBlT,EAAQmT,EAASC,EAAeC,GAAmB39B,OAAS,EACtEy9B,EAAUG,EAAkBH,EAASC,GAErCpT,EAGb,MAAMtD,EAASyW,EACTf,EAyDR,SAA6BvW,EAAgBmE,EAAgBwU,EAAiBrB,EAAiBC,EAA+BC,GAC5H,IAAI5W,EAOJ,OALEA,EADEyW,EAAmBlT,EAAQmT,EAASC,EAAeC,GAAmB39B,OAAS,EACtEy9B,EAAUG,EAAkBH,EAASC,GAErCpT,EAGRnE,EAAS2Y,GACZ/X,GAAY0W,GACXtX,GAAU2Y,GACX/X,EAAW0W,EACX,IAEF,GACF,CAxEoBwB,CAAoB9Y,EAAQmE,EAAQwU,EAASrB,EAASC,EAAeC,GAEvF,OAAOO,EAAOhrB,EACZiT,EAAQY,EAAU+X,EAAS9X,EAClB,MAAT0V,EAA+BgB,GAC/B19B,OAAQm+B,EAASzB,EAAWiB,GAChC,CA7EMuB,CAAmB/Y,EAAQmE,EAAQwU,EAASrB,EAASC,EAAeC,GAIxE,IAAIjB,EACJ,GAAIpS,IAAWmT,EAEb,OADAf,EAAYvW,EAAS2Y,EAAS,IAAiB,IACxCZ,EAAO9qB,KAAK0qB,IAAI3X,EAAS2Y,GAAUX,EAASzB,EAAWiB,IAEhEjB,EAAYpS,EAASmT,EAAS,IAAiB,IAC/C,MAAM0B,EAAgB/rB,KAAK0qB,IAAIxT,EAASmT,GAIxC,OAAOS,EAaT,SAAwBkB,EAAe1B,GACrC,OAAOA,EAAch3B,KAAO04B,CAC9B,CAlBsBC,CAAe/U,EAASmT,EAAUqB,EAAU3Y,EAAQuX,IACrEyB,EAAgB,GAAKzB,EAAch3B,KAAO,IACtB4jB,EAASmT,EAAUtX,EAAS2Y,GAQpC,GAPYX,EAASzB,EAAWiB,GACjD,82BCtCA,MAAYlgC,EAAOC,EAAAC,EAAA,OACnB2hC,EAAA3hC,EAAA,MAEAE,EAAAF,EAAA,MAEA4hC,EAAA5hC,EAAA,MACA6hC,EAAA7hC,EAAA,MACA8hC,EAAA9hC,EAAA,MACA+hC,EAAA/hC,EAAA,MAOMgiC,EAA2B,CAAC,OAAQ,QAE1C,IAAIC,EAAS,EAEb,MAAAC,UAA8BhiC,EAAAK,WAO5B,WAAAC,CAAYwJ,GACVnJ,QAEAC,KAAKqhC,MAAQrhC,KAAK0B,UAAU,IAAIm/B,EAAA5yB,oBAAa/E,IAC7ClJ,KAAKshC,cAAgBthC,KAAK0B,UAAU,IAAIo/B,EAAAS,cAExCvhC,KAAKwhC,eAAiB,IAAMxhC,KAAKqhC,MAAMn4B,SACvC,MAAMu4B,EAAUC,GACP1hC,KAAKqhC,MAAMn4B,QAAQw4B,GAEtBC,EAAS,CAACD,EAAkBj3B,KAChCzK,KAAK4hC,sBAAsBF,GAC3B1hC,KAAKqhC,MAAMn4B,QAAQw4B,GAAYj3B,GAGjC,IAAK,MAAMi3B,KAAY1hC,KAAKqhC,MAAMn4B,QAAS,CACzC,MAAM24B,EAAO,CACX/9B,IAAK29B,EAAO5/B,KAAK7B,KAAM0hC,GACvB58B,IAAK68B,EAAO9/B,KAAK7B,KAAM0hC,IAEzB94B,OAAOk5B,eAAe9hC,KAAKwhC,eAAgBE,EAAUG,EACvD,CACF,CAEQ,qBAAAD,CAAsBF,GAI5B,GAAIR,EAAyBzV,SAASiW,GACpC,MAAM,IAAI3/B,MAAM,WAAW2/B,wCAE/B,CAEQ,iBAAAK,GACN,IAAK/hC,KAAKqhC,MAAMj3B,eAAeE,WAAW03B,iBACxC,MAAM,IAAIjgC,MAAM,uEAEpB,CAEA,UAAW+N,GAAyB,OAAO9P,KAAKqhC,MAAMvxB,MAAQ,CAC9D,YAAWmyB,GAA6B,OAAOjiC,KAAKqhC,MAAMY,QAAU,CACpE,gBAAW1yB,GAA+B,OAAOvP,KAAKqhC,MAAM9xB,YAAc,CAC1E,UAAW2yB,GAA2B,OAAOliC,KAAKqhC,MAAMa,MAAQ,CAChE,SAAWn/B,GAA4D,OAAO/C,KAAKqhC,MAAMt+B,KAAO,CAChG,cAAWJ,GAA6B,OAAO3C,KAAKqhC,MAAM1+B,UAAY,CACtE,YAAWR,GAAqD,OAAOnC,KAAKqhC,MAAMl/B,QAAU,CAC5F,YAAWF,GAAqD,OAAOjC,KAAKqhC,MAAMp/B,QAAU,CAC5F,YAAWM,GAA6B,OAAOvC,KAAKqhC,MAAM9+B,QAAU,CACpE,qBAAWmN,GAAoC,OAAO1P,KAAKqhC,MAAM3xB,iBAAmB,CACpF,iBAAWE,GAAkC,OAAO5P,KAAKqhC,MAAMzxB,aAAe,CAC9E,iBAAWuyB,GAAgC,OAAOniC,KAAKqhC,MAAMc,aAAe,CAC5E,sBAAW/+B,GAAkD,OAAOpD,KAAKqhC,MAAMj+B,kBAAoB,CAEnG,WAAWtB,GAAqC,OAAO9B,KAAKqhC,MAAMv/B,OAAS,CAC3E,iBAAW8I,GAA2C,OAAO5K,KAAKqhC,MAAMz2B,aAAe,CACvF,UAAWw3B,GACT,OAAOpiC,KAAKqiC,UAAY,IAAIrB,EAAAsB,UAAUtiC,KAAKqhC,MAC7C,CACA,WAAWkB,GAET,OADAviC,KAAK+hC,oBACE,IAAId,EAAAuB,WAAWxiC,KAAKqhC,MAC7B,CACA,YAAWn3B,GAA8C,OAAOlK,KAAKqhC,MAAMn3B,QAAU,CACrF,QAAWnJ,GAAiB,OAAOf,KAAKqhC,MAAMtgC,IAAM,CACpD,QAAWkH,GAAiB,OAAOjI,KAAKqhC,MAAMp5B,IAAM,CACpD,UAAW9D,GACT,OAAOnE,KAAKyiC,UAAYziC,KAAK0B,UAAU,IAAIq/B,EAAA2B,mBAAmB1iC,KAAKqhC,OACrE,CACA,WAAWvjB,GACT,OAAO9d,KAAKqhC,MAAMvjB,OACpB,CACA,SAAW6kB,GACT,MAAMC,EAAI5iC,KAAKqhC,MAAMl3B,YAAYE,gBACjC,IAAIw4B,EAA+D,OACnE,OAAQ7iC,KAAKqhC,MAAMjmB,kBAAkB0nB,gBACnC,IAAK,MAAOD,EAAoB,MAAO,MACvC,IAAK,QAASA,EAAoB,QAAS,MAC3C,IAAK,OAAQA,EAAoB,OAAQ,MACzC,IAAK,MAAOA,EAAoB,MAElC,MAAO,CACLE,0BAA2BH,EAAEI,sBAC7BC,sBAAuBL,EAAEM,kBACzBl5B,mBAAoB44B,EAAE54B,mBACtBm5B,WAAYnjC,KAAKqhC,MAAMl3B,YAAYw4B,MAAMQ,WACzCN,kBAAmBA,EACnBO,WAAYR,EAAES,OACdC,sBAAuBV,EAAEW,kBACzBC,cAAeZ,EAAE/uB,UACjB4vB,YAAazjC,KAAKqhC,MAAMl3B,YAAYu5B,eACpCC,uBAAwBf,EAAEtQ,mBAC1BsR,eAAgBhB,EAAEgB,eAClBC,eAAgBjB,EAAEkB,WAEtB,CACA,cAAWt7B,GACT,OAAOxI,KAAKqhC,MAAM74B,UACpB,CACA,WAAWU,GACT,OAAOlJ,KAAKwhC,cACd,CACA,WAAWt4B,CAAQA,GACjB,IAAK,MAAMw4B,KAAYx4B,EACrBlJ,KAAKwhC,eAAeE,GAAYx4B,EAAQw4B,EAE5C,CACO,IAAA3tB,GACL/T,KAAKqhC,MAAMttB,MACb,CACO,KAAAhO,GACL/F,KAAKqhC,MAAMt7B,OACb,CACO,KAAAya,CAAMvD,EAAc8mB,GAAwB,GACjD/jC,KAAKqhC,MAAM7gB,MAAMvD,EAAM8mB,EACzB,CACO,MAAA5qB,CAAO1U,EAAiB1D,GAC7Bf,KAAKgkC,gBAAgBv/B,EAAS1D,GAC9Bf,KAAKqhC,MAAMloB,OAAO1U,EAAS1D,EAC7B,CACO,IAAA4V,CAAKC,GACV5W,KAAKqhC,MAAM1qB,KAAKC,EAClB,CACO,2BAAAsG,CAA4BC,GACjCnd,KAAKqhC,MAAMnkB,4BAA4BC,EACzC,CACO,6BAAAC,CAA8BC,GACnCrd,KAAKqhC,MAAMjkB,8BAA8BC,EAC3C,CACO,oBAAAxM,CAAqB0M,GAC1B,OAAOvd,KAAKqhC,MAAMxwB,qBAAqB0M,EACzC,CACO,uBAAAC,CAAwBC,GAC7B,OAAOzd,KAAKqhC,MAAM7jB,wBAAwBC,EAC5C,CACO,yBAAAG,CAA0BF,GAC/B1d,KAAKqhC,MAAMzjB,0BAA0BF,EACvC,CACO,cAAAK,CAAeC,EAAwB,GAE5C,OADAhe,KAAKgkC,gBAAgBhmB,GACdhe,KAAKqhC,MAAMtjB,eAAeC,EACnC,CACO,kBAAAE,CAAmBC,GAExB,OADAne,KAAKikC,wBAAwB9lB,EAAkBtJ,GAAK,EAAGsJ,EAAkBpV,OAAS,EAAGoV,EAAkBxV,QAAU,GAC1G3I,KAAKqhC,MAAMnjB,mBAAmBC,EACvC,CACO,YAAA7I,GACL,OAAOtV,KAAKqhC,MAAM/rB,cACpB,CACO,MAAAlN,CAAOJ,EAAgBJ,EAAarG,GACzCvB,KAAKgkC,gBAAgBh8B,EAAQJ,EAAKrG,GAClCvB,KAAKqhC,MAAMj5B,OAAOJ,EAAQJ,EAAKrG,EACjC,CACO,YAAA4E,GACL,OAAOnG,KAAKqhC,MAAMl7B,cACpB,CACO,oBAAAkY,GACL,OAAOre,KAAKqhC,MAAMhjB,sBACpB,CACO,cAAA9X,GACLvG,KAAKqhC,MAAM96B,gBACb,CACO,SAAAiY,GACLxe,KAAKqhC,MAAM7iB,WACb,CACO,WAAAC,CAAYpc,EAAeC,GAChCtC,KAAKgkC,gBAAgB3hC,EAAOC,GAC5BtC,KAAKqhC,MAAM5iB,YAAYpc,EAAOC,EAChC,CACO,OAAA+W,GACLtZ,MAAMsZ,SACR,CACO,WAAAvT,CAAY2U,GACjBza,KAAKgkC,gBAAgBvpB,GACrBza,KAAKqhC,MAAMv7B,YAAY2U,EACzB,CACO,WAAAiC,CAAYC,GACjB3c,KAAKgkC,gBAAgBrnB,GACrB3c,KAAKqhC,MAAM3kB,YAAYC,EACzB,CACO,WAAAC,GACL5c,KAAKqhC,MAAMzkB,aACb,CACO,cAAAC,GACL7c,KAAKqhC,MAAMxkB,gBACb,CACO,YAAAE,CAAaxY,GAClBvE,KAAKgkC,gBAAgBz/B,GACrBvE,KAAKqhC,MAAMtkB,aAAaxY,EAC1B,CACO,KAAA8H,GACLrM,KAAKqhC,MAAMh1B,OACb,CACO,KAAA63B,CAAMjnB,EAA2BqN,GACtCtqB,KAAKqhC,MAAM6C,MAAMjnB,EAAMqN,EACzB,CACO,OAAA6Z,CAAQlnB,EAA2BqN,GACxCtqB,KAAKqhC,MAAM6C,MAAMjnB,GACjBjd,KAAKqhC,MAAM6C,MAAM,OAAQ5Z,EAC3B,CACO,KAAArgB,CAAMgT,GACXjd,KAAKqhC,MAAMp3B,MAAMgT,EACnB,CACO,OAAA/Y,CAAQ7B,EAAeC,GAC5BtC,KAAKgkC,gBAAgB3hC,EAAOC,GAC5BtC,KAAKqhC,MAAMn9B,QAAQ7B,EAAOC,EAC5B,CACO,KAAAgP,GACLtR,KAAKqhC,MAAM/vB,OACb,CACO,iBAAAwP,GACL9gB,KAAKqhC,MAAMvgB,mBACb,CACO,SAAAsjB,CAAUC,GACfrkC,KAAKshC,cAAc8C,UAAUpkC,KAAMqkC,EACrC,CACO,kBAAWC,GAEhB,MAAO,CACL,eAAIvsB,GAAwB,OAAO/Y,EAAQ+Y,YAAYjU,KAAO,EAC9D,eAAIiU,CAAYtN,GAAiBzL,EAAQ+Y,YAAYjT,IAAI2F,EAAQ,EACjE,iBAAI5G,GAA0B,OAAO7E,EAAQ6E,cAAcC,KAAO,EAClE,iBAAID,CAAc4G,GAAiBzL,EAAQ6E,cAAciB,IAAI2F,EAAQ,EAEzE,CAEQ,eAAAu5B,IAAmBO,GACzB,IAAKpD,KAAUoD,EACb,GAAIpD,IAAWqD,KAAY18B,MAAMq5B,IAAWA,EAAS,GAAM,EACzD,MAAM,IAAIp/B,MAAM,iCAGtB,CAEQ,uBAAAkiC,IAA2BM,GACjC,IAAKpD,KAAUoD,EACb,GAAIpD,IAAWA,IAAWqD,KAAY18B,MAAMq5B,IAAWA,EAAS,GAAM,GAAKA,EAAS,GAClF,MAAM,IAAIp/B,MAAM,0CAGtB,ugBCzQF,MAAA0iC,EAAAvlC,EAAA,MACAwlC,EAAAxlC,EAAA,MACAylC,EAAAzlC,EAAA,MACA0lC,EAAA1lC,EAAA,MACA2lC,EAAA3lC,EAAA,MACA4lC,EAAA5lC,EAAA,KAEAG,EAAAH,EAAA,MAEAqO,EAAArO,EAAA,MACAE,EAAAF,EAAA,MACAI,EAAAJ,EAAA,MACA8O,EAAA9O,EAAA,MACAK,EAAAL,EAAA,MAaA,IAAI6lC,EAAiB,EAOR3oB,EAAN,cAA0Bhd,EAAAK,WAwB/B,WAAAC,CACmBC,EACAwX,EACA8N,EACA4N,EACAjb,EACAE,EACAktB,EACMplC,EACYyY,EACD6R,EACDpY,EACFsd,EACOvvB,EACNoS,GAEhClS,QAfiBC,KAAAL,UAAAA,EACAK,KAAAmX,UAAAA,EACAnX,KAAAilB,SAAAA,EACAjlB,KAAA6yB,eAAAA,EACA7yB,KAAA4X,iBAAAA,EACA5X,KAAA8X,iBAAAA,EACA9X,KAAAglC,YAAAA,EAEkBhlC,KAAAqY,iBAAAA,EACDrY,KAAAkqB,gBAAAA,EACDlqB,KAAA8R,eAAAA,EACF9R,KAAAovB,aAAAA,EACOpvB,KAAAH,oBAAAA,EACNG,KAAAiS,cAAAA,EApC1BjS,KAAAilC,eAAyBF,IAKzB/kC,KAAAc,aAA8B,GAG9Bd,KAAAklC,uBAA+C,EAAAL,EAAAM,8BAG/CnlC,KAAAolC,0BAAoC,EAGpCplC,KAAAqlC,qBAAkC,GAClCrlC,KAAAslC,0BAAoC,EAI3BtlC,KAAAulC,iBAAmBvlC,KAAK0B,UAAU,IAAIsM,EAAAsB,SACvCtP,KAAA2a,gBAAkB3a,KAAKulC,iBAAiBh3B,MAmBtDvO,KAAKY,cAAgBZ,KAAKmX,UAAU1W,cAAc,OAClDT,KAAKY,cAAcF,UAAUC,IAAG,cAChCX,KAAKY,cAAckI,MAAMqM,WAAa,SACtCnV,KAAKY,cAAcC,aAAa,cAAe,QAC/Cb,KAAKwlC,oBAAoBxlC,KAAK8R,eAAe7J,KAAMjI,KAAK8R,eAAe/Q,MACvEf,KAAKylC,oBAAsBzlC,KAAKmX,UAAU1W,cAAc,OACxDT,KAAKylC,oBAAoB/kC,UAAUC,IAAG,mBACtCX,KAAKylC,oBAAoB5kC,aAAa,cAAe,QAErDb,KAAKwI,YAAa,EAAAo8B,EAAAc,0BAClB1lC,KAAK2lC,oBACL3lC,KAAK0B,UAAU1B,KAAKkqB,gBAAgB0b,eAAe,IAAM5lC,KAAK6lC,0BAE9D7lC,KAAK0B,UAAU1B,KAAKiS,cAAc0G,eAAexX,GAAKnB,KAAK8lC,WAAW3kC,KACtEnB,KAAK8lC,WAAW9lC,KAAKiS,cAAcQ,QAEnCzS,KAAK+lC,YAAcnmC,EAAqBuQ,eAAes0B,EAAAuB,sBAAuB5tB,UAE9EpY,KAAKilB,SAASvkB,UAAUC,IAAI,4BAAkCX,KAAKilC,gBACnEjlC,KAAK6yB,eAAe5xB,YAAYjB,KAAKY,eACrCZ,KAAK6yB,eAAe5xB,YAAYjB,KAAKylC,qBAErCzlC,KAAK0B,UAAU1B,KAAKglC,YAAYzf,oBAAoBpkB,GAAKnB,KAAKimC,iBAAiB9kC,KAC/EnB,KAAK0B,UAAU1B,KAAKglC,YAAYvf,oBAAoBtkB,GAAKnB,KAAKkmC,iBAAiB/kC,KAE/EnB,KAAKmmC,yBAA2B,IAAIC,EAAwBpmC,KAAKY,cAAeZ,KAAKH,qBACrFG,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAKmX,UAAW,YAAa,IAAMnX,KAAKmmC,yBAAyBE,0BACtGrmC,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKmmC,yBAAyB9sB,YAChErZ,KAAKsmC,uBAAyBtmC,KAAK0B,UAAU,IAAIojC,EAAAyB,sBAC/C,IAAMvmC,KAAKulC,iBAAiBt0B,KAAK,CAAE5O,MAAO,EAAGC,IAAKtC,KAAK8R,eAAe/Q,KAAO,IAC7Ef,KAAKH,oBACLG,KAAKkqB,kBAGPlqB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKilB,SAASvkB,UAAUgD,OAAO,4BAAkC1D,KAAKilC,gBAItEjlC,KAAKY,cAAc8C,SACnB1D,KAAKylC,oBAAoB/hC,SACzB1D,KAAKwmC,YAAYntB,UACjBrZ,KAAKymC,mBAAmB/iC,SACxB1D,KAAK0mC,wBAAwBhjC,YAG/B1D,KAAKwmC,YAAc,IAAI9B,EAAAiC,WACvB3mC,KAAKwmC,YAAYI,QACf5mC,KAAKkqB,gBAAgB5f,WAAWwzB,WAChC99B,KAAKkqB,gBAAgB5f,WAAWrB,SAChCjJ,KAAKkqB,gBAAgB5f,WAAWu8B,WAChC7mC,KAAKkqB,gBAAgB5f,WAAWw8B,gBAElC9mC,KAAK+mC,oBACP,CAEQ,iBAAApB,GACN,MAAM3O,EAAMh3B,KAAKH,oBAAoBm3B,IACrCh3B,KAAKwI,WAAWqG,OAAOpM,KAAKsG,MAAQ/I,KAAKqY,iBAAiBtP,MAAQiuB,EAClEh3B,KAAKwI,WAAWqG,OAAOpM,KAAKkG,OAASgM,KAAKoiB,KAAK/2B,KAAKqY,iBAAiB1P,OAASquB,GAC9Eh3B,KAAKwI,WAAWqG,OAAOnG,KAAKK,MAAQ/I,KAAKwI,WAAWqG,OAAOpM,KAAKsG,MAAQ4L,KAAK6d,MAAMxyB,KAAKkqB,gBAAgB5f,WAAW08B,eACnHhnC,KAAKwI,WAAWqG,OAAOnG,KAAKC,OAASgM,KAAKkiB,MAAM72B,KAAKwI,WAAWqG,OAAOpM,KAAKkG,OAAS3I,KAAKkqB,gBAAgB5f,WAAW6K,YACrHnV,KAAKwI,WAAWqG,OAAOpM,KAAKqI,KAAO,EACnC9K,KAAKwI,WAAWqG,OAAOpM,KAAKuI,IAAM,EAClChL,KAAKwI,WAAWqG,OAAO7F,OAAOD,MAAQ/I,KAAKwI,WAAWqG,OAAOnG,KAAKK,MAAQ/I,KAAK8R,eAAe7J,KAC9FjI,KAAKwI,WAAWqG,OAAO7F,OAAOL,OAAS3I,KAAKwI,WAAWqG,OAAOnG,KAAKC,OAAS3I,KAAK8R,eAAe/Q,KAChGf,KAAKwI,WAAWC,IAAIO,OAAOD,MAAQ4L,KAAK6d,MAAMxyB,KAAKwI,WAAWqG,OAAO7F,OAAOD,MAAQiuB,GACpFh3B,KAAKwI,WAAWC,IAAIO,OAAOL,OAASgM,KAAK6d,MAAMxyB,KAAKwI,WAAWqG,OAAO7F,OAAOL,OAASquB,GACtFh3B,KAAKwI,WAAWC,IAAIC,KAAKK,MAAQ/I,KAAKwI,WAAWC,IAAIO,OAAOD,MAAQ/I,KAAK8R,eAAe7J,KACxFjI,KAAKwI,WAAWC,IAAIC,KAAKC,OAAS3I,KAAKwI,WAAWC,IAAIO,OAAOL,OAAS3I,KAAK8R,eAAe/Q,KAE1F,IAAK,MAAMe,KAAW9B,KAAKc,aACzBgB,EAAQgH,MAAMC,MAAQ,GAAG/I,KAAKwI,WAAWC,IAAIO,OAAOD,UACpDjH,EAAQgH,MAAMH,OAAS,GAAG3I,KAAKwI,WAAWC,IAAIC,KAAKC,WACnD7G,EAAQgH,MAAMqM,WAAa,GAAGnV,KAAKwI,WAAWC,IAAIC,KAAKC,WAEvD7G,EAAQgH,MAAMk1B,SAAW,SAGtBh+B,KAAK0mC,0BACR1mC,KAAK0mC,wBAA0B1mC,KAAKmX,UAAU1W,cAAc,SAC5DT,KAAK6yB,eAAe5xB,YAAYjB,KAAK0mC,0BAGvC,MAAMO,EACJ,GAAGjnC,KAAKknC,kGAMVlnC,KAAK0mC,wBAAwB9iC,YAAcqjC,EAE3CjnC,KAAKylC,oBAAoB38B,MAAMH,OAAS3I,KAAK4X,iBAAiB9O,MAAMH,OACpE3I,KAAK6yB,eAAe/pB,MAAMC,MAAQ,GAAG/I,KAAKwI,WAAWC,IAAIO,OAAOD,UAChE/I,KAAK6yB,eAAe/pB,MAAMH,OAAS,GAAG3I,KAAKwI,WAAWC,IAAIO,OAAOL,UACnE,CAEQ,UAAAm9B,CAAWrzB,GACZzS,KAAKymC,qBACRzmC,KAAKymC,mBAAqBzmC,KAAKmX,UAAU1W,cAAc,SACvDT,KAAK6yB,eAAe5xB,YAAYjB,KAAKymC,qBAIvC,IAAIQ,EACF,GAAGjnC,KAAKknC,gEAKGz0B,EAAOc,WAAW9K,QAE/Bw+B,GACE,GAAGjnC,KAAKknC,kCAAwDlnC,KAAKknC,qDACpDlnC,KAAKkqB,gBAAgB5f,WAAWwzB,0BAClC99B,KAAKkqB,gBAAgB5f,WAAWrB,oDAIjDg+B,GACE,GAAGjnC,KAAKknC,qDACG35B,EAAAgF,MAAM40B,gBAAgB10B,EAAOc,WAAY,IAAK9K,QAG3Dw+B,GACE,GAAGjnC,KAAKknC,0DACSlnC,KAAKkqB,gBAAgB5f,WAAWu8B,eAE9C7mC,KAAKknC,oDACSlnC,KAAKkqB,gBAAgB5f,WAAWw8B,mBAE9C9mC,KAAKknC,6DAGLlnC,KAAKknC,mEAIV,MAAME,EAA4B,mBAAmBpnC,KAAKilC,iBACpDoC,EAAsB,aAAarnC,KAAKilC,iBACxCqC,EAAwB,eAAetnC,KAAKilC,iBAClDgC,GACE,cAAcG,6CAKhBH,GACE,cAAcI,kCAKhBJ,GACE,cAAcK,+BAES70B,EAAO80B,OAAO9+B,gBACzBgK,EAAO+0B,aAAa/+B,oDAIpBgK,EAAO80B,OAAO9+B,UAI5Bw+B,GACE,GAAGjnC,KAAKknC,kHACOE,2BAEZpnC,KAAKknC,4GACOG,2BAEZrnC,KAAKknC,8GACOI,2BAGZtnC,KAAKknC,wHAMLlnC,KAAKknC,sFACcz0B,EAAO80B,OAAO9+B,eACzBgK,EAAO+0B,aAAa/+B,QAE5BzI,KAAKknC,+GACcz0B,EAAO80B,OAAO9+B,0BACzBgK,EAAO+0B,aAAa/+B,mBAE5BzI,KAAKknC,yFACez0B,EAAO80B,OAAO9+B,8BAGlCzI,KAAKknC,8EACQlnC,KAAKkqB,gBAAgB5f,WAAWm9B,qBAAqBh1B,EAAO80B,OAAO9+B,cAEhFzI,KAAKknC,2FACez0B,EAAO80B,OAAO9+B,8DAKvCw+B,GACE,GAAGjnC,KAAKknC,+GAOLlnC,KAAKknC,wFAEcz0B,EAAOi1B,0BAA0Bj/B,QAEpDzI,KAAKknC,kFAEcz0B,EAAOk1B,kCAAkCl/B,QAGjE,IAAK,MAAO3J,EAAGkwB,KAAMvc,EAAOC,KAAKmU,UAC/BogB,GACE,GAAGjnC,KAAKknC,+BAAkDpoC,cAAckwB,EAAEvmB,SACvEzI,KAAKknC,+BAAkDpoC,wBAAkCyO,EAAAgF,MAAM40B,gBAAgBnY,EAAG,IAAKvmB,SACvHzI,KAAKknC,+BAAkDpoC,yBAAyBkwB,EAAEvmB,SAEzFw+B,GACE,GAAGjnC,KAAKknC,+BAAkDvC,EAAAiD,mCAAmCr6B,EAAAgF,MAAMs1B,OAAOp1B,EAAOY,YAAY5K,SAC1HzI,KAAKknC,+BAAkDvC,EAAAiD,6CAAuDr6B,EAAAgF,MAAM40B,gBAAgB55B,EAAAgF,MAAMs1B,OAAOp1B,EAAOY,YAAa,IAAK5K,SAC1KzI,KAAKknC,+BAAkDvC,EAAAiD,8CAA8Cn1B,EAAOc,WAAW9K,SAE5HzI,KAAKymC,mBAAmB7iC,YAAcqjC,CACxC,CAUQ,kBAAAF,GAEN,MAAMe,EAAU9nC,KAAKwI,WAAWC,IAAIC,KAAKK,MAAQ/I,KAAKwmC,YAAY1iC,IAAI,KAAK,GAAO,GAClF9D,KAAKY,cAAckI,MAAMk+B,cAAgB,GAAGc,MAC5C9nC,KAAK+lC,YAAYgC,eAAiBD,CACpC,CAEO,4BAAAE,GACLhoC,KAAK2lC,oBACL3lC,KAAKwmC,YAAYn6B,QACjBrM,KAAK+mC,oBACP,CAEQ,mBAAAvB,CAAoBv9B,EAAclH,GAExC,IAAK,IAAIjC,EAAIkB,KAAKc,aAAaS,OAAQzC,GAAKiC,EAAMjC,IAAK,CACrD,MAAM8I,EAAM5H,KAAKmX,UAAU1W,cAAc,OACzCT,KAAKY,cAAcK,YAAY2G,GAC/B5H,KAAKc,aAAamD,KAAK2D,GACvB5H,KAAKqlC,qBAAqBphC,MAAK,EACjC,CAEA,KAAOjE,KAAKc,aAAaS,OAASR,GAChCf,KAAKY,cAAc8E,YAAY1F,KAAKc,aAAa2E,OAC7CzF,KAAKqlC,qBAAqB5/B,OAC5BzF,KAAKslC,2BAGX,CAEO,YAAAxrB,CAAa7R,EAAclH,GAChCf,KAAKwlC,oBAAoBv9B,EAAMlH,GAC/Bf,KAAK2lC,oBACL3lC,KAAK4a,uBAAuB5a,KAAKklC,sBAAsB5mB,eAAgBte,KAAKklC,sBAAsB3mB,aAAcve,KAAKklC,sBAAsBrqB,iBAC7I,CAEO,qBAAAotB,GACLjoC,KAAK2lC,oBACL3lC,KAAKwmC,YAAYn6B,QACjBrM,KAAK+mC,oBACP,CAEO,UAAAhtB,GACL/Z,KAAKY,cAAcF,UAAUgD,OAAM,eACnC1D,KAAKmmC,yBAAyB+B,QAC9BloC,KAAKmoC,WAAW,EAAGnoC,KAAK8R,eAAe/Q,KAAO,EAChD,CAEO,WAAAiZ,GACLha,KAAKY,cAAcF,UAAUC,IAAG,eAChCX,KAAKmmC,yBAAyBiC,SAC9BpoC,KAAKmoC,WAAWnoC,KAAK8R,eAAe3N,OAAOgQ,EAAGnU,KAAK8R,eAAe3N,OAAOgQ,EAC3E,CAEO,8BAAAk0B,CAA+BC,GACpCtoC,KAAKsmC,uBAAuBiC,mBAAmBD,EACjD,CAEO,sBAAA1tB,CAAuBvY,EAAqCC,EAAmCuY,GACpG,MAAM9Z,EAAOf,KAAK8R,eAAe/Q,KAGjCf,KAAKylC,oBAAoB+C,kBACzBxoC,KAAK+lC,YAAYnrB,uBAAuBvY,EAAOC,EAAKuY,GAGpD,IAAI4tB,EAAmB,EACnBC,GAAkB,EAClB1oC,KAAK2oC,qBAAuB3oC,KAAK4oC,oBACnC5oC,KAAKklC,sBAAsB2D,OAAO7oC,KAAKL,UAAWK,KAAK2oC,oBAAqB3oC,KAAK4oC,kBAAmB5oC,KAAKolC,0BACrGplC,KAAKklC,sBAAsB5vB,eAC7BmzB,EAAmBzoC,KAAKklC,sBAAsB4D,uBAC9CJ,EAAiB1oC,KAAKklC,sBAAsB6D,uBAKhD,IAAIC,EAAmB,EACnBC,GAAkB,EACtB,IAAK5mC,IAAUC,EACb,OAGF,GADAtC,KAAKklC,sBAAsB2D,OAAO7oC,KAAKL,UAAW0C,EAAOC,EAAKuY,GAC1D7a,KAAKklC,sBAAsB5vB,aAAc,CAC3C,MAAM4zB,EAAmBlpC,KAAKklC,sBAAsBgE,iBAC9CC,EAAiBnpC,KAAKklC,sBAAsBiE,eAC5CL,EAAyB9oC,KAAKklC,sBAAsB4D,uBACpDC,EAAuB/oC,KAAKklC,sBAAsB6D,qBAExDC,EAAmBF,EACnBG,EAAiBF,EAGjB,MAAMK,EAAmBppC,KAAKmX,UAAUQ,yBAExC,GAAIkD,EAAkB,CACpB,MAAMwuB,EAAahnC,EAAM,GAAKC,EAAI,GAClC8mC,EAAiBnoC,YACfjB,KAAKspC,wBAAwBR,EAAwBO,EAAa/mC,EAAI,GAAKD,EAAM,GAAIgnC,EAAahnC,EAAM,GAAKC,EAAI,GAAIymC,EAAuBD,EAAyB,GAEzK,KAAO,CAEL,MAAMjJ,EAAWqJ,IAAqBJ,EAAyBzmC,EAAM,GAAK,EACpEy9B,EAASgJ,IAA2BK,EAAiB7mC,EAAI,GAAKtC,KAAK8R,eAAe7J,KACxFmhC,EAAiBnoC,YAAYjB,KAAKspC,wBAAwBR,EAAwBjJ,EAAUC,IAE5F,MAAMyJ,EAAkBR,EAAuBD,EAAyB,EAGxE,GAFAM,EAAiBnoC,YAAYjB,KAAKspC,wBAAwBR,EAAyB,EAAG,EAAG9oC,KAAK8R,eAAe7J,KAAMshC,IAE/GT,IAA2BC,EAAsB,CAEnD,MAAMS,EAAcL,IAAmBJ,EAAuBzmC,EAAI,GAAKtC,KAAK8R,eAAe7J,KAC3FmhC,EAAiBnoC,YAAYjB,KAAKspC,wBAAwBP,EAAsB,EAAGS,GACrF,CACF,CACAxpC,KAAKylC,oBAAoBxkC,YAAYmoC,EACvC,CAGA,IAAIK,EAAiB90B,KAAKC,IAAI6zB,EAAkBO,GAC5CU,EAAe/0B,KAAKkZ,IAAI6a,EAAgBO,GAE5C,GAAIS,GAAgB,EAAG,CAErBD,EAAiB90B,KAAKkZ,IAAI4b,EAAgB,GAC1CC,EAAe/0B,KAAKC,IAAI80B,EAAc3oC,EAAO,GAG7C,MACM4oC,EADS3pC,KAAK8R,eAAe3N,OACFgQ,EAC7BnU,KAAKklC,sBAAsB5vB,cAAgBq0B,GAAqB,GAAKA,EAAoB5oC,IAC3F0oC,EAAiB90B,KAAKC,IAAI60B,EAAgBE,GAC1CD,EAAe/0B,KAAKkZ,IAAI6b,EAAcC,IAGxC3pC,KAAKmoC,WAAWsB,EAAgBC,EAClC,CAGA1pC,KAAK2oC,oBAAsBtmC,EAC3BrC,KAAK4oC,kBAAoBtmC,EACzBtC,KAAKolC,yBAA2BvqB,CAClC,CAQQ,uBAAAyuB,CAAwB1hC,EAAagiC,EAAkBC,EAAgBpc,EAAmB,GAChG,MAAM3rB,EAAU9B,KAAKmX,UAAU1W,cAAc,OACvCqK,EAAO8+B,EAAW5pC,KAAKwI,WAAWC,IAAIC,KAAKK,MACjD,IAAIA,EAAQ/I,KAAKwI,WAAWC,IAAIC,KAAKK,OAAS8gC,EAASD,GASvD,OARI9+B,EAAO/B,EAAQ/I,KAAKwI,WAAWC,IAAIO,OAAOD,QAC5CA,EAAQ/I,KAAKwI,WAAWC,IAAIO,OAAOD,MAAQ+B,GAG7ChJ,EAAQgH,MAAMH,OAAY8kB,EAAWztB,KAAKwI,WAAWC,IAAIC,KAAKC,OAAvC,KACvB7G,EAAQgH,MAAMkC,IAASpD,EAAM5H,KAAKwI,WAAWC,IAAIC,KAAKC,OAAlC,KACpB7G,EAAQgH,MAAMgC,KAAO,GAAGA,MACxBhJ,EAAQgH,MAAMC,MAAQ,GAAGA,MAClBjH,CACT,CAEO,gBAAA+X,GAEL7Z,KAAKmmC,yBAAyBE,uBAChC,CAEQ,qBAAAR,GAEN7lC,KAAK2lC,oBAEL3lC,KAAK8lC,WAAW9lC,KAAKiS,cAAcQ,QAEnCzS,KAAKwmC,YAAYI,QACf5mC,KAAKkqB,gBAAgB5f,WAAWwzB,WAChC99B,KAAKkqB,gBAAgB5f,WAAWrB,SAChCjJ,KAAKkqB,gBAAgB5f,WAAWu8B,WAChC7mC,KAAKkqB,gBAAgB5f,WAAWw8B,gBAElC9mC,KAAK+mC,oBACP,CAEO,KAAA16B,GACL,IAAK,MAAMlL,KAAKnB,KAAKc,aASnBK,EAAEqnC,kBAEAxoC,KAAKslC,0BAA4B,IACnCtlC,KAAKqlC,qBAAqByE,MAAK,GAC/B9pC,KAAKslC,0BAA4B,EACjCtlC,KAAKsmC,uBAAuByD,yBAAwB,GAExD,CAEO,UAAA5B,CAAW9lC,EAAeC,GAC/B,MAAM6B,EAASnE,KAAK8R,eAAe3N,OAC7B6lC,EAAkB7lC,EAAOqQ,MAAQrQ,EAAOgQ,EACxCO,EAAUC,KAAKC,IAAIzQ,EAAO0Q,EAAG7U,KAAK8R,eAAe7J,KAAO,GACxDgiC,EAAcjqC,KAAKovB,aAAa/kB,gBAAgB4/B,aAAejqC,KAAKkqB,gBAAgB5f,WAAW2/B,YAC/FC,EAAclqC,KAAKovB,aAAa/kB,gBAAgB6/B,aAAelqC,KAAKkqB,gBAAgB5f,WAAW4/B,YAC/FC,EAAsBnqC,KAAKkqB,gBAAgB5f,WAAW6/B,oBACtDC,EAAU,CAAEC,kBAAkB,GAEpC,IAAK,IAAIl2B,EAAI9R,EAAO8R,GAAK7R,EAAK6R,IAAK,CACjC,MAAMvM,EAAMuM,EAAIhQ,EAAOK,MACjBiD,EAAazH,KAAKc,aAAaqT,GACrC,IAAK1M,EACH,SAEF,MAAM/C,EAAWP,EAAOE,MAAMP,IAAI8D,GAC7BlD,GAKL+C,EAAW+gC,mBACNxoC,KAAK+lC,YAAYuE,UAClB5lC,EACAkD,EACAA,IAAQoiC,EACRE,EACAC,EACAz1B,EACAu1B,EACAjqC,KAAKsmC,uBAAuBiE,UAC5BvqC,KAAKwI,WAAWC,IAAIC,KAAKK,MACzB/I,KAAKwmC,aACJ,GACA,EACD4D,IAGJpqC,KAAKwqC,kBAAkBr2B,EAAGi2B,EAAQC,oBArBhC5iC,EAAW+gC,kBACXxoC,KAAKwqC,kBAAkBr2B,GAAG,GAqB9B,CACAnU,KAAKyqC,uBACP,CAEA,qBAAYvD,GACV,MAAO,6BAAsClnC,KAAKilC,gBACpD,CAEQ,gBAAAgB,CAAiB9kC,GACvBnB,KAAK0qC,kBAAkBvpC,EAAEuoB,GAAIvoB,EAAEyoB,GAAIzoB,EAAEwoB,GAAIxoB,EAAE0oB,GAAI1oB,EAAE8G,MAAM,EACzD,CAEQ,gBAAAi+B,CAAiB/kC,GACvBnB,KAAK0qC,kBAAkBvpC,EAAEuoB,GAAIvoB,EAAEyoB,GAAIzoB,EAAEwoB,GAAIxoB,EAAE0oB,GAAI1oB,EAAE8G,MAAM,EACzD,CAEQ,iBAAAyiC,CAAkB71B,EAAW+U,EAAYzV,EAAW0V,EAAY5hB,EAAc0iC,GAiBhFx2B,EAAI,IAAGU,EAAI,GACXgV,EAAK,IAAGD,EAAK,GACjB,MAAMghB,EAAO5qC,KAAK8R,eAAe/Q,KAAO,EACxCoT,EAAIQ,KAAKkZ,IAAIlZ,KAAKC,IAAIT,EAAGy2B,GAAO,GAChC/gB,EAAKlV,KAAKkZ,IAAIlZ,KAAKC,IAAIiV,EAAI+gB,GAAO,GAElC3iC,EAAO0M,KAAKC,IAAI3M,EAAMjI,KAAK8R,eAAe7J,MAC1C,MAAM9D,EAASnE,KAAK8R,eAAe3N,OAC7B6lC,EAAkB7lC,EAAOqQ,MAAQrQ,EAAOgQ,EACxCO,EAAUC,KAAKC,IAAIzQ,EAAO0Q,EAAG5M,EAAO,GACpCgiC,EAAcjqC,KAAKkqB,gBAAgB5f,WAAW2/B,YAC9CC,EAAclqC,KAAKkqB,gBAAgB5f,WAAW4/B,YAC9CC,EAAsBnqC,KAAKkqB,gBAAgB5f,WAAW6/B,oBACtDC,EAAU,CAAEC,kBAAkB,GAGpC,IAAK,IAAIvrC,EAAIqV,EAAGrV,GAAK+qB,IAAM/qB,EAAG,CAC5B,MAAM8I,EAAM9I,EAAIqF,EAAOK,MACjBiD,EAAazH,KAAKc,aAAahC,GACrC,IAAK2I,EACH,SAEF,MAAMojC,EAAa1mC,EAAOE,MAAMP,IAAI8D,GAC/BijC,GAKLpjC,EAAW+gC,mBACNxoC,KAAK+lC,YAAYuE,UAClBO,EACAjjC,EACAA,IAAQoiC,EACRE,EACAC,EACAz1B,EACAu1B,EACAjqC,KAAKsmC,uBAAuBiE,UAC5BvqC,KAAKwI,WAAWC,IAAIC,KAAKK,MACzB/I,KAAKwmC,YACLmE,EAAW7rC,IAAMqV,EAAIU,EAAI,GAAM,EAC/B81B,GAAY7rC,IAAM+qB,EAAKD,EAAK3hB,GAAQ,GAAM,EAC1CmiC,IAGJpqC,KAAKwqC,kBAAkB1rC,EAAGsrC,EAAQC,oBArBhC5iC,EAAW+gC,kBACXxoC,KAAKwqC,kBAAkB1rC,GAAG,GAqB9B,CACAkB,KAAKyqC,uBACP,CAEQ,iBAAAD,CAAkB5iC,EAAayiC,GACpBrqC,KAAKqlC,qBAAqBz9B,KAC1ByiC,IAGjBrqC,KAAKqlC,qBAAqBz9B,GAAOyiC,EACjCrqC,KAAKslC,2BAA6B+E,EAAmB,GAAK,EAC5D,CAEQ,qBAAAI,GACNzqC,KAAKsmC,uBAAuByD,wBAAwB/pC,KAAKslC,0BAA4B,EACvF,iCA7mBWlpB,EAAW7S,EAAA,CAgCnBC,EAAA,EAAAlK,EAAAmK,uBACAD,EAAA,EAAAnK,EAAAkZ,kBACA/O,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,GAAAlK,EAAAwqB,gBACAtgB,EAAA,GAAAlK,EAAAqzB,cACAnpB,EAAA,GAAAnK,EAAAqK,qBACAF,EAAA,GAAAnK,EAAAoZ,gBAtCQ2D,GAgnBb,MAAMgqB,EAIJ,WAAA1mC,CACmBkB,EACAf,GADAG,KAAAY,cAAAA,EACAZ,KAAAH,oBAAAA,EAJXG,KAAA8qC,eAAyB,EAM3B9qC,KAAKH,oBAAoBkrC,WAC3B/qC,KAAKgrC,iBAET,CAEO,OAAA3xB,GACLrZ,KAAKirC,iBACP,CAEO,qBAAA5E,GACDrmC,KAAK8qC,eACP9qC,KAAKY,cAAcF,UAAUgD,OAAM,2BAErC1D,KAAKgrC,iBACP,CAEO,KAAA9C,GACLloC,KAAK8qC,eAAgB,EACrB9qC,KAAKirC,iBACP,CAEO,MAAA7C,GACLpoC,KAAK8qC,eAAgB,EACrB9qC,KAAKY,cAAcF,UAAUgD,OAAM,2BACnC1D,KAAKgrC,iBACP,CAEQ,eAAAA,GACNhrC,KAAK8qC,eAAgB,EACrB9qC,KAAKirC,kBACLjrC,KAAKkrC,aAAelrC,KAAKH,oBAAoBqX,OAAOuX,WAAW,KAC7DzuB,KAAKmrC,0BACN,IACH,CAEQ,eAAAF,QACoBrmC,IAAtB5E,KAAKkrC,eACPlrC,KAAKH,oBAAoBqX,OAAOiX,aAAanuB,KAAKkrC,cAClDlrC,KAAKkrC,kBAAetmC,EAExB,CAEQ,sBAAAumC,GACNnrC,KAAKY,cAAcF,UAAUC,IAAG,2BAChCX,KAAK8qC,eAAgB,EACrB9qC,KAAKkrC,kBAAetmC,CACtB,qgBCrsBF,MAAA+/B,EAAAzlC,EAAA,MACAksC,EAAAlsC,EAAA,MACA+qB,EAAA/qB,EAAA,MACAG,EAAAH,EAAA,MACAqO,EAAArO,EAAA,MACAI,EAAAJ,EAAA,MACA4N,EAAA5N,EAAA,KACA0lC,EAAA1lC,EAAA,MACAmsC,EAAAnsC,EAAA,MAsBO,IAAM8mC,EAAN,MASL,WAAAtmC,CACmByX,EACyB0B,EACRqR,EACIrqB,EACPuvB,EACMnf,EACLgC,GANfjS,KAAAmX,UAAAA,EACyBnX,KAAA6Y,wBAAAA,EACR7Y,KAAAkqB,gBAAAA,EACIlqB,KAAAH,oBAAAA,EACPG,KAAAovB,aAAAA,EACMpvB,KAAAiQ,mBAAAA,EACLjQ,KAAAiS,cAAAA,EAf1BjS,KAAAoqB,UAAsB,IAAIH,EAAAI,SAI1BrqB,KAAAsrC,mBAA6B,EAE9BtrC,KAAA+nC,eAAiB,CAUrB,CAEI,sBAAAntB,CAAuBvY,EAAqCC,EAAmCuY,GACpG7a,KAAKurC,gBAAkBlpC,EACvBrC,KAAKwrC,cAAgBlpC,EACrBtC,KAAKsrC,kBAAoBzwB,CAC3B,CAEO,SAAAyvB,CACL5lC,EACAkD,EACA6jC,EACAvB,EACAC,EACAz1B,EACAu1B,EACAyB,EACA12B,EACA22B,EACAC,EACAC,EACAzB,GAGA,MAAM0B,EAA8B,GAChC1B,IACFA,EAAQC,kBAAmB,GAE7B,MAAM0B,EAAe/rC,KAAK6Y,wBAAwBmzB,oBAAoBpkC,GAChE6K,EAASzS,KAAKiS,cAAcQ,OAElC,IAKIw5B,EALAzhB,EAAa9lB,EAASwnC,uBACtBT,GAAejhB,EAAa9V,EAAU,IACxC8V,EAAa9V,EAAU,GAIzB,IAEI5V,EAOAgpC,EATAqE,EAAa,EACbtiC,EAAO,GAEPuiC,EAAQ,EACRC,EAAQ,EACRC,EAAS,EACTC,GAAiC,EACjCC,EAAa,EACbC,GAA4B,EAE5BC,EAAwB,EAC5B,MAAMC,EAAoB,GAEpBC,GAA0B,IAAfhB,IAAiC,IAAbC,EAErC,IAAK,IAAIh3B,EAAI,EAAGA,EAAI2V,EAAY3V,IAAK,CACnCnQ,EAASomB,SAASjW,EAAG7U,KAAKoqB,WAC1B,IAAIrhB,EAAQ/I,KAAKoqB,UAAUrV,WAG3B,GAAc,IAAVhM,EACF,SAIF,IAAI8jC,GAAW,EAIXC,EAAoBj4B,GAAK63B,EAEzBK,EAAYl4B,EAKZnM,EAAkB1I,KAAKoqB,UAC3B,GAAI2hB,EAAaxqC,OAAS,GAAKsT,IAAMk3B,EAAa,GAAG,IAAMe,EAAkB,CAC3E,MAAMnlB,EAAQokB,EAAapoC,QAGrBqpC,EAAsBhtC,KAAKitC,mBAAmBtlB,EAAM,GAAI/f,GAC9D,IAAK9I,EAAI6oB,EAAM,GAAK,EAAG7oB,EAAI6oB,EAAM,GAAI7oB,IACnCguC,IAAsBE,IAAwBhtC,KAAKitC,mBAAmBnuC,EAAG8I,GAG3EklC,KAAsBrB,GAAe/2B,EAAUiT,EAAM,IAAMjT,GAAWiT,EAAM,GACvEmlB,GAGHD,GAAW,EAIXnkC,EAAO,IAAIoE,EAAAogC,eACTltC,KAAKoqB,UACL1lB,EAASC,mBAAkB,EAAMgjB,EAAM,GAAIA,EAAM,IACjDA,EAAM,GAAKA,EAAM,IAInBolB,EAAYplB,EAAM,GAAK,EAGvB5e,EAAQL,EAAKqM,YAhBb23B,EAAwB/kB,EAAM,EAkBlC,CAEA,MAAMwlB,EAAgBntC,KAAKitC,mBAAmBp4B,EAAGjN,GAC3CwlC,EAAe3B,GAAe52B,IAAMH,EACpC24B,EAAcT,GAAY/3B,GAAK+2B,GAAa/2B,GAAKg3B,EACnDzB,GAAW1hC,EAAK4kC,YAClBlD,EAAQC,kBAAmB,IAENqB,GAAWhjC,EAAK4kC,WAErCX,EAAQ1oC,KAAI,sBAGd,IAAIspC,GAAc,EAClBvtC,KAAKiQ,mBAAmBu9B,wBAAwB34B,EAAGjN,OAAKhD,EAAW6oC,IACjEF,GAAc,IAIhB,IAAIG,EAAQhlC,EAAKilC,YAAcvC,EAAAwC,qBAQ/B,GAPc,MAAVF,IAAkBhlC,EAAKmlC,eAAiBnlC,EAAKolC,gBAC/CJ,EAAQ,KAIV5F,EAAU/+B,EAAQiM,EAAY22B,EAAW7nC,IAAI4pC,EAAOhlC,EAAKqlC,SAAUrlC,EAAKslC,YAEnE/B,EAEE,CAWL,GACEE,IAEGgB,GAAiBV,IACbU,IAAkBV,GAAoB/jC,EAAKsD,KAAOogC,KAGtDe,GAAiBV,GAAoBh6B,EAAOw7B,qBAC1CvlC,EAAKuD,KAAOogC,IAEd3jC,EAAKsiB,SAASkjB,MAAQ5B,GACtBe,IAAgBd,GAChBzE,IAAY0E,IACXY,IACAP,IACAU,GACDT,EACH,CAEIpkC,EAAKylC,cACPtkC,GAAQuhC,EAAAwC,qBAER/jC,GAAQ6jC,EAEVvB,IACA,QACF,CAMMA,IACFF,EAAYroC,YAAciG,GAE5BoiC,EAAcjsC,KAAKmX,UAAU1W,cAAc,QAC3C0rC,EAAa,EACbtiC,EAAO,EAEX,MAnDEoiC,EAAcjsC,KAAKmX,UAAU1W,cAAc,QAqE7C,GAhBA2rC,EAAQ1jC,EAAKsD,GACbqgC,EAAQ3jC,EAAKuD,GACbqgC,EAAS5jC,EAAKsiB,SAASkjB,IACvB3B,EAAec,EACfb,EAAa1E,EACb2E,EAAmBU,EAEfN,GAIEn4B,GAAWG,GAAKH,GAAWq4B,IAC7Br4B,EAAUG,IAIT7U,KAAKovB,aAAasU,gBAAkB0J,GAAgBptC,KAAKovB,aAAa5S,oBAEzE,GADAmwB,EAAQ1oC,KAAI,gBACRjE,KAAKH,oBAAoBkrC,UACvBd,GACF0C,EAAQ1oC,KAAI,sBAEd0oC,EAAQ1oC,KACU,QAAhBimC,EACG,mBACiB,cAAhBA,EACC,yBACA,2BAGP,GAAIC,EACF,OAAQA,GACN,IAAK,UACHwC,EAAQ1oC,KAAI,wBACZ,MACF,IAAK,QACH0oC,EAAQ1oC,KAAI,sBACZ,MACF,IAAK,MACH0oC,EAAQ1oC,KAAI,oBACZ,MACF,IAAK,YACH0oC,EAAQ1oC,KAAI,0BA2BtB,GAlBIyE,EAAKqlC,UACPpB,EAAQ1oC,KAAI,cAGVyE,EAAKslC,YACPrB,EAAQ1oC,KAAI,gBAGVyE,EAAK0lC,SACPzB,EAAQ1oC,KAAI,aAIZ4F,EADEnB,EAAKylC,cACA/C,EAAAwC,qBAEAllC,EAAKilC,YAAcvC,EAAAwC,qBAGxBllC,EAAKmlC,gBACPlB,EAAQ1oC,KAAK,mBAA6ByE,EAAKsiB,SAASqjB,kBAC3C,MAATxkC,IACFA,EAAO,MAEJnB,EAAK4lC,2BACR,GAAI5lC,EAAK6lC,sBACPtC,EAAYnjC,MAAM0lC,oBAAsB,OAAOnD,EAAAoD,cAAcj8B,WAAW9J,EAAKgmC,qBAAqBld,KAAK,YAClG,CACL,IAAIvlB,EAAKvD,EAAKgmC,oBACV1uC,KAAKkqB,gBAAgB5f,WAAWqkC,4BAA8BjmC,EAAKqlC,UAAY9hC,EAAK,IACtFA,GAAM,GAERggC,EAAYnjC,MAAM0lC,oBAAsB/7B,EAAOC,KAAKzG,GAAIxD,GAC1D,CAIAC,EAAKolC,eACPnB,EAAQ1oC,KAAI,kBACC,MAAT4F,IACFA,EAAO,MAIPnB,EAAKkmC,mBACPjC,EAAQ1oC,KAAI,uBAKVopC,IACFpB,EAAYnjC,MAAM+lC,eAAiB,aAGrC,IAAI5iC,EAAKvD,EAAKomC,aACVC,EAAcrmC,EAAKsmC,iBACnBhjC,EAAKtD,EAAKumC,aACVC,EAAcxmC,EAAKymC,iBACvB,MAAMC,IAAc1mC,EAAK0mC,YACzB,GAAIA,EAAW,CACb,MAAMC,EAAOpjC,EACbA,EAAKD,EACLA,EAAKqjC,EACL,MAAMC,EAAQP,EACdA,EAAcG,EACdA,EAAcI,CAChB,CAIA,IAAIC,EACAC,EA6CAC,EA5CAC,IAAQ,EA6CZ,OA5CA1vC,KAAKiQ,mBAAmBu9B,wBAAwB34B,EAAGjN,OAAKhD,EAAW6oC,IACzC,QAApBA,EAAEvkC,QAAQ2qB,OAAmB6b,KAG7BjC,EAAEkC,qBACJT,EAAW,SACXljC,EAAKyhC,EAAEkC,mBAAmBr8B,MAAQ,EAAI,SACtCi8B,EAAa9B,EAAEkC,oBAEblC,EAAEmC,qBACJb,EAAW,SACX9iC,EAAKwhC,EAAEmC,mBAAmBt8B,MAAQ,EAAI,SACtCk8B,EAAa/B,EAAEmC,oBAEjBF,GAA4B,QAApBjC,EAAEvkC,QAAQ2qB,UAIf6b,IAASvC,IAKZoC,EAAavvC,KAAKH,oBAAoBkrC,UAAYt4B,EAAOi1B,0BAA4Bj1B,EAAOk1B,kCAC5F37B,EAAKujC,EAAWj8B,MAAQ,EAAI,SAC5B47B,EAAW,SAGXQ,IAAQ,EAEJj9B,EAAOw7B,sBACTc,EAAW,SACX9iC,EAAKwG,EAAOw7B,oBAAoB36B,MAAQ,EAAI,SAC5Ck8B,EAAa/8B,EAAOw7B,sBAKpByB,IACF/C,EAAQ1oC,KAAK,wBAKPirC,GACN,cACA,cACEO,EAAah9B,EAAOC,KAAK1G,GACzB2gC,EAAQ1oC,KAAK,YAAY+H,KACzB,MACF,cACEyjC,EAAaliC,EAAAsF,SAASC,QAAQ9G,GAAM,GAAIA,GAAM,EAAI,IAAW,IAALA,GACxDhM,KAAK6vC,UAAU5D,EAAa,sBAAsBjgC,IAAO,GAAG1H,SAAS,IAAIwrC,SAAS,EAAG,QACrF,MAEF,QACMV,GACFK,EAAah9B,EAAOc,WACpBo5B,EAAQ1oC,KAAK,YAAY0gC,EAAAiD,2BAEzB6H,EAAah9B,EAAOY,WAY1B,OAPKk8B,GACC7mC,EAAK0lC,UACPmB,EAAahiC,EAAAgF,MAAM40B,gBAAgBsI,EAAY,KAK3CV,GACN,cACA,cACMrmC,EAAKqlC,UAAY9hC,EAAK,GAAKjM,KAAKkqB,gBAAgB5f,WAAWqkC,6BAC7D1iC,GAAM,GAEHjM,KAAK+vC,sBAAsB9D,EAAawD,EAAYh9B,EAAOC,KAAKzG,GAAKvD,EAAM6mC,OAAY3qC,IAC1F+nC,EAAQ1oC,KAAK,YAAYgI,KAE3B,MACF,cACE,MAAMsG,EAAQhF,EAAAsF,SAASC,QACpB7G,GAAM,GAAM,IACZA,GAAO,EAAK,IACA,IAAb,GAEGjM,KAAK+vC,sBAAsB9D,EAAawD,EAAYl9B,EAAO7J,EAAM6mC,EAAYC,IAChFxvC,KAAK6vC,UAAU5D,EAAa,UAAUhgC,EAAG3H,SAAS,IAAIwrC,SAAS,EAAG,QAEpE,MAEF,QACO9vC,KAAK+vC,sBAAsB9D,EAAawD,EAAYh9B,EAAOc,WAAY7K,EAAM6mC,EAAYC,IACxFJ,GACFzC,EAAQ1oC,KAAK,YAAY0gC,EAAAiD,0BAQ7B+E,EAAQprC,SACV0qC,EAAY+D,UAAYrD,EAAQnb,KAAK,KACrCmb,EAAQprC,OAAS,GAId6rC,GAAiBP,GAAaU,IAAeT,EAGhDb,EAAYroC,YAAciG,EAF1BsiC,IAKErE,IAAY9nC,KAAK+nC,iBACnBkE,EAAYnjC,MAAMk+B,cAAgB,GAAGc,OAGvCgE,EAAS7nC,KAAKgoC,GACdp3B,EAAIk4B,CACN,CAOA,OAJId,GAAeE,IACjBF,EAAYroC,YAAciG,GAGrBiiC,CACT,CAEQ,qBAAAiE,CAAsBjuC,EAAsBkK,EAAYC,EAAYvD,EAAiB6mC,EAAgCC,GAC3H,GAA6D,IAAzDxvC,KAAKkqB,gBAAgB5f,WAAW2lC,uBAA8B,EAAArL,EAAAsL,6BAA4BxnC,EAAKynC,WACjG,OAAO,EAIT,MAAMC,EAAQpwC,KAAKqwC,kBAAkB3nC,GACrC,IAAI4nC,EAMJ,GALKf,GAAeC,IAClBc,EAAgBF,EAAMhkC,SAASJ,EAAGsH,KAAMrH,EAAGqH,YAIvB1O,IAAlB0rC,EAA6B,CAG/B,MAAMC,EAAQvwC,KAAKkqB,gBAAgB5f,WAAW2lC,sBAAwBvnC,EAAK0lC,QAAU,EAAI,GACzFkC,EAAgB/iC,EAAAgF,MAAMi+B,oBAAoBjB,GAAcvjC,EAAIwjC,GAAcvjC,EAAIskC,GAC9EH,EAAMjkC,UAAUojC,GAAcvjC,GAAIsH,MAAOk8B,GAAcvjC,GAAIqH,KAAMg9B,GAAiB,KACpF,CAEA,QAAIA,IACFtwC,KAAK6vC,UAAU/tC,EAAS,SAASwuC,EAAc7nC,QACxC,EAIX,CAEQ,iBAAA4nC,CAAkB3nC,GACxB,OAAIA,EAAK0lC,QACApuC,KAAKiS,cAAcQ,OAAOg+B,kBAE5BzwC,KAAKiS,cAAcQ,OAAOi+B,aACnC,CAEQ,SAAAb,CAAU/tC,EAAsBgH,GACtChH,EAAQjB,aAAa,QAAS,GAAGiB,EAAQuD,aAAa,UAAY,KAAKyD,KACzE,CAEQ,kBAAAmkC,CAAmBp4B,EAAWV,GACpC,MAAM9R,EAAQrC,KAAKurC,gBACbjpC,EAAMtC,KAAKwrC,cACjB,SAAKnpC,IAAUC,KAGXtC,KAAKsrC,kBACHjpC,EAAM,IAAMC,EAAI,GACXuS,GAAKxS,EAAM,IAAM8R,GAAK9R,EAAM,IACjCwS,EAAIvS,EAAI,IAAM6R,GAAK7R,EAAI,GAEpBuS,EAAIxS,EAAM,IAAM8R,GAAK9R,EAAM,IAChCwS,GAAKvS,EAAI,IAAM6R,GAAK7R,EAAI,GAEpB6R,EAAI9R,EAAM,IAAM8R,EAAI7R,EAAI,IAC3BD,EAAM,KAAOC,EAAI,IAAM6R,IAAM9R,EAAM,IAAMwS,GAAKxS,EAAM,IAAMwS,EAAIvS,EAAI,IAClED,EAAM,GAAKC,EAAI,IAAM6R,IAAM7R,EAAI,IAAMuS,EAAIvS,EAAI,IAC7CD,EAAM,GAAKC,EAAI,IAAM6R,IAAM9R,EAAM,IAAMwS,GAAKxS,EAAM,GACzD,qDAlgBW2jC,EAAqBz8B,EAAA,CAW7BC,EAAA,EAAAlK,EAAAyZ,yBACAvP,EAAA,EAAAnK,EAAA0tB,iBACAvjB,EAAA,EAAAlK,EAAAoK,qBACAF,EAAA,EAAAnK,EAAAszB,cACAnpB,EAAA,EAAAnK,EAAAiR,oBACA9G,EAAA,EAAAlK,EAAAmZ,gBAhBQutB,qFChCb,MAAApB,EAAA1lC,EAAA,mBA2BA,MAmBE,WAAAQ,CACEixC,EAAoD,IAAM,IAAIC,GAdtD5wC,KAAA6wC,MAAQ,IAAIC,aAAY,KAO1B9wC,KAAA+wC,MAAQ,GACR/wC,KAAAgxC,UAAY,EACZhxC,KAAAixC,QAAsB,SACtBjxC,KAAAkxC,YAA0B,OAC1BlxC,KAAAmxC,gBAAkD,GAKxDnxC,KAAKmxC,gBAAkB,CACrBR,IACAA,IACAA,IACAA,KAGF3wC,KAAKqM,OACP,CAEO,OAAAgN,GACLrZ,KAAKmxC,gBAAgB5vC,OAAS,EAC9BvB,KAAKoxC,YAASxsC,CAChB,CAKO,KAAAyH,GACLrM,KAAK6wC,MAAM/G,MAAI,MAEf9pC,KAAKoxC,OAAS,IAAI3sB,GACpB,CAOO,OAAAmiB,CAAQyK,EAAcpoC,EAAkBqoC,EAAoBC,GAG/DF,IAASrxC,KAAK+wC,OACd9nC,IAAajJ,KAAKgxC,WAClBM,IAAWtxC,KAAKixC,SAChBM,IAAevxC,KAAKkxC,cAKtBlxC,KAAK+wC,MAAQM,EACbrxC,KAAKgxC,UAAY/nC,EACjBjJ,KAAKixC,QAAUK,EACftxC,KAAKkxC,YAAcK,EAEnBvxC,KAAKmxC,gBAAe,GAAsBvK,QAAQyK,EAAMpoC,EAAUqoC,GAAQ,GAC1EtxC,KAAKmxC,gBAAe,GAAmBvK,QAAQyK,EAAMpoC,EAAUsoC,GAAY,GAC3EvxC,KAAKmxC,gBAAe,GAAqBvK,QAAQyK,EAAMpoC,EAAUqoC,GAAQ,GACzEtxC,KAAKmxC,gBAAe,GAA0BvK,QAAQyK,EAAMpoC,EAAUsoC,GAAY,GAElFvxC,KAAKqM,QACP,CAMO,GAAAvI,CAAIkrB,EAAWwiB,EAAwBC,GAC5C,IAAIC,EACJ,IAAKF,IAASC,GAAuB,IAAbziB,EAAEztB,SAAiBmwC,EAAK1iB,EAAEvP,WAAW,IAAG,IAAiC,CAC/F,IAAkB,OAAdzf,KAAK6wC,MAAMa,GACb,OAAO1xC,KAAK6wC,MAAMa,GAEpB,MAAM3oC,EAAQ/I,KAAK2xC,SAAS3iB,EAAG,GAI/B,OAHIjmB,EAAQ,IACV/I,KAAK6wC,MAAMa,GAAM3oC,GAEZA,CACT,CACA,IAAI9F,EAAM+rB,EACNwiB,IAAMvuC,GAAO,KACbwuC,IAAQxuC,GAAO,KACnB,IAAI8F,EAAQ/I,KAAKoxC,OAAQttC,IAAIb,GAC7B,QAAc2B,IAAVmE,EAAqB,CACvB,IAAI6oC,EAAU,EACVJ,IAAMI,GAAO,GACbH,IAAQG,GAAO,GACnB7oC,EAAQ/I,KAAK2xC,SAAS3iB,EAAG4iB,GACrB7oC,EAAQ,GACV/I,KAAKoxC,OAAQtsC,IAAI7B,EAAK8F,EAE1B,CACA,OAAOA,CACT,CAEU,QAAA4oC,CAAS3iB,EAAW4iB,GAC5B,OAAO5xC,KAAKmxC,gBAAgBS,GAAS51B,QAAQgT,EAC/C,GAGF,MAAM4hB,EAIJ,WAAAlxC,GACiC,oBAApBmyC,iBACT7xC,KAAKi2B,QAAU,IAAI4b,gBAAgB,EAAG,GACtC7xC,KAAKu2B,MAAO,EAAAqO,EAAAkN,cAAa9xC,KAAKi2B,QAAQK,WAAW,SAEjDt2B,KAAKi2B,QAAU7d,SAAS3X,cAAc,UACtCT,KAAKi2B,QAAQltB,MAAQ,EACrB/I,KAAKi2B,QAAQttB,OAAS,EACtB3I,KAAKu2B,MAAO,EAAAqO,EAAAkN,cAAa9xC,KAAKi2B,QAAQK,WAAW,OAErD,CAEO,OAAAsQ,CAAQ9I,EAAoB70B,EAAkB49B,EAAwB4K,GAC3E,MAAMM,EAAYN,EAAS,SAAW,GACtCzxC,KAAKu2B,KAAK8a,KAAO,GAAGU,KAAalL,KAAc59B,OAAc60B,IAAakU,MAC5E,CAEO,OAAAh2B,CAAQgT,GACb,OAAOhvB,KAAKu2B,KAAK0b,YAAYjjB,GAAGjmB,KAClC,+FClKWtK,EAAAmpC,uBAAyB,eCStC,SAAAsK,EAAiCC,GAI/B,OAAO,OAAUA,GAAaA,GAAa,KAC7C,CAcA,SAAAC,EAAwBD,GACtB,OACEA,GAAa,QAAWA,GAAa,QACrCA,GAAa,QAAWA,GAAa,QACrCA,GAAa,QAAWA,GAAa,QACrCA,GAAa,MAAWA,GAAa,MACrCA,GAAa,MAAWA,GAAa,OACrCA,GAAa,OAAWA,GAAa,OACrCA,GAAa,QAAWA,GAAa,QACrCA,GAAa,QAAWA,GAAa,MAEzC,iEArCA,SAAgC1nC,GAC9B,IAAKA,EACH,MAAM,IAAI1I,MAAM,2BAElB,OAAO0I,CACT,oDASA,SAA2C0nC,GACzC,OAAO,OAAUA,GAAaA,GAAa,KAC7C,+BAuBA,SAA+BA,EAA+BppC,EAAespC,EAAoBC,GAC/F,OAEY,IAAVvpC,GAGAspC,EAAa19B,KAAKoiB,KAAuB,IAAlBub,SAET1tC,IAAdutC,GAA2BA,EAAY,MAEtCC,EAAQD,KAERD,EAAiBC,KAjCtB,SAAyBA,GACvB,OAAO,OAAUA,GAAaA,GAAa,KAC7C,CA+BqCI,CAAgBJ,EAErD,gCAEA,SAA4CA,GAC1C,OAAOD,EAAiBC,IAlC1B,SAA2BA,GACzB,OAAO,MAAUA,GAAaA,GAAa,IAC7C,CAgCwCK,CAAkBL,EAC1D,2BAEA,WACE,MAAO,CACL1pC,IAAK,CACHO,OAiBG,CACLD,MAAO,EACPJ,OAAQ,GAlBND,KAgBG,CACLK,MAAO,EACPJ,OAAQ,IAhBRkG,OAAQ,CACN7F,OAaG,CACLD,MAAO,EACPJ,OAAQ,GAdND,KAYG,CACLK,MAAO,EACPJ,OAAQ,GAbNlG,KAAM,CACJsG,MAAO,EACPJ,OAAQ,EACRmC,KAAM,EACNE,IAAK,IAIb,6BASA,SAAyCgK,EAAmByiB,EAAmBgb,EAAwB,GACrG,OAAQz9B,GAAqC,EAAxBL,KAAK6d,MAAMiF,GAAiBgb,KAA2C,EAAxB99B,KAAK6d,MAAMiF,GACjF,2FCJA,WACE,OAAO,IAAIib,CACb,EAnFA,MAAMA,EAYJ,WAAAhzC,GACEM,KAAKqM,OACP,CAEO,KAAAA,GACLrM,KAAKsV,cAAe,EACpBtV,KAAK6a,kBAAmB,EACxB7a,KAAKkpC,iBAAmB,EACxBlpC,KAAKmpC,eAAiB,EACtBnpC,KAAK8oC,uBAAyB,EAC9B9oC,KAAK+oC,qBAAuB,EAC5B/oC,KAAK6/B,SAAW,EAChB7/B,KAAK8/B,OAAS,EACd9/B,KAAKse,oBAAiB1Z,EACtB5E,KAAKue,kBAAe3Z,CACtB,CAEO,MAAAikC,CAAO8J,EAAqBtwC,EAAqCC,EAAmCuY,GAA4B,GAIrI,GAHA7a,KAAKse,eAAiBjc,EACtBrC,KAAKue,aAAejc,GAEfD,IAAUC,GAAQD,EAAM,KAAOC,EAAI,IAAMD,EAAM,KAAOC,EAAI,GAE7D,YADAtC,KAAKqM,QAKP,MAAMumC,EAAYD,EAASn/B,QAAQC,OAAOjP,MACpC0kC,EAAmB7mC,EAAM,GAAKuwC,EAC9BzJ,EAAiB7mC,EAAI,GAAKswC,EAC1B9J,EAAyBn0B,KAAKkZ,IAAIqb,EAAkB,GACpDH,EAAuBp0B,KAAKC,IAAIu0B,EAAgBwJ,EAAS5xC,KAAO,GAGlE+nC,GAA0B6J,EAAS5xC,MAAQgoC,EAAuB,EACpE/oC,KAAKqM,SAIPrM,KAAKsV,cAAe,EACpBtV,KAAK6a,iBAAmBA,EACxB7a,KAAKkpC,iBAAmBA,EACxBlpC,KAAKmpC,eAAiBA,EACtBnpC,KAAK8oC,uBAAyBA,EAC9B9oC,KAAK+oC,qBAAuBA,EAC5B/oC,KAAK6/B,SAAWx9B,EAAM,GACtBrC,KAAK8/B,OAASx9B,EAAI,GACpB,CAEO,cAAAuwC,CAAeF,EAAoB99B,EAAWV,GACnD,QAAKnU,KAAKsV,eAGVnB,GAAKw+B,EAASxuC,OAAOsP,OAAOm/B,UACxB5yC,KAAK6a,iBACH7a,KAAK6/B,UAAY7/B,KAAK8/B,OACjBjrB,GAAK7U,KAAK6/B,UAAY1rB,GAAKnU,KAAK8oC,wBACrCj0B,EAAI7U,KAAK8/B,QAAU3rB,GAAKnU,KAAK+oC,qBAE1Bl0B,EAAI7U,KAAK6/B,UAAY1rB,GAAKnU,KAAK8oC,wBACpCj0B,GAAK7U,KAAK8/B,QAAU3rB,GAAKnU,KAAK+oC,qBAE1B50B,EAAInU,KAAKkpC,kBAAoB/0B,EAAInU,KAAKmpC,gBAC3CnpC,KAAKkpC,mBAAqBlpC,KAAKmpC,gBAAkBh1B,IAAMnU,KAAKkpC,kBAAoBr0B,GAAK7U,KAAK6/B,UAAYhrB,EAAI7U,KAAK8/B,QAC/G9/B,KAAKkpC,iBAAmBlpC,KAAKmpC,gBAAkBh1B,IAAMnU,KAAKmpC,gBAAkBt0B,EAAI7U,KAAK8/B,QACrF9/B,KAAKkpC,iBAAmBlpC,KAAKmpC,gBAAkBh1B,IAAMnU,KAAKkpC,kBAAoBr0B,GAAK7U,KAAK6/B,SAC7F,+FCjFF,MAAAzgC,EAAAF,EAAA,MAGA,MAAAqnC,UAA2CnnC,EAAAK,WAOzC,WAAAC,CACmButB,EACAptB,EACAqqB,GAEjBnqB,QAJiBC,KAAAitB,gBAAAA,EACAjtB,KAAAH,oBAAAA,EACAG,KAAAkqB,gBAAAA,EATXlqB,KAAA8yC,kBAA4B,EAE5B9yC,KAAA+yC,UAAoB,EACpB/yC,KAAAgzC,uBAAiC,EACjChzC,KAAAizC,oBAA8B,EAQpCjzC,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,wBAAyBy7B,IAClFlzC,KAAKmzC,oBAAoBD,MAE3BlzC,KAAKmzC,oBAAoBnzC,KAAKkqB,gBAAgB5f,WAAW8oC,uBACzDpzC,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKqzC,kBACzC,CAEA,aAAW9I,GACT,OAAOvqC,KAAK+yC,QACd,CAEA,aAAWO,GACT,OAAOtzC,KAAK8yC,kBAAoB,CAClC,CAEO,uBAAA/I,CAAwBwJ,GACzBvzC,KAAKgzC,wBAA0BO,IAInCvzC,KAAKgzC,sBAAwBO,EAC7BvzC,KAAKwzC,uBACP,CAEO,kBAAAjL,CAAmBD,GACpBtoC,KAAKizC,qBAAuB3K,IAIhCtoC,KAAKizC,mBAAqB3K,EAC1BtoC,KAAKwzC,uBACP,CAEO,mBAAAL,CAAoBD,GACrBA,IAAalzC,KAAK8yC,oBAItB9yC,KAAK8yC,kBAAoBI,EACzBlzC,KAAKqzC,iBACLrzC,KAAKwzC,uBACP,CAEQ,oBAAAA,GAEN,GADoBxzC,KAAK8yC,kBAAoB,GAAK9yC,KAAKgzC,uBAAyBhzC,KAAKizC,mBACpE,CACf,QAAuBruC,IAAnB5E,KAAKyzC,UACP,OAEF,MAAMC,EAAa1zC,KAAK+yC,SASxB,OARA/yC,KAAK+yC,UAAW,EAChB/yC,KAAKyzC,UAAYzzC,KAAKH,oBAAoBqX,OAAOy8B,YAAY,KAC3D3zC,KAAK+yC,UAAY/yC,KAAK+yC,SACtB/yC,KAAKitB,mBACJjtB,KAAK8yC,wBACHY,GACH1zC,KAAKitB,kBAGT,CAEAjtB,KAAKqzC,iBACArzC,KAAK+yC,WACR/yC,KAAK+yC,UAAW,EAChB/yC,KAAKitB,kBAET,CAEQ,cAAAomB,QACiBzuC,IAAnB5E,KAAKyzC,YACPzzC,KAAKH,oBAAoBqX,OAAO08B,cAAc5zC,KAAKyzC,WACnDzzC,KAAKyzC,eAAY7uC,EAErB,i5BC1FF,MAAYivC,EAAG50C,EAAAC,EAAA,OACf40C,EAAA50C,EAAA,MACA60C,EAAA70C,EAAA,KAEA80C,EAAA90C,EAAA,MAEA+0C,EAAA/0C,EAAA,MACAg1C,EAAAh1C,EAAA,MACYi1C,EAAQl1C,EAAAC,EAAA,MA8BpB,MAAAk1C,UAAgDF,EAAAG,OAe9C,WAAA30C,CAAY40C,GACVv0C,QACAC,KAAKu0C,YAAcD,EAAKE,WACxBx0C,KAAKy0C,MAAQH,EAAKI,KAClB10C,KAAK20C,YAAcL,EAAK3kB,WACxB3vB,KAAK40C,cAAgBN,EAAKO,aAC1B70C,KAAK80C,gBAAkBR,EAAKS,eAC5B/0C,KAAKg1C,sBAAwBh1C,KAAK0B,UAAU,IAAIuyC,EAAAgB,8BAA8BX,EAAKY,WAAY,iCAAmCZ,EAAKa,wBAAyB,mCAAqCb,EAAKa,0BAC1Mn1C,KAAKg1C,sBAAsBI,YAAYp1C,KAAK80C,gBAAgBO,YAC5Dr1C,KAAKs1C,oBAAsBt1C,KAAK0B,UAAU,IAAIqyC,EAAAwB,0BAC9Cv1C,KAAKw1C,eAAgB,EACrBx1C,KAAKshB,QAAU,IAAIwyB,EAAA2B,YAAYr9B,SAAS3X,cAAc,QACtDT,KAAKshB,QAAQzgB,aAAa,OAAQ,gBAClCb,KAAKshB,QAAQzgB,aAAa,cAAe,QAEzCb,KAAKg1C,sBAAsBU,WAAW11C,KAAKshB,SAC3CthB,KAAKshB,QAAQq0B,YAAY,YAEzB31C,KAAK0B,UAAUmyC,EAAIvwC,sBAAsBtD,KAAKshB,QAAQA,QAASuyB,EAAIxwB,UAAUW,aAAe7iB,GAAoBnB,KAAK41C,oBAAoBz0C,IAC3I,CAOU,YAAA00C,CAAavB,GACrB,MAAMwB,EAAQ91C,KAAK0B,UAAU,IAAIsyC,EAAA+B,eAAezB,IAGhD,OAFAt0C,KAAKshB,QAAQA,QAAQrgB,YAAY60C,EAAME,WACvCh2C,KAAKshB,QAAQA,QAAQrgB,YAAY60C,EAAMx0B,SAChCw0B,CACT,CAKU,aAAAG,CAAcjrC,EAAaF,EAAc/B,EAA2BJ,GAC5E3I,KAAKk2C,OAAS,IAAIpC,EAAA2B,YAAYr9B,SAAS3X,cAAc,QACrDT,KAAKk2C,OAAOC,aAAa,gBACzBn2C,KAAKk2C,OAAOP,YAAY,YACxB31C,KAAKk2C,OAAOE,OAAOprC,GACnBhL,KAAKk2C,OAAOG,QAAQvrC,GACC,iBAAV/B,GACT/I,KAAKk2C,OAAOI,SAASvtC,GAED,iBAAXJ,GACT3I,KAAKk2C,OAAOK,UAAU5tC,GAExB3I,KAAKk2C,OAAOM,iBAAgB,GAC5Bx2C,KAAKk2C,OAAOO,WAAW,UAEvBz2C,KAAKshB,QAAQA,QAAQrgB,YAAYjB,KAAKk2C,OAAO50B,SAE7CthB,KAAK0B,UAAUmyC,EAAIvwC,sBACjBtD,KAAKk2C,OAAO50B,QACZuyB,EAAIxwB,UAAUW,aACb7iB,IACkB,IAAbA,EAAEyU,SACJzU,EAAE6E,iBACFhG,KAAK02C,mBAAmBv1C,OAK9BnB,KAAK22C,SAAS32C,KAAKk2C,OAAO50B,QAASngB,IAC7BA,EAAEy1C,YACJz1C,EAAEoK,mBAGR,CAIU,kBAAAsrC,CAAmBC,GAQ3B,OAPI92C,KAAK80C,gBAAgBiC,eAAeD,KACtC92C,KAAKg1C,sBAAsBI,YAAYp1C,KAAK80C,gBAAgBO,YAC5Dr1C,KAAKw1C,eAAgB,EAChBx1C,KAAKu0C,aACRv0C,KAAKg3C,UAGFh3C,KAAKw1C,aACd,CAEU,wBAAAyB,CAAyBC,GAQjC,OAPIl3C,KAAK80C,gBAAgBqC,cAAcD,KACrCl3C,KAAKg1C,sBAAsBI,YAAYp1C,KAAK80C,gBAAgBO,YAC5Dr1C,KAAKw1C,eAAgB,EAChBx1C,KAAKu0C,aACRv0C,KAAKg3C,UAGFh3C,KAAKw1C,aACd,CAEU,4BAAA4B,CAA6BC,GAQrC,OAPIr3C,KAAK80C,gBAAgBhjB,kBAAkBulB,KACzCr3C,KAAKg1C,sBAAsBI,YAAYp1C,KAAK80C,gBAAgBO,YAC5Dr1C,KAAKw1C,eAAgB,EAChBx1C,KAAKu0C,aACRv0C,KAAKg3C,UAGFh3C,KAAKw1C,aACd,CAIO,WAAA8B,GACLt3C,KAAKg1C,sBAAsBuC,oBAAmB,EAChD,CAEO,SAAAC,GACLx3C,KAAKg1C,sBAAsBuC,oBAAmB,EAChD,CAEO,MAAAP,GACAh3C,KAAKw1C,gBAGVx1C,KAAKw1C,eAAgB,EAErBx1C,KAAKy3C,eAAez3C,KAAK80C,gBAAgB4C,wBAAyB13C,KAAK80C,gBAAgB6C,yBACvF33C,KAAK43C,cAAc53C,KAAK80C,gBAAgB+C,gBAAiB73C,KAAK80C,gBAAgBgD,eAAiB93C,KAAK80C,gBAAgBiD,qBACtH,CAGQ,mBAAAnC,CAAoBz0C,GACtBA,EAAEgE,SAAWnF,KAAKshB,QAAQA,SAG9BthB,KAAKg4C,mBAAmB72C,EAC1B,CAEO,mBAAA82C,CAAoB92C,GACzB,MAAM+2C,EAASl4C,KAAKshB,QAAQA,QAAQ62B,iBAAiB,GAAGntC,IAClDotC,EAAcF,EAASl4C,KAAK80C,gBAAgBiD,oBAC5CM,EAAaH,EAASl4C,KAAK80C,gBAAgBiD,oBAAsB/3C,KAAK80C,gBAAgB+C,gBACtFS,EAAat4C,KAAKu4C,uBAAuBp3C,GAC3Ci3C,GAAeE,GAAcA,GAAcD,EAC5B,IAAbl3C,EAAEyU,SACJzU,EAAE6E,iBACFhG,KAAK02C,mBAAmBv1C,IAG1BnB,KAAKg4C,mBAAmB72C,EAE5B,CAEQ,kBAAA62C,CAAmB72C,GACzB,IAAIq3C,EACAC,EACJ,GAAIt3C,EAAEgE,SAAWnF,KAAKshB,QAAQA,SAAgC,iBAAdngB,EAAEq3C,SAA6C,iBAAdr3C,EAAEs3C,QACjFD,EAAUr3C,EAAEq3C,QACZC,EAAUt3C,EAAEs3C,YACP,CACL,MAAMC,EAAkB7E,EAAI8E,uBAAuB34C,KAAKshB,QAAQA,SAChEk3B,EAAUr3C,EAAEy3C,MAAQF,EAAgB5tC,KACpC2tC,EAAUt3C,EAAE03C,MAAQH,EAAgB1tC,GACtC,CAEA,MAAMnE,EAAS7G,KAAK84C,6BAA6BN,EAASC,GAC1Dz4C,KAAK+4C,6BACH/4C,KAAK40C,cACD50C,KAAK80C,gBAAgBkE,wCAAwCnyC,GAC7D7G,KAAK80C,gBAAgBmE,mCAAmCpyC,IAG7C,IAAb1F,EAAEyU,SACJzU,EAAE6E,iBACFhG,KAAK02C,mBAAmBv1C,GAE5B,CAEQ,kBAAAu1C,CAAmBv1C,GACzB,KAAKA,EAAEgE,QAAYhE,EAAEgE,kBAAkB+zC,SACrC,OAEF,MAAMC,EAAyBn5C,KAAKu4C,uBAAuBp3C,GACrDi4C,EAAmCp5C,KAAKq5C,iCAAiCl4C,GACzEm4C,EAAwBt5C,KAAK80C,gBAAgByE,QACnDv5C,KAAKk2C,OAAOsD,gBAAgB,gBAAgB,GAE5Cx5C,KAAKs1C,oBAAoBmE,gBACvBt4C,EAAEgE,OACFhE,EAAEu4C,UACFv4C,EAAEw4C,QACDC,IACC,MAAMC,EAA4B75C,KAAKq5C,iCAAiCO,GAClEE,EAAyBnlC,KAAK0qB,IAAIwa,EAA4BT,GAEpE,GAAIjF,EAASr0B,WAAag6B,EAtOE,IAwO1B,YADA95C,KAAK+4C,6BAA6BO,EAAsBznB,qBAI1D,MACMkoB,EADkB/5C,KAAKu4C,uBAAuBqB,GACbT,EACvCn5C,KAAK+4C,6BAA6BO,EAAsBU,kCAAkCD,KAE5F,KACE/5C,KAAKk2C,OAAOsD,gBAAgB,gBAAgB,GAC5Cx5C,KAAKy0C,MAAMwF,kBAIfj6C,KAAKy0C,MAAMyF,iBACb,CAEQ,4BAAAnB,CAA6BoB,GAEnC,MAAMC,EAA4C,GAClDp6C,KAAKq6C,oBAAoBD,EAAuBD,GAEhDn6C,KAAK20C,YAAY2F,qBAAqBF,EACxC,CAEO,mBAAAG,CAAoBC,GACzBx6C,KAAKy6C,qBAAqBD,GAC1Bx6C,KAAK80C,gBAAgB4F,iBAAiBF,GACtCx6C,KAAKw1C,eAAgB,EAChBx1C,KAAKu0C,aACRv0C,KAAKg3C,QAET,CAEO,QAAA3B,GACL,OAAOr1C,KAAK80C,gBAAgBO,UAC9B,mCCnKF,SAASsF,EAAelwC,GACtB,MAAyB,iBAAVA,EAAqB,GAAGA,MAAYA,CACrD,qFAxHA,MAaE,WAAA/K,CACkB4hB,GAAAthB,KAAAshB,QAAAA,EAZVthB,KAAA21B,OAAiB,GACjB31B,KAAA46C,QAAkB,GAClB56C,KAAA66C,KAAe,GACf76C,KAAA86C,MAAgB,GAChB96C,KAAA+6C,QAAkB,GAClB/6C,KAAAg7C,OAAiB,GACjBh7C,KAAAi7C,WAAqB,GACrBj7C,KAAAk7C,UAAoB,GACpBl7C,KAAAm7C,YAAsB,EACtBn7C,KAAAo7C,SAAkF,MAItF,CAEG,QAAA9E,CAAS3gB,GACd,MAAM5sB,EAAQ4xC,EAAehlB,GACzB31B,KAAK21B,SAAW5sB,IAGpB/I,KAAK21B,OAAS5sB,EACd/I,KAAKshB,QAAQxY,MAAMC,MAAQ/I,KAAK21B,OAClC,CAEO,SAAA4gB,CAAUqE,GACf,MAAMjyC,EAASgyC,EAAeC,GAC1B56C,KAAK46C,UAAYjyC,IAGrB3I,KAAK46C,QAAUjyC,EACf3I,KAAKshB,QAAQxY,MAAMH,OAAS3I,KAAK46C,QACnC,CAEO,MAAAxE,CAAOyE,GACZ,MAAM7vC,EAAM2vC,EAAeE,GACvB76C,KAAK66C,OAAS7vC,IAGlBhL,KAAK66C,KAAO7vC,EACZhL,KAAKshB,QAAQxY,MAAMkC,IAAMhL,KAAK66C,KAChC,CAEO,OAAAxE,CAAQyE,GACb,MAAMhwC,EAAO6vC,EAAeG,GACxB96C,KAAK86C,QAAUhwC,IAGnB9K,KAAK86C,MAAQhwC,EACb9K,KAAKshB,QAAQxY,MAAMgC,KAAO9K,KAAK86C,MACjC,CAEO,SAAAO,CAAUN,GACf,MAAMO,EAASX,EAAeI,GAC1B/6C,KAAK+6C,UAAYO,IAGrBt7C,KAAK+6C,QAAUO,EACft7C,KAAKshB,QAAQxY,MAAMwyC,OAASt7C,KAAK+6C,QACnC,CAEO,QAAAQ,CAASP,GACd,MAAM5mB,EAAQumB,EAAeK,GACzBh7C,KAAKg7C,SAAW5mB,IAGpBp0B,KAAKg7C,OAAS5mB,EACdp0B,KAAKshB,QAAQxY,MAAMsrB,MAAQp0B,KAAKg7C,OAClC,CAEO,YAAA7E,CAAanG,GACdhwC,KAAKi7C,aAAejL,IAGxBhwC,KAAKi7C,WAAajL,EAClBhwC,KAAKshB,QAAQ0uB,UAAYhwC,KAAKi7C,WAChC,CAEO,eAAAzB,CAAgBxJ,EAAmBwL,GACxCx7C,KAAKshB,QAAQ5gB,UAAU6W,OAAOy4B,EAAWwL,GACzCx7C,KAAKi7C,WAAaj7C,KAAKshB,QAAQ0uB,SACjC,CAEO,WAAA2F,CAAY1wC,GACbjF,KAAKk7C,YAAcj2C,IAGvBjF,KAAKk7C,UAAYj2C,EACjBjF,KAAKshB,QAAQxY,MAAM7D,SAAWjF,KAAKk7C,UACrC,CAEO,eAAA1E,CAAgBiF,GACjBz7C,KAAKm7C,aAAeM,IAGxBz7C,KAAKm7C,WAAaM,EAEhBz7C,KAAKshB,QAAQxY,MAAMK,UADjBsyC,EAC6B,6BAEA,GAEnC,CAEO,UAAAhF,CAAWiF,GACZ17C,KAAKo7C,WAAaM,IAGtB17C,KAAKo7C,SAAWM,EAChB17C,KAAKshB,QAAQxY,MAAM4yC,QAAU17C,KAAKo7C,SACpC,CAEO,YAAAv6C,CAAa86C,EAAclxC,GAChCzK,KAAKshB,QAAQzgB,aAAa86C,EAAMlxC,EAClC,83BClHF,MAAYopC,EAAG50C,EAAAC,EAAA,OACfE,EAAAF,EAAA,iCAKA,iBAAAQ,GAEmBM,KAAA47C,OAAS,IAAIx8C,EAAAy8C,gBACtB77C,KAAA87C,qBAAmD,KACnD97C,KAAA+7C,gBAAyC,IA0EnD,CAxES,OAAA1iC,GACLrZ,KAAKg8C,gBAAe,GACpBh8C,KAAK47C,OAAOviC,SACd,CAEO,cAAA2iC,CAAeC,GACpB,IAAKj8C,KAAKk8C,eACR,OAGFl8C,KAAK47C,OAAOvvC,QACZrM,KAAK87C,qBAAuB,KAC5B,MAAMK,EAAiBn8C,KAAK+7C,gBAC5B/7C,KAAK+7C,gBAAkB,KAEnBE,GAAsBE,GACxBA,GAEJ,CAEO,YAAAD,GACL,QAASl8C,KAAK87C,oBAChB,CAEO,eAAArC,CACL2C,EACA1C,EACA2C,EACAC,EACAH,GAEIn8C,KAAKk8C,gBACPl8C,KAAKg8C,gBAAe,GAEtBh8C,KAAK87C,qBAAuBQ,EAC5Bt8C,KAAK+7C,gBAAkBI,EAEvB,IAAII,EAAgCH,EAEpC,IACEA,EAAeI,kBAAkB9C,GACjC15C,KAAK47C,OAAOj7C,KAAI,EAAAvB,EAAAqE,cAAa,KAC3B,IACE24C,EAAeK,sBAAsB/C,EACvC,CAAE,MAEF,IAEJ,CAAE,MACA6C,EAAc1I,EAAIpyB,UAAU26B,EAC9B,CAEAp8C,KAAK47C,OAAOj7C,IAAIkzC,EAAIvwC,sBAClBi5C,EACA1I,EAAIxwB,UAAUY,aACb9iB,IACKA,EAAEw4C,UAAY0C,GAKlBl7C,EAAE6E,iBACFhG,KAAK87C,qBAAsB36C,IALzBnB,KAAKg8C,gBAAe,MAS1Bh8C,KAAK47C,OAAOj7C,IAAIkzC,EAAIvwC,sBAClBi5C,EACA1I,EAAIxwB,UAAUa,WACb/iB,GAAoBnB,KAAKg8C,gBAAe,IAE7C,8FCnFF,MAAAU,EAAAx9C,EAAA,MAEAy9C,EAAAz9C,EAAA,MAGA,MAAA09C,UAAyCF,EAAAtI,kBAEvC,WAAA10C,CAAYiwB,EAAwBzmB,EAA4CwrC,GAC9E,MAAMmI,EAAmBltB,EAAWmtB,sBAC9BC,EAAiBptB,EAAWqtB,2BAkBlC,GAjBAj9C,MAAM,CACJy0C,WAAYtrC,EAAQsrC,WACpBE,KAAMA,EACNK,eAAgB,IAAI4H,EAAAM,eACjB/zC,EAAQg0C,oBAAsBh0C,EAAQi0C,wBAA0B,EAC9C,IAAlBj0C,EAAQmnB,WAA4C,EAAInnB,EAAQi0C,wBAChD,IAAhBj0C,EAAQknB,SAA0C,EAAIlnB,EAAQ+oB,sBAC/D4qB,EAAiB9zC,MACjB8zC,EAAiBO,YACjBL,EAAeM,YAEjBnI,WAAYhsC,EAAQmnB,WACpB8kB,wBAAyB,mBACzBxlB,WAAYA,EACZklB,aAAc3rC,EAAQ2rC,eAGpB3rC,EAAQg0C,oBACV,MAAM,IAAIn7C,MAAM,oDAGlB/B,KAAKi2C,cAActhC,KAAKkiB,OAAO3tB,EAAQi0C,wBAA0Bj0C,EAAQo0C,sBAAwB,GAAI,OAAG14C,EAAWsE,EAAQo0C,qBAC7H,CAEU,aAAA1F,CAAc2F,EAAoBC,GAC1Cx9C,KAAKk2C,OAAOI,SAASiH,GACrBv9C,KAAKk2C,OAAOG,QAAQmH,EACtB,CAEU,cAAA/F,CAAegG,EAAmBC,GAC1C19C,KAAKshB,QAAQg1B,SAASmH,GACtBz9C,KAAKshB,QAAQi1B,UAAUmH,GACvB19C,KAAKshB,QAAQ+0B,QAAQ,GACrBr2C,KAAKshB,QAAQ+5B,UAAU,EACzB,CAEO,YAAAsC,CAAax8C,GAIlB,OAHAnB,KAAKw1C,cAAgBx1C,KAAKi3C,yBAAyB91C,EAAEi8C,cAAgBp9C,KAAKw1C,cAC1Ex1C,KAAKw1C,cAAgBx1C,KAAKo3C,6BAA6Bj2C,EAAEk8C,aAAer9C,KAAKw1C,cAC7Ex1C,KAAKw1C,cAAgBx1C,KAAK62C,mBAAmB11C,EAAE4H,QAAU/I,KAAKw1C,cACvDx1C,KAAKw1C,aACd,CAEU,4BAAAsD,CAA6BN,EAAiBC,GACtD,OAAOD,CACT,CAEU,sBAAAD,CAAuBp3C,GAC/B,OAAOA,EAAEy3C,KACX,CAEU,gCAAAS,CAAiCl4C,GACzC,OAAOA,EAAE03C,KACX,CAEU,oBAAA4B,CAAqBrzB,GAC7BpnB,KAAKk2C,OAAOK,UAAUnvB,EACxB,CAEO,mBAAAizB,CAAoBl1C,EAA4B43C,GACrD53C,EAAOk4C,WAAaN,CACtB,CAEO,aAAAnsB,CAAc1nB,GACnBlJ,KAAKu6C,oBAAsC,IAAlBrxC,EAAQmnB,WAA4C,EAAInnB,EAAQi0C,yBACzFn9C,KAAK80C,gBAAgB8I,yBAAyC,IAAhB10C,EAAQknB,SAA0C,EAAIlnB,EAAQ+oB,uBAC5GjyB,KAAKg1C,sBAAsB6I,cAAc30C,EAAQmnB,YACjDrwB,KAAK40C,cAAgB1rC,EAAQ2rC,YAC/B,q6BC9EF,MAAYV,EAAQl1C,EAAAC,EAAA,MAOd4+C,EAA6B,IAAI59C,QAEvC,SAAS69C,EAA4BC,GACnC,IAAKA,EAAEpnC,QAAUonC,EAAEpnC,SAAWonC,EAC5B,OAAO,KAGT,IACE,MAAMnxB,EAAWmxB,EAAEnxB,SACboxB,EAAiBD,EAAEpnC,OAAOiW,SAChC,GAAwB,SAApBA,EAASwW,QAA+C,SAA1B4a,EAAe5a,QAAqBxW,EAASwW,SAAW4a,EAAe5a,OACvG,OAAO,IAEX,CAAE,MACA,OAAO,IACT,CAEA,OAAO2a,EAAEpnC,MACX,CAEA,MAAMsnC,EAEI,gCAAOC,CAA0Bv8B,GACvC,IAAIw8B,EAAmBN,EAA2Bh6C,IAAI8d,GACtD,IAAKw8B,EAAkB,CACrBA,EAAmB,GACnBN,EAA2Bh5C,IAAI8c,EAAcw8B,GAC7C,IACIxnC,EADAonC,EAAmBp8B,EAEvB,GACEhL,EAASmnC,EAA4BC,GACjCpnC,EACFwnC,EAAiBn6C,KAAK,CACpBiT,OAAQ,IAAImnC,QAAQL,GACpBM,cAAeN,EAAEO,cAAgB,OAGnCH,EAAiBn6C,KAAK,CACpBiT,OAAQ,IAAImnC,QAAQL,GACpBM,cAAe,OAGnBN,EAAIpnC,QACGonC,EACX,CACA,OAAOI,EAAiB72C,MAAM,EAChC,CAEO,uDAAOi3C,CAAiDC,EAAqBC,GAElF,IAAKA,GAAkBD,IAAgBC,EACrC,MAAO,CACL1zC,IAAK,EACLF,KAAM,GAIV,IAAIE,EAAM,EACNF,EAAO,EAEX,MAAM6zC,EAAc3+C,KAAKm+C,0BAA0BM,GAEnD,IAAK,MAAMG,KAAiBD,EAAa,CACvC,MAAME,EAAgBD,EAAc1nC,OAAO4nC,QAI3C,GAHA9zC,GAAO6zC,GAAel9B,SAAW,EACjC7W,GAAQ+zC,GAAen9B,SAAW,EAE9Bm9B,IAAkBH,EACpB,MAGF,IAAKE,EAAcN,cACjB,MAGF,MAAMS,EAAeH,EAAcN,cAAcl1C,wBACjD4B,GAAO+zC,EAAa/zC,IACpBF,GAAQi0C,EAAaj0C,IACvB,CAEA,MAAO,CACLE,IAAKA,EACLF,KAAMA,EAEV,uBAuBF,MAkBE,WAAApL,CAAYkiB,EAAsBzgB,GAChCnB,KAAKg/C,UAAYC,KAAK3wB,MACtBtuB,KAAKk/C,aAAe/9C,EACpBnB,KAAK42C,WAA0B,IAAbz1C,EAAEyU,OACpB5V,KAAKm/C,aAA4B,IAAbh+C,EAAEyU,OACtB5V,KAAKo/C,YAA2B,IAAbj+C,EAAEyU,OACrB5V,KAAK25C,QAAUx4C,EAAEw4C,QAEjB35C,KAAKmF,OAAShE,EAAEgE,OAEhBnF,KAAKk6B,OAAS/4B,EAAE+4B,QAAU,EACX,aAAX/4B,EAAEqQ,OACJxR,KAAKk6B,OAAS,GAEhBl6B,KAAKuf,QAAUpe,EAAEoe,QACjBvf,KAAKq/C,SAAWl+C,EAAEk+C,SAClBr/C,KAAK6e,OAAS1d,EAAE0d,OAChB7e,KAAKwf,QAAUre,EAAEqe,QAEM,iBAAZre,EAAEy3C,OACX54C,KAAKs/C,KAAOn+C,EAAEy3C,MACd54C,KAAKu/C,KAAOp+C,EAAE03C,QAEd74C,KAAKs/C,KAAOn+C,EAAE4J,QAAU/K,KAAKmF,OAAO6R,cAAcwoC,KAAKnC,WAAar9C,KAAKmF,OAAO6R,cAAcyoC,gBAAgBpC,WAC9Gr9C,KAAKu/C,KAAOp+C,EAAE8J,QAAUjL,KAAKmF,OAAO6R,cAAcwoC,KAAKxtB,UAAYhyB,KAAKmF,OAAO6R,cAAcyoC,gBAAgBztB,WAG/G,MAAM0tB,EAAgBxB,EAAYM,iDAAiD58B,EAAczgB,EAAE2hB,MACnG9iB,KAAKs/C,MAAQI,EAAc50C,KAC3B9K,KAAKu/C,MAAQG,EAAc10C,GAC7B,CAEO,cAAAhF,GACLhG,KAAKk/C,aAAal5C,gBACpB,CAEO,eAAAuF,GACLvL,KAAKk/C,aAAa3zC,iBACpB,wBA0BF,MAOE,WAAA7L,CAAYyB,EAA4Bw+C,EAAiB,EAAGC,EAAiB,GAE3E5/C,KAAKk/C,aAAe/9C,GAAK,KACzBnB,KAAKmF,OAAShE,EAAKA,EAAEgE,QAAWhE,EAAU0+C,YAAc1+C,EAAE2+C,YAAc,KAAQ,KAEhF9/C,KAAK4/C,OAASA,EACd5/C,KAAK2/C,OAASA,EAEd,IAAII,GAA2B,EAC/B,GAAI5L,EAAS6L,SAAU,CACrB,MAAMC,EAAqBC,UAAUC,UAAUC,MAAM,iBAErDL,GAD2BE,EAAqBp4C,SAASo4C,EAAmB,GAAI,IAAM,MAC9C,GAC1C,CAEA,GAAI9+C,EAAG,CACL,MAAMk/C,EAAKl/C,EACLm/C,EAAKn/C,EACLo/C,EAAmBp/C,EAAE2hB,MAAMy9B,kBAAoB,EAErD,QAA8B,IAAnBF,EAAGG,YAEVxgD,KAAK4/C,OADHG,EACYM,EAAGG,aAAe,IAAMD,GAExBF,EAAGG,YAAc,SAE5B,QAAgC,IAArBF,EAAGG,eAAiCH,EAAGI,OAASJ,EAAGG,cACnEzgD,KAAK4/C,QAAUU,EAAGpmB,OAAS,OACtB,GAAe,UAAX/4B,EAAEqQ,KAAkB,CAC7B,MAAM7G,EAAKxJ,EAEPwJ,EAAGg2C,YAAch2C,EAAGi2C,eAClBzM,EAASx+B,YAAcw+B,EAASx1B,MAClC3e,KAAK4/C,QAAUz+C,EAAEy+C,OAAS,EAE1B5/C,KAAK4/C,QAAUz+C,EAAEy+C,OAGnB5/C,KAAK4/C,QAAUz+C,EAAEy+C,OAAS,EAE9B,CAEA,QAA8B,IAAnBS,EAAGQ,YACR1M,EAAS2M,UAAY3M,EAASr0B,UAChC9f,KAAK2/C,QAAWU,EAAGQ,YAAc,IAEjC7gD,KAAK2/C,OADII,EACKM,EAAGQ,aAAe,IAAMN,GAExBF,EAAGQ,YAAc,SAE5B,QAAkC,IAAvBP,EAAGS,iBAAmCT,EAAGI,OAASJ,EAAGS,gBACrE/gD,KAAK2/C,QAAUx+C,EAAE+4B,OAAS,OACrB,GAAe,UAAX/4B,EAAEqQ,KAAkB,CAC7B,MAAM7G,EAAKxJ,EAEPwJ,EAAGg2C,YAAch2C,EAAGi2C,eAClBzM,EAASx+B,YAAcw+B,EAASx1B,MAClC3e,KAAK2/C,QAAUx+C,EAAEw+C,OAAS,EAE1B3/C,KAAK2/C,QAAUx+C,EAAEw+C,OAGnB3/C,KAAK2/C,QAAUx+C,EAAEw+C,OAAS,EAE9B,CAEoB,IAAhB3/C,KAAK4/C,QAAgC,IAAhB5/C,KAAK2/C,QAAgBx+C,EAAE6/C,aAE5ChhD,KAAK4/C,OADHG,EACY5+C,EAAE6/C,YAAc,IAAMT,GAEtBp/C,EAAE6/C,WAAa,IAGnC,CACF,CAEO,cAAAh7C,GACLhG,KAAKk/C,cAAcl5C,gBACrB,CAEO,eAAAuF,GACLvL,KAAKk/C,cAAc3zC,iBACrB,mGC7RF,MAAAyC,EAAA9O,EAAA,MACAE,EAAAF,EAAA,MAoCA,MAAA+hD,EAaE,WAAAvhD,CACmBwhD,EACjBn4C,EACAq0C,EACAC,EACA10C,EACAqoB,EACAgB,GANiBhyB,KAAAkhD,oBAAAA,EAbXlhD,KAAAmhD,uBAA0Bv8C,EAqB5B5E,KAAKkhD,sBACPn4C,GAAgB,EAChBq0C,GAA4B,EAC5BC,GAA0B,EAC1B10C,GAAkB,EAClBqoB,GAA8B,EAC9BgB,GAAwB,GAG1BhyB,KAAKohD,cAAgB/D,EACrBr9C,KAAKqhD,aAAervB,EAEhBjpB,EAAQ,IACVA,EAAQ,GAENs0C,EAAat0C,EAAQq0C,IACvBC,EAAaD,EAAcr0C,GAEzBs0C,EAAa,IACfA,EAAa,GAGX10C,EAAS,IACXA,EAAS,GAEPqpB,EAAYrpB,EAASqoB,IACvBgB,EAAYhB,EAAeroB,GAEzBqpB,EAAY,IACdA,EAAY,GAGdhyB,KAAK+I,MAAQA,EACb/I,KAAKo9C,YAAcA,EACnBp9C,KAAKq9C,WAAaA,EAClBr9C,KAAK2I,OAASA,EACd3I,KAAKgxB,aAAeA,EACpBhxB,KAAKgyB,UAAYA,CACnB,CAEO,MAAAsvB,CAAOC,GACZ,OACEvhD,KAAKohD,gBAAkBG,EAAMH,eAC7BphD,KAAKqhD,eAAiBE,EAAMF,cAC5BrhD,KAAK+I,QAAUw4C,EAAMx4C,OACrB/I,KAAKo9C,cAAgBmE,EAAMnE,aAC3Bp9C,KAAKq9C,aAAekE,EAAMlE,YAC1Br9C,KAAK2I,SAAW44C,EAAM54C,QACtB3I,KAAKgxB,eAAiBuwB,EAAMvwB,cAC5BhxB,KAAKgyB,YAAcuvB,EAAMvvB,SAE7B,CAEO,oBAAAwvB,CAAqB3Y,EAA8B4Y,GACxD,OAAO,IAAIR,EACTjhD,KAAKkhD,yBACoB,IAAjBrY,EAAO9/B,MAAwB8/B,EAAO9/B,MAAQ/I,KAAK+I,WAC5B,IAAvB8/B,EAAOuU,YAA8BvU,EAAOuU,YAAcp9C,KAAKo9C,YACvEqE,EAAwBzhD,KAAKohD,cAAgBphD,KAAKq9C,gBACxB,IAAlBxU,EAAOlgC,OAAyBkgC,EAAOlgC,OAAS3I,KAAK2I,YAC7B,IAAxBkgC,EAAO7X,aAA+B6X,EAAO7X,aAAehxB,KAAKgxB,aACzEywB,EAAwBzhD,KAAKqhD,aAAerhD,KAAKgyB,UAErD,CAEO,kBAAA0vB,CAAmB7Y,GACxB,OAAO,IAAIoY,EACTjhD,KAAKkhD,oBACLlhD,KAAK+I,MACL/I,KAAKo9C,iBACyB,IAAtBvU,EAAOwU,WAA6BxU,EAAOwU,WAAar9C,KAAKohD,cACrEphD,KAAK2I,OACL3I,KAAKgxB,kBACwB,IAArB6X,EAAO7W,UAA4B6W,EAAO7W,UAAYhyB,KAAKqhD,aAEvE,CAEO,iBAAAM,CAAkBC,EAAuBC,GAC9C,MAAMC,EAAgB9hD,KAAK+I,QAAU64C,EAAS74C,MACxCg5C,EAAsB/hD,KAAKo9C,cAAgBwE,EAASxE,YACpD4E,EAAqBhiD,KAAKq9C,aAAeuE,EAASvE,WAElD4E,EAAiBjiD,KAAK2I,SAAWi5C,EAASj5C,OAC1Cu5C,EAAuBliD,KAAKgxB,eAAiB4wB,EAAS5wB,aACtDmxB,EAAoBniD,KAAKgyB,YAAc4vB,EAAS5vB,UAEtD,MAAO,CACL6vB,kBAAmBA,EACnBO,SAAUR,EAAS74C,MACnBs5C,eAAgBT,EAASxE,YACzBkF,cAAeV,EAASvE,WAExBt0C,MAAO/I,KAAK+I,MACZq0C,YAAap9C,KAAKo9C,YAClBC,WAAYr9C,KAAKq9C,WAEjBkF,UAAWX,EAASj5C,OACpB65C,gBAAiBZ,EAAS5wB,aAC1ByxB,aAAcb,EAAS5vB,UAEvBrpB,OAAQ3I,KAAK2I,OACbqoB,aAAchxB,KAAKgxB,aACnBgB,UAAWhyB,KAAKgyB,UAEhB8vB,aAAcA,EACdC,mBAAoBA,EACpBC,kBAAmBA,EAEnBC,cAAeA,EACfC,oBAAqBA,EACrBC,iBAAkBA,EAEtB,kBAuCF,MAAAvyB,UAAgCxwB,EAAAK,WAY9B,WAAAC,CAAYwJ,GACVnJ,QAXMC,KAAA0iD,sBAAyB99C,EAOzB5E,KAAAgb,UAAYhb,KAAK0B,UAAU,IAAIsM,EAAAsB,SACvBtP,KAAAuC,SAAiCvC,KAAKgb,UAAUzM,MAK9DvO,KAAK2iD,sBAAwBz5C,EAAQ4mB,qBACrC9vB,KAAK4iD,8BAAgC15C,EAAQ6mB,6BAC7C/vB,KAAK6iD,OAAS,IAAI5B,EAAY/3C,EAAQ2mB,mBAAoB,EAAG,EAAG,EAAG,EAAG,EAAG,GACzE7vB,KAAK8iD,iBAAmB,IAC1B,CAEgB,OAAAzpC,GACVrZ,KAAK8iD,mBACP9iD,KAAK8iD,iBAAiBzpC,UACtBrZ,KAAK8iD,iBAAmB,MAE1B/iD,MAAMsZ,SACR,CAEO,uBAAA4W,CAAwBH,GAC7B9vB,KAAK2iD,sBAAwB7yB,CAC/B,CAEO,sBAAAizB,CAAuBhG,GAC5B,OAAO/8C,KAAK6iD,OAAOnB,mBAAmB3E,EACxC,CAEO,mBAAAD,GACL,OAAO98C,KAAK6iD,MACd,CAEO,mBAAA9xB,CAAoBvoB,EAAkCi5C,GAC3D,MAAMuB,EAAWhjD,KAAK6iD,OAAOrB,qBAAqBh5C,EAAYi5C,GAC9DzhD,KAAKijD,UAAUD,EAAUE,QAAQljD,KAAK8iD,mBAEtC9iD,KAAK8iD,kBAAkBK,uBAAuBnjD,KAAK6iD,OACrD,CAEO,uBAAAO,GACL,OAAIpjD,KAAK8iD,iBACA9iD,KAAK8iD,iBAAiBO,GAExBrjD,KAAK6iD,MACd,CAEO,wBAAA7F,GACL,OAAOh9C,KAAK6iD,MACd,CAEO,oBAAAvI,CAAqBzR,GAC1B,MAAMma,EAAWhjD,KAAK6iD,OAAOnB,mBAAmB7Y,GAE5C7oC,KAAK8iD,mBACP9iD,KAAK8iD,iBAAiBzpC,UACtBrZ,KAAK8iD,iBAAmB,MAG1B9iD,KAAKijD,UAAUD,GAAU,EAC3B,CAEO,uBAAAM,CAAwBza,EAA4B9W,GACzD,GAAmC,IAA/B/xB,KAAK2iD,sBAAT,CAIA,GAAI3iD,KAAK8iD,iBAAkB,CACzBja,EAAS,CACPwU,gBAA0C,IAAtBxU,EAAOwU,WAA6Br9C,KAAK8iD,iBAAiBO,GAAGhG,WAAaxU,EAAOwU,WACrGrrB,eAAwC,IAArB6W,EAAO7W,UAA4BhyB,KAAK8iD,iBAAiBO,GAAGrxB,UAAY6W,EAAO7W,WAGpG,MAAMuxB,EAAcvjD,KAAK6iD,OAAOnB,mBAAmB7Y,GAEnD,GAAI7oC,KAAK8iD,iBAAiBO,GAAGhG,aAAekG,EAAYlG,YAAcr9C,KAAK8iD,iBAAiBO,GAAGrxB,YAAcuxB,EAAYvxB,UACvH,OAEF,IAAIwxB,EAEFA,EADEzxB,EACmB,IAAI0xB,EAAyBzjD,KAAK8iD,iBAAiBY,KAAMH,EAAavjD,KAAK8iD,iBAAiBa,UAAW3jD,KAAK8iD,iBAAiB5P,UAE7HuQ,EAAyBphD,MAAMrC,KAAK6iD,OAAQU,EAAavjD,KAAK2iD,uBAErF3iD,KAAK8iD,iBAAiBzpC,UACtBrZ,KAAK8iD,iBAAmBU,CAC1B,KAAO,CACL,MAAMD,EAAcvjD,KAAK6iD,OAAOnB,mBAAmB7Y,GAEnD7oC,KAAK8iD,iBAAmBW,EAAyBphD,MAAMrC,KAAK6iD,OAAQU,EAAavjD,KAAK2iD,sBACxF,CAEA3iD,KAAK8iD,iBAAiBc,yBAA2B5jD,KAAK4iD,8BAA8B,KAC7E5iD,KAAK8iD,mBAGV9iD,KAAK8iD,iBAAiBc,yBAA2B,KACjD5jD,KAAK6jD,4BAhCP,MADE7jD,KAAKs6C,qBAAqBzR,EAmC9B,CAEO,yBAAAib,GACL,OAAOZ,QAAQljD,KAAK8iD,iBACtB,CAEQ,uBAAAe,GACN,IAAK7jD,KAAK8iD,iBACR,OAEF,MAAMja,EAAS7oC,KAAK8iD,iBAAiBiB,OAC/Bf,EAAWhjD,KAAK6iD,OAAOnB,mBAAmB7Y,GAIhD,OAFA7oC,KAAKijD,UAAUD,GAAU,GAEpBhjD,KAAK8iD,iBAINja,EAAOmb,QACThkD,KAAK8iD,iBAAiBzpC,eACtBrZ,KAAK8iD,iBAAmB,YAI1B9iD,KAAK8iD,iBAAiBc,yBAA2B5jD,KAAK4iD,8BAA8B,KAC7E5iD,KAAK8iD,mBAGV9iD,KAAK8iD,iBAAiBc,yBAA2B,KACjD5jD,KAAK6jD,mCAfP,CAiBF,CAEQ,SAAAZ,CAAUD,EAAuBnB,GACvC,MAAMoC,EAAWjkD,KAAK6iD,OAClBoB,EAAS3C,OAAO0B,KAGpBhjD,KAAK6iD,OAASG,EACdhjD,KAAKgb,UAAU/J,KAAKjR,KAAK6iD,OAAOlB,kBAAkBsC,EAAUpC,IAC9D,iBAGF,MAAMqC,EAMJ,WAAAxkD,CAAY29C,EAAoBrrB,EAAmBgyB,GACjDhkD,KAAKq9C,WAAaA,EAClBr9C,KAAKgyB,UAAYA,EACjBhyB,KAAKgkD,OAASA,CAChB,EAQF,SAASG,EAAmBT,EAAcL,GACxC,MAAMe,EAAQf,EAAKK,EACnB,OAAO,SAAUW,GACf,OAAOX,EAAOU,GAiGT,GALYE,EAKI,EAjGcD,EA6F9B1vC,KAAK4vC,IAAID,EAAG,KADrB,IAAqBA,CA3FnB,CACF,CAWA,MAAMb,EAWJ,WAAA/jD,CAAYgkD,EAA6BL,EAA2BM,EAAmBzQ,GACrFlzC,KAAK0jD,KAAOA,EACZ1jD,KAAKqjD,GAAKA,EACVrjD,KAAKkzC,SAAWA,EAChBlzC,KAAK2jD,UAAYA,EAEjB3jD,KAAK4jD,yBAA2B,KAEhC5jD,KAAKwkD,iBACP,CAEQ,eAAAA,GACNxkD,KAAKykD,YAAczkD,KAAK0kD,eAAe1kD,KAAK0jD,KAAKrG,WAAYr9C,KAAKqjD,GAAGhG,WAAYr9C,KAAKqjD,GAAGt6C,OACzF/I,KAAK2kD,WAAa3kD,KAAK0kD,eAAe1kD,KAAK0jD,KAAK1xB,UAAWhyB,KAAKqjD,GAAGrxB,UAAWhyB,KAAKqjD,GAAG16C,OACxF,CAEQ,cAAA+7C,CAAehB,EAAcL,EAAYuB,GAE/C,GADcjwC,KAAK0qB,IAAIqkB,EAAOL,GAClB,IAAMuB,EAAc,CAC9B,IAAIC,EAAmBC,EAQvB,OAPIpB,EAAOL,GACTwB,EAAQnB,EAAO,IAAOkB,EACtBE,EAAQzB,EAAK,IAAOuB,IAEpBC,EAAQnB,EAAO,IAAOkB,EACtBE,EAAQzB,EAAK,IAAOuB,GA7CJ/lD,EA+CIslD,EAAmBT,EAAMmB,GA/CdtgC,EA+CsB4/B,EAAmBW,EAAOzB,GA/CjC0B,EA+CsC,IA9CnF,SAAUV,GACf,OAAIA,EAAaU,EACRlmD,EAAEwlD,EAAaU,GAEjBxgC,GAAG8/B,EAAaU,IAAQ,EAAIA,GACrC,CA0CE,CAhDJ,IAAwBlmD,EAAe0lB,EAAewgC,EAiDlD,OAAOZ,EAAmBT,EAAML,EAClC,CAEO,OAAAhqC,GACiC,OAAlCrZ,KAAK4jD,2BACP5jD,KAAK4jD,yBAAyBvqC,UAC9BrZ,KAAK4jD,yBAA2B,KAEpC,CAEO,sBAAAT,CAAuBphC,GAC5B/hB,KAAKqjD,GAAKthC,EAAM2/B,mBAAmB1hD,KAAKqjD,IACxCrjD,KAAKwkD,iBACP,CAEO,IAAAT,GACL,OAAO/jD,KAAKglD,MAAM/F,KAAK3wB,MACzB,CAEU,KAAA02B,CAAM12B,GACd,MAAM+1B,GAAc/1B,EAAMtuB,KAAK2jD,WAAa3jD,KAAKkzC,SAEjD,GAAImR,EAAa,EAAG,CAClB,MAAMY,EAAgBjlD,KAAKykD,YAAYJ,GACjCa,EAAellD,KAAK2kD,WAAWN,GACrC,OAAO,IAAIH,EAAsBe,EAAeC,GAAc,EAChE,CAEA,OAAO,IAAIhB,EAAsBlkD,KAAKqjD,GAAGhG,WAAYr9C,KAAKqjD,GAAGrxB,WAAW,EAC1E,CAEO,YAAO3vB,CAAMqhD,EAA6BL,EAA2BnQ,GAC1EA,GAAsB,GACtB,MAAMyQ,EAAY1E,KAAK3wB,MAAQ,GAE/B,OAAO,IAAIm1B,EAAyBC,EAAML,EAAIM,EAAWzQ,EAC3D,83BCvdF,MAAYW,EAAG50C,EAAAC,EAAA,OACf40C,EAAA50C,EAAA,MACAimD,EAAAjmD,EAAA,MAEAkmD,EAAAlmD,EAAA,MAEAmmD,EAAAnmD,EAAA,MACAg1C,EAAAh1C,EAAA,MACAyjB,EAAAzjB,EAAA,MACA8O,EAAA9O,EAAA,MACAE,EAAAF,EAAA,MACYi1C,EAAQl1C,EAAAC,EAAA,MACpBgwB,EAAAhwB,EAAA,MAQA,MAAMomD,EAMJ,WAAA5lD,CAAYs/C,EAAmBW,EAAgBC,GAC7C5/C,KAAKg/C,UAAYA,EACjBh/C,KAAK2/C,OAASA,EACd3/C,KAAK4/C,OAASA,EACd5/C,KAAKulD,MAAQ,CACf,EAGF,MAAMC,EASJ,WAAA9lD,GACEM,KAAKylD,UAAY,EACjBzlD,KAAK0lD,QAAU,GACf1lD,KAAK2lD,QAAU,EACf3lD,KAAK4lD,OAAS,CAChB,CAEO,oBAAAC,GACL,IAAqB,IAAjB7lD,KAAK2lD,SAAiC,IAAhB3lD,KAAK4lD,MAC7B,OAAO,EAGT,IAAIE,EAAqB,EACrBP,EAAQ,EACRQ,EAAY,EAEZ1zC,EAAQrS,KAAK4lD,MACjB,MAAkB,IAAXvzC,GAAc,CACnB,MAAM2zC,EAAa3zC,IAAUrS,KAAK2lD,OAASG,EAAqBnxC,KAAK4vC,IAAI,GAAIwB,GAI7E,GAHAD,GAAsBE,EACtBT,GAASvlD,KAAK0lD,QAAQrzC,GAAOkzC,MAAQS,EAEjC3zC,IAAUrS,KAAK2lD,OACjB,MAGFtzC,GAASrS,KAAKylD,UAAYpzC,EAAQ,GAAKrS,KAAKylD,UAC5CM,GACF,CAEA,OAAQR,GAAS,EACnB,CAEO,wBAAAU,CAAyB9kD,GAC9B,GAAIgzC,EAAS6L,SAAU,CACrB,MAAMp+B,EAAeiyB,EAAIpyB,UAAUtgB,EAAE+9C,cAC/BgH,EAAiB/R,EAASgS,cAAcvkC,GAC9C5hB,KAAKomD,OAAOnH,KAAK3wB,MAAOntB,EAAEw+C,OAASuG,EAAgB/kD,EAAEy+C,OAASsG,EAChE,MACElmD,KAAKomD,OAAOnH,KAAK3wB,MAAOntB,EAAEw+C,OAAQx+C,EAAEy+C,OAExC,CAEO,MAAAwG,CAAOpH,EAAmBW,EAAgBC,GAC/C,IAAIyG,EAAe,KACnB,MAAMpkC,EAAO,IAAIqjC,EAAyBtG,EAAWW,EAAQC,IAExC,IAAjB5/C,KAAK2lD,SAAiC,IAAhB3lD,KAAK4lD,OAC7B5lD,KAAK0lD,QAAQ,GAAKzjC,EAClBjiB,KAAK2lD,OAAS,EACd3lD,KAAK4lD,MAAQ,IAEbS,EAAermD,KAAK0lD,QAAQ1lD,KAAK4lD,OAEjC5lD,KAAK4lD,OAAS5lD,KAAK4lD,MAAQ,GAAK5lD,KAAKylD,UACjCzlD,KAAK4lD,QAAU5lD,KAAK2lD,SACtB3lD,KAAK2lD,QAAU3lD,KAAK2lD,OAAS,GAAK3lD,KAAKylD,WAEzCzlD,KAAK0lD,QAAQ1lD,KAAK4lD,OAAS3jC,GAG7BA,EAAKsjC,MAAQvlD,KAAKsmD,cAAcrkC,EAAMokC,EACxC,CAEQ,aAAAC,CAAcrkC,EAAgCokC,GAEpD,GAAI1xC,KAAK0qB,IAAIpd,EAAK09B,QAAU,GAAKhrC,KAAK0qB,IAAIpd,EAAK29B,QAAU,EACvD,OAAO,EAGT,IAAI2F,EAAgB,GAMpB,GAJKvlD,KAAKumD,aAAatkC,EAAK09B,SAAY3/C,KAAKumD,aAAatkC,EAAK29B,UAC7D2F,GAAS,KAGPc,EAAc,CAChB,MAAMG,EAAY7xC,KAAK0qB,IAAIpd,EAAK09B,QAC1B8G,EAAY9xC,KAAK0qB,IAAIpd,EAAK29B,QAE1B8G,EAAoB/xC,KAAK0qB,IAAIgnB,EAAa1G,QAC1CgH,EAAoBhyC,KAAK0qB,IAAIgnB,EAAazG,QAE1CgH,EAAYjyC,KAAKkZ,IAAIlZ,KAAKC,IAAI4xC,EAAWE,GAAoB,GAC7DG,EAAYlyC,KAAKkZ,IAAIlZ,KAAKC,IAAI6xC,EAAWE,GAAoB,GAE7DG,EAAYnyC,KAAKkZ,IAAI24B,EAAWE,GAChCK,EAAYpyC,KAAKkZ,IAAI44B,EAAWE,GAEhBG,EAAYF,IAAc,GAAKG,EAAYF,IAAc,IAE7EtB,GAAS,GAEb,CAEA,OAAO5wC,KAAKC,IAAID,KAAKkZ,IAAI03B,EAAO,GAAI,EACtC,CAEQ,YAAAgB,CAAa97C,GAEnB,OADckK,KAAK0qB,IAAI1qB,KAAK6d,MAAM/nB,GAASA,GAC3B,GAClB,EA5GuB+6C,EAAAwB,SAAW,IAAIxB,EA+GxC,MAAAr1B,UAA6C+jB,EAAAG,OA2B3C,WAAWnrC,GACT,OAAOlJ,KAAKmjB,QACd,CAEA,WAAAzjB,CAAmBoC,EAAsBoH,EAA4CymB,GAGnF,IAAIs3B,EAFJlnD,QAReC,KAAAgb,UAAYhb,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAuC,SAAiCvC,KAAKgb,UAAUzM,MAQ9DrF,EAAUA,GAAW,GAErB,MAAMg+C,GAAkBv3B,EACpBA,EACFs3B,EAAqBt3B,GAErBzmB,EAAQqnB,wBAAyB,EACjC02B,EAAqB,IAAI/3B,EAAAU,WAAW,CAClCC,oBAAoB,EACpBC,qBAAsB,EACtBC,6BAA+BzF,GAAaupB,EAAI9jB,6BAA6B8jB,EAAIpyB,UAAU3f,GAAUwoB,MAIzGtqB,KAAKmjB,SAuVT,SAAwBmxB,GACtB,MAAMt1B,EAA4C,CAChDw1B,gBAAwC,IAApBF,EAAKE,YAA6BF,EAAKE,WAC3DxE,eAAsC,IAAnBsE,EAAKtE,UAA4BsE,EAAKtE,UAAY,GACrE1f,gBAAwC,IAApBgkB,EAAKhkB,YAA6BgkB,EAAKhkB,WAC3DQ,sBAAoD,IAA1BwjB,EAAKxjB,kBAAmCwjB,EAAKxjB,iBACvEq2B,cAAoC,IAAlB7S,EAAK6S,UAA2B7S,EAAK6S,SACvDC,0CAA4F,IAA9C9S,EAAK8S,sCAAuD9S,EAAK8S,qCAC/GC,6BAAkE,IAAjC/S,EAAK+S,yBAA0C/S,EAAK+S,wBACrFC,gBAAwC,IAApBhT,EAAKgT,YAA6BhT,EAAKgT,WAC3Dp1B,iCAA0E,IAArCoiB,EAAKpiB,4BAA8CoiB,EAAKpiB,4BAA8B,EAC3HE,2BAA8D,IAA/BkiB,EAAKliB,sBAAwCkiB,EAAKliB,sBAAwB,EACzGm1B,2BAA8D,IAA/BjT,EAAKiT,uBAAwCjT,EAAKiT,sBACjFh3B,4BAAgE,IAAhC+jB,EAAK/jB,wBAAyC+jB,EAAK/jB,uBAEnFi3B,qBAAkD,IAAzBlT,EAAKkT,gBAAkClT,EAAKkT,gBAAkB,KAEvFn3B,gBAAwC,IAApBikB,EAAKjkB,WAA6BikB,EAAKjkB,WAAY,EACvE8sB,6BAAkE,IAAjC7I,EAAK6I,wBAA0C7I,EAAK6I,wBAA0B,GAC/GG,0BAA4D,IAA9BhJ,EAAKgJ,qBAAuChJ,EAAKgJ,qBAAuB,EACtGJ,yBAA0D,IAA7B5I,EAAK4I,qBAAsC5I,EAAK4I,oBAE7E9sB,cAAoC,IAAlBkkB,EAAKlkB,SAA2BkkB,EAAKlkB,SAAU,EACjE6B,2BAA8D,IAA/BqiB,EAAKriB,sBAAwCqiB,EAAKriB,sBAAwB,GACzGzB,uBAAsD,IAA3B8jB,EAAK9jB,mBAAoC8jB,EAAK9jB,kBACzEi3B,wBAAwD,IAA5BnT,EAAKmT,mBAAqCnT,EAAKmT,mBAAqB,EAEhG5S,kBAA4C,IAAtBP,EAAKO,cAA+BP,EAAKO,cAUjE,OAPA71B,EAAOs+B,0BAA6D,IAA9BhJ,EAAKgJ,qBAAuChJ,EAAKgJ,qBAAuBt+B,EAAOm+B,wBACrHn+B,EAAOyoC,wBAAyD,IAA5BnT,EAAKmT,mBAAqCnT,EAAKmT,mBAAqBzoC,EAAOiT,sBAE3GkiB,EAASx1B,QACXK,EAAOgxB,WAAa,cAGfhxB,CACT,CA7XoB0oC,CAAex+C,GAC/BlJ,KAAK20C,YAAcsS,EAEnBjnD,KAAK0B,UAAU1B,KAAK20C,YAAYpyC,SAAUpB,IACxCnB,KAAK4xB,cAAczwB,GACnBnB,KAAKgb,UAAU/J,KAAK9P,MAElB+lD,GACFlnD,KAAK0B,UAAU1B,KAAK20C,aAGtB,MAAMgT,EAAgC,CACpC72B,iBAAmB82B,GAAwC5nD,KAAK6nD,kBAAkBD,GAClF1N,gBAAiB,IAAMl6C,KAAK8nD,mBAC5B7N,cAAe,IAAMj6C,KAAK+nD,kBAE5B/nD,KAAKgoD,mBAAqBhoD,KAAK0B,UAAU,IAAI2jD,EAAA4C,kBAAkBjoD,KAAK20C,YAAa30C,KAAKmjB,SAAUwkC,IAChG3nD,KAAKkoD,qBAAuBloD,KAAK0B,UAAU,IAAI0jD,EAAAxI,oBAAoB58C,KAAK20C,YAAa30C,KAAKmjB,SAAUwkC,IAEpG3nD,KAAKmoD,SAAW/vC,SAAS3X,cAAc,OACvCT,KAAKmoD,SAASnY,UAAY,4BAA8BhwC,KAAKmjB,SAAS6sB,UACtEhwC,KAAKmoD,SAAStnD,aAAa,OAAQ,gBACnCb,KAAKmoD,SAASr/C,MAAM7D,SAAW,WAC/BjF,KAAKmoD,SAASlnD,YAAYa,GAC1B9B,KAAKmoD,SAASlnD,YAAYjB,KAAKkoD,qBAAqB5mC,QAAQA,SAC5DthB,KAAKmoD,SAASlnD,YAAYjB,KAAKgoD,mBAAmB1mC,QAAQA,SAEtDthB,KAAKmjB,SAASmN,YAChBtwB,KAAKooD,mBAAqB,IAAItU,EAAA2B,YAAYr9B,SAAS3X,cAAc,QACjET,KAAKooD,mBAAmBjS,aAAa,gBACrCn2C,KAAKmoD,SAASlnD,YAAYjB,KAAKooD,mBAAmB9mC,SAElDthB,KAAKqoD,kBAAoB,IAAIvU,EAAA2B,YAAYr9B,SAAS3X,cAAc,QAChET,KAAKqoD,kBAAkBlS,aAAa,gBACpCn2C,KAAKmoD,SAASlnD,YAAYjB,KAAKqoD,kBAAkB/mC,SAEjDthB,KAAKsoD,sBAAwB,IAAIxU,EAAA2B,YAAYr9B,SAAS3X,cAAc,QACpET,KAAKsoD,sBAAsBnS,aAAa,gBACxCn2C,KAAKmoD,SAASlnD,YAAYjB,KAAKsoD,sBAAsBhnC,WAErDthB,KAAKooD,mBAAqB,KAC1BpoD,KAAKqoD,kBAAoB,KACzBroD,KAAKsoD,sBAAwB,MAG/BtoD,KAAKuoD,iBAAmBvoD,KAAKmjB,SAASqkC,iBAAmBxnD,KAAKmoD,SAE9DnoD,KAAKwoD,qBAAuB,GAC5BxoD,KAAKyoD,0BAA0BzoD,KAAKmjB,SAAS2N,kBAE7C9wB,KAAK0oD,aAAa1oD,KAAKuoD,iBAAmBpnD,GAAMnB,KAAK2oD,iBAAiBxnD,IACtEnB,KAAK4oD,cAAc5oD,KAAKuoD,iBAAmBpnD,GAAMnB,KAAK6oD,kBAAkB1nD,IAExEnB,KAAK8oD,aAAe9oD,KAAK0B,UAAU,IAAIihB,EAAAomC,cACvC/oD,KAAKgpD,aAAc,EACnBhpD,KAAKipD,cAAe,EAEpBjpD,KAAKw1C,eAAgB,EAErBx1C,KAAKkpD,iBAAkB,CACzB,CAEgB,OAAA7vC,GACdrZ,KAAKwoD,sBAAuB,EAAAppD,EAAAia,SAAQrZ,KAAKwoD,sBACzCzoD,MAAMsZ,SACR,CAEO,UAAA8X,GACL,OAAOnxB,KAAKmoD,QACd,CAEO,mBAAArL,GACL,OAAO98C,KAAK20C,YAAYmI,qBAC1B,CAEO,mBAAA/rB,CAAoBvoB,GACzBxI,KAAK20C,YAAY5jB,oBAAoBvoB,GAAY,EACnD,CAEO,iBAAAspB,CAAkB+W,GACnBA,EAAO9W,eACT/xB,KAAK20C,YAAY2O,wBAAwBza,EAAQA,EAAO9W,gBAExD/xB,KAAK20C,YAAY2F,qBAAqBzR,EAE1C,CAEO,iBAAAhX,GACL,OAAO7xB,KAAK20C,YAAYqI,0BAC1B,CAEO,eAAAmM,CAAgBC,GACrBppD,KAAKmjB,SAAS6sB,UAAYoZ,EACtBjV,EAASx1B,QACX3e,KAAKmjB,SAAS6sB,WAAa,cAE7BhwC,KAAKmoD,SAASnY,UAAY,4BAA8BhwC,KAAKmjB,SAAS6sB,SACxE,CAEO,aAAApf,CAAcy4B,QACwB,IAAhCA,EAAWv4B,mBACpB9wB,KAAKmjB,SAAS2N,iBAAmBu4B,EAAWv4B,iBAC5C9wB,KAAKyoD,0BAA0BzoD,KAAKmjB,SAAS2N,wBAEO,IAA3Cu4B,EAAWn3B,8BACpBlyB,KAAKmjB,SAAS+O,4BAA8Bm3B,EAAWn3B,kCAET,IAArCm3B,EAAWj3B,wBACpBpyB,KAAKmjB,SAASiP,sBAAwBi3B,EAAWj3B,4BAEH,IAArCi3B,EAAW9B,wBACpBvnD,KAAKmjB,SAASokC,sBAAwB8B,EAAW9B,4BAEd,IAA1B8B,EAAWh5B,aACpBrwB,KAAKmjB,SAASkN,WAAag5B,EAAWh5B,iBAEL,IAAxBg5B,EAAWj5B,WACpBpwB,KAAKmjB,SAASiN,SAAWi5B,EAAWj5B,eAEQ,IAAnCi5B,EAAWnM,sBACpBl9C,KAAKmjB,SAAS+5B,oBAAsBmM,EAAWnM,0BAEL,IAAjCmM,EAAW74B,oBACpBxwB,KAAKmjB,SAASqN,kBAAoB64B,EAAW74B,wBAEG,IAAvC64B,EAAWlM,0BACpBn9C,KAAKmjB,SAASg6B,wBAA0BkM,EAAWlM,8BAEL,IAArCkM,EAAWp3B,wBACpBjyB,KAAKmjB,SAAS8O,sBAAwBo3B,EAAWp3B,4BAEZ,IAA5Bo3B,EAAWxU,eACpB70C,KAAKmjB,SAAS0xB,aAAewU,EAAWxU,cAE1C70C,KAAKkoD,qBAAqBt3B,cAAc5wB,KAAKmjB,UAC7CnjB,KAAKgoD,mBAAmBp3B,cAAc5wB,KAAKmjB,UAEtCnjB,KAAKmjB,SAASqxB,YACjBx0C,KAAKspD,SAET,CAEO,iCAAAC,CAAkCrK,GACvCl/C,KAAK6nD,kBAAkB,IAAI1C,EAAAqE,mBAAmBtK,GAChD,CAIQ,yBAAAuJ,CAA0BgB,GAGhC,GAFqBzpD,KAAKwoD,qBAAqBjnD,OAAS,IAEpCkoD,IAIpBzpD,KAAKwoD,sBAAuB,EAAAppD,EAAAia,SAAQrZ,KAAKwoD,sBAErCiB,GAAc,CAChB,MAAMC,EAAgBxK,IACpBl/C,KAAK6nD,kBAAkB,IAAI1C,EAAAqE,mBAAmBtK,KAGhDl/C,KAAKwoD,qBAAqBvkD,KAAK4vC,EAAIvwC,sBAAsBtD,KAAKuoD,iBAAkB1U,EAAIxwB,UAAUc,YAAaulC,EAAc,CAAEC,SAAS,IACtI,CACF,CAEQ,iBAAA9B,CAAkB1mD,GACxB,GAAIA,EAAE+9C,cAAczhB,iBAClB,OAGF,MAAMmsB,EAAapE,EAAqBwB,SACxC4C,EAAW3D,yBAAyB9kD,GAEpC,IAAI0oD,GAAY,EAEhB,GAAI1oD,EAAEy+C,QAAUz+C,EAAEw+C,OAAQ,CACxB,IAAIC,EAASz+C,EAAEy+C,OAAS5/C,KAAKmjB,SAAS+O,4BAClCytB,EAASx+C,EAAEw+C,OAAS3/C,KAAKmjB,SAAS+O,4BAElClyB,KAAKmjB,SAASokC,wBACZvnD,KAAKmjB,SAASmkC,YAAc3H,EAASC,IAAW,EAClDD,EAASC,EAAS,EACTjrC,KAAK0qB,IAAIugB,IAAWjrC,KAAK0qB,IAAIsgB,GACtCA,EAAS,EAETC,EAAS,GAIT5/C,KAAKmjB,SAASgkC,YACfvH,EAAQD,GAAU,CAACA,EAAQC,IAG9B,MAAMkK,GAAgB3V,EAASx1B,OAASxd,EAAE+9C,cAAgB/9C,EAAE+9C,aAAaG,UACpEr/C,KAAKmjB,SAASmkC,aAAcwC,GAAkBnK,IACjDA,EAASC,EACTA,EAAS,GAGPz+C,EAAE+9C,cAAgB/9C,EAAE+9C,aAAargC,SACnC8gC,GAAkB3/C,KAAKmjB,SAASiP,sBAChCwtB,GAAkB5/C,KAAKmjB,SAASiP,uBAGlC,MAAM23B,EAAuB/pD,KAAK20C,YAAYyO,0BAE9C,IAAIhJ,EAA4C,GAChD,GAAIwF,EAAQ,CACV,MAAMoK,EAAiB,GAAqCpK,EACtDqK,EAAmBF,EAAqB/3B,WAAag4B,EAAiB,EAAIr1C,KAAKkiB,MAAMmzB,GAAkBr1C,KAAKoiB,KAAKizB,IACvHhqD,KAAKgoD,mBAAmB3N,oBAAoBD,EAAuB6P,EACrE,CACA,GAAItK,EAAQ,CACV,MAAMuK,EAAkB,GAAqCvK,EACvDwK,EAAoBJ,EAAqB1M,YAAc6M,EAAkB,EAAIv1C,KAAKkiB,MAAMqzB,GAAmBv1C,KAAKoiB,KAAKmzB,IAC3HlqD,KAAKkoD,qBAAqB7N,oBAAoBD,EAAuB+P,EACvE,CAEA/P,EAAwBp6C,KAAK20C,YAAYoO,uBAAuB3I,IAE5D2P,EAAqB1M,aAAejD,EAAsBiD,YAAc0M,EAAqB/3B,YAAcooB,EAAsBpoB,aAGjIhyB,KAAKmjB,SAASoN,wBAChBq5B,EAAW/D,uBAIT7lD,KAAK20C,YAAY2O,wBAAwBlJ,GAEzCp6C,KAAK20C,YAAY2F,qBAAqBF,GAGxCyP,GAAY,EAEhB,CAEA,IAAIO,EAAoBP,GACnBO,GAAqBpqD,KAAKmjB,SAASkkC,0BACtC+C,GAAoB,IAEjBA,GAAqBpqD,KAAKmjB,SAASikC,uCAAyCpnD,KAAKgoD,mBAAmB3S,YAAcr1C,KAAKkoD,qBAAqB7S,cAC/I+U,GAAoB,GAGlBA,IACFjpD,EAAE6E,iBACF7E,EAAEoK,kBAEN,CAEQ,aAAAqmB,CAAczwB,GACpBnB,KAAKw1C,cAAgBx1C,KAAKkoD,qBAAqBvK,aAAax8C,IAAMnB,KAAKw1C,cACvEx1C,KAAKw1C,cAAgBx1C,KAAKgoD,mBAAmBrK,aAAax8C,IAAMnB,KAAKw1C,cAEjEx1C,KAAKmjB,SAASmN,aAChBtwB,KAAKw1C,eAAgB,GAGnBx1C,KAAKkpD,iBACPlpD,KAAKqqD,UAGFrqD,KAAKmjB,SAASqxB,YACjBx0C,KAAKspD,SAET,CAEO,SAAAgB,GACL,IAAKtqD,KAAKmjB,SAASqxB,WACjB,MAAM,IAAIzyC,MAAM,sDAGlB/B,KAAKspD,SACP,CAEQ,OAAAA,GACN,GAAKtpD,KAAKw1C,gBAIVx1C,KAAKw1C,eAAgB,EAErBx1C,KAAKkoD,qBAAqBlR,SAC1Bh3C,KAAKgoD,mBAAmBhR,SAEpBh3C,KAAKmjB,SAASmN,YAAY,CAC5B,MAAMi6B,EAAcvqD,KAAK20C,YAAYqI,2BAC/BwN,EAAYD,EAAYv4B,UAAY,EACpCy4B,EAAaF,EAAYlN,WAAa,EAEtCqN,EAAiBD,EAAa,qBAAuB,GACrDE,EAAgBH,EAAY,oBAAsB,GAClDI,EAAoBH,GAAcD,EAAY,gCAAkC,GACtFxqD,KAAKooD,mBAAoBjS,aAAa,eAAeuU,KACrD1qD,KAAKqoD,kBAAmBlS,aAAa,eAAewU,KACpD3qD,KAAKsoD,sBAAuBnS,aAAa,eAAeyU,IAAmBD,IAAeD,IAC5F,CACF,CAIQ,gBAAA5C,GACN9nD,KAAKgpD,aAAc,EACnBhpD,KAAKqqD,SACP,CAEQ,cAAAtC,GACN/nD,KAAKgpD,aAAc,EACnBhpD,KAAK6qD,OACP,CAEQ,iBAAAhC,CAAkB1nD,GACxBnB,KAAKipD,cAAe,EACpBjpD,KAAK6qD,OACP,CAEQ,gBAAAlC,CAAiBxnD,GACvBnB,KAAKipD,cAAe,EACpBjpD,KAAKqqD,SACP,CAEQ,OAAAA,GACNrqD,KAAKgoD,mBAAmB1Q,cACxBt3C,KAAKkoD,qBAAqB5Q,cAC1Bt3C,KAAK8qD,eACP,CAEQ,KAAAD,GACD7qD,KAAKipD,cAAiBjpD,KAAKgpD,cAC9BhpD,KAAKgoD,mBAAmBxQ,YACxBx3C,KAAKkoD,qBAAqB1Q,YAE9B,CAEQ,aAAAsT,GACD9qD,KAAKipD,cAAiBjpD,KAAKgpD,aAC9BhpD,KAAK8oD,aAAajkC,aAAa,IAAM7kB,KAAK6qD,QAAO,IAErD,g5BCthBF,MAAA9W,EAAA70C,EAAA,KACAg1C,EAAAh1C,EAAA,MACAyjB,EAAAzjB,EAAA,MACY20C,EAAG50C,EAAAC,EAAA,OAgBf,MAAA62C,UAAoC7B,EAAAG,OASlC,WAAA30C,CAAY40C,GACVv0C,QACAC,KAAK+qD,gBAAkBzW,EAAK0W,eAE5BhrD,KAAKg2C,UAAY59B,SAAS3X,cAAc,OACxCT,KAAKg2C,UAAUhG,UAAY,yBAC3BhwC,KAAKg2C,UAAUltC,MAAM7D,SAAW,WAChCjF,KAAKg2C,UAAUltC,MAAMC,MAAQurC,EAAK2W,QAAU,KAC5CjrD,KAAKg2C,UAAUltC,MAAMH,OAAS2rC,EAAK4W,SAAW,UACtB,IAAb5W,EAAKtpC,MACdhL,KAAKg2C,UAAUltC,MAAMkC,IAAM,YAEJ,IAAdspC,EAAKxpC,OACd9K,KAAKg2C,UAAUltC,MAAMgC,KAAO,YAEH,IAAhBwpC,EAAKgH,SACdt7C,KAAKg2C,UAAUltC,MAAMwyC,OAAS,YAEN,IAAfhH,EAAKlgB,QACdp0B,KAAKg2C,UAAUltC,MAAMsrB,MAAQ,OAG/Bp0B,KAAKshB,QAAUlJ,SAAS3X,cAAc,OACtCT,KAAKshB,QAAQ0uB,UAAYsE,EAAKtE,UAG9BhwC,KAAKshB,QAAQxY,MAAM7D,SAAW,WAC9B,MAAMkmD,EAAYx2C,KAAKC,IAAI0/B,EAAK2W,QAAS3W,EAAK4W,UAC9ClrD,KAAKshB,QAAQxY,MAAMC,MAAQoiD,EAAY,KACvCnrD,KAAKshB,QAAQxY,MAAMH,OAASwiD,EAAY,UAChB,IAAb7W,EAAKtpC,MACdhL,KAAKshB,QAAQxY,MAAMkC,IAAMspC,EAAKtpC,IAAM,WAEb,IAAdspC,EAAKxpC,OACd9K,KAAKshB,QAAQxY,MAAMgC,KAAOwpC,EAAKxpC,KAAO,WAEb,IAAhBwpC,EAAKgH,SACdt7C,KAAKshB,QAAQxY,MAAMwyC,OAAShH,EAAKgH,OAAS,WAElB,IAAfhH,EAAKlgB,QACdp0B,KAAKshB,QAAQxY,MAAMsrB,MAAQkgB,EAAKlgB,MAAQ,MAG1Cp0B,KAAKs1C,oBAAsBt1C,KAAK0B,UAAU,IAAIqyC,EAAAwB,0BAC9Cv1C,KAAK0B,UAAUmyC,EAAIuX,8BAA8BprD,KAAKg2C,UAAWnC,EAAIxwB,UAAUW,aAAe7iB,GAAMnB,KAAKqrD,kBAAkBlqD,KAC3HnB,KAAK0B,UAAUmyC,EAAIuX,8BAA8BprD,KAAKshB,QAASuyB,EAAIxwB,UAAUW,aAAe7iB,GAAMnB,KAAKqrD,kBAAkBlqD,KAEzHnB,KAAKsrD,wBAA0BtrD,KAAK0B,UAAU,IAAImyC,EAAInvB,qBACtD1kB,KAAKurD,gCAAkCvrD,KAAK0B,UAAU,IAAIihB,EAAAomC,aAC5D,CAEQ,iBAAAsC,CAAkBlqD,GACnBA,EAAEgE,QAAYhE,EAAEgE,kBAAkB+zC,UAOvCl5C,KAAK+qD,kBACL/qD,KAAKsrD,wBAAwBlsC,SAC7Bpf,KAAKurD,gCAAgC1mC,aANZ,KACvB7kB,KAAKsrD,wBAAwBzmC,aAAa,IAAM7kB,KAAK+qD,kBAAmB,IAAO,GAAIlX,EAAIpyB,UAAUtgB,KAK/B,KAEpEnB,KAAKs1C,oBAAoBmE,gBACvBt4C,EAAEgE,OACFhE,EAAEu4C,UACFv4C,EAAEw4C,QACDC,MACD,KACE55C,KAAKsrD,wBAAwBlsC,SAC7Bpf,KAAKurD,gCAAgCnsC,WAIzCje,EAAE6E,iBACJ,yGCzFF,MAAAi3C,EAsDE,WAAAv9C,CAAYyrD,EAAmB3Q,EAAuBgR,EAA+B1U,EAAqB2U,EAAoB1O,GAC5H/8C,KAAK0rD,eAAiB/2C,KAAK6d,MAAMgoB,GACjCx6C,KAAK2rD,uBAAyBh3C,KAAK6d,MAAMg5B,GACzCxrD,KAAK4rD,WAAaj3C,KAAK6d,MAAM24B,GAE7BnrD,KAAK6rD,aAAe/U,EACpB92C,KAAK8rD,YAAcL,EACnBzrD,KAAK+rD,gBAAkBhP,EAEvB/8C,KAAKgsD,uBAAyB,EAC9BhsD,KAAKisD,mBAAoB,EACzBjsD,KAAKksD,oBAAsB,EAC3BlsD,KAAKmsD,qBAAuB,EAC5BnsD,KAAKosD,wBAA0B,EAE/BpsD,KAAKqsD,wBACP,CAEO,KAAA9S,GACL,OAAO,IAAI0D,EAAej9C,KAAK4rD,WAAY5rD,KAAK0rD,eAAgB1rD,KAAK2rD,uBAAwB3rD,KAAK6rD,aAAc7rD,KAAK8rD,YAAa9rD,KAAK+rD,gBACzI,CAEO,cAAAhV,CAAeD,GACpB,MAAMwV,EAAe33C,KAAK6d,MAAMskB,GAChC,OAAI92C,KAAK6rD,eAAiBS,IACxBtsD,KAAK6rD,aAAeS,EACpBtsD,KAAKqsD,0BACE,EAGX,CAEO,aAAAlV,CAAcsU,GACnB,MAAMc,EAAc53C,KAAK6d,MAAMi5B,GAC/B,OAAIzrD,KAAK8rD,cAAgBS,IACvBvsD,KAAK8rD,YAAcS,EACnBvsD,KAAKqsD,0BACE,EAGX,CAEO,iBAAAv6B,CAAkBirB,GACvB,MAAMyP,EAAkB73C,KAAK6d,MAAMuqB,GACnC,OAAI/8C,KAAK+rD,kBAAoBS,IAC3BxsD,KAAK+rD,gBAAkBS,EACvBxsD,KAAKqsD,0BACE,EAGX,CAEO,gBAAA3R,CAAiBF,GACtBx6C,KAAK0rD,eAAiB/2C,KAAK6d,MAAMgoB,EACnC,CAEO,YAAAiS,CAAatB,GAClB,MAAMuB,EAAa/3C,KAAK6d,MAAM24B,GAC1BnrD,KAAK4rD,aAAec,IACtB1sD,KAAK4rD,WAAac,EAClB1sD,KAAKqsD,yBAET,CAEO,wBAAAzO,CAAyB4N,GAC9BxrD,KAAK2rD,uBAAyBh3C,KAAK6d,MAAMg5B,EAC3C,CAEQ,qBAAOmB,CACbnB,EACAL,EACArU,EACA2U,EACA1O,GAEA,MAAM6P,EAAwBj4C,KAAKkZ,IAAI,EAAGipB,EAAc0U,GAClDqB,EAA4Bl4C,KAAKkZ,IAAI,EAAG++B,EAAwB,EAAIzB,GACpE2B,EAAoBrB,EAAa,GAAKA,EAAa3U,EAEzD,IAAKgW,EACH,MAAO,CACLF,sBAAuBj4C,KAAK6d,MAAMo6B,GAClCE,iBAAkBA,EAClBC,mBAAoBp4C,KAAK6d,MAAMq6B,GAC/BG,oBAAqB,EACrBC,uBAAwB,GAI5B,MAAMF,EAAqBp4C,KAAK6d,MAAM7d,KAAKkZ,IAzJnB,GAyJ4ClZ,KAAKkiB,MAAMigB,EAAc+V,EAA4BpB,KAEnHuB,GAAuBH,EAA4BE,IAAuBtB,EAAa3U,GACvFmW,EAA0BlQ,EAAiBiQ,EAEjD,MAAO,CACLJ,sBAAuBj4C,KAAK6d,MAAMo6B,GAClCE,iBAAkBA,EAClBC,mBAAoBp4C,KAAK6d,MAAMu6B,GAC/BC,oBAAqBA,EACrBC,uBAAwBt4C,KAAK6d,MAAMy6B,GAEvC,CAEQ,sBAAAZ,GACN,MAAMz9B,EAAIquB,EAAe0P,eAAe3sD,KAAK2rD,uBAAwB3rD,KAAK4rD,WAAY5rD,KAAK6rD,aAAc7rD,KAAK8rD,YAAa9rD,KAAK+rD,iBAChI/rD,KAAKgsD,uBAAyBp9B,EAAEg+B,sBAChC5sD,KAAKisD,kBAAoBr9B,EAAEk+B,iBAC3B9sD,KAAKksD,oBAAsBt9B,EAAEm+B,mBAC7B/sD,KAAKmsD,qBAAuBv9B,EAAEo+B,oBAC9BhtD,KAAKosD,wBAA0Bx9B,EAAEq+B,sBACnC,CAEO,YAAAnV,GACL,OAAO93C,KAAK4rD,UACd,CAEO,iBAAA/5B,GACL,OAAO7xB,KAAK+rD,eACd,CAEO,qBAAArU,GACL,OAAO13C,KAAKgsD,sBACd,CAEO,qBAAArU,GACL,OAAO33C,KAAK0rD,cACd,CAEO,QAAArW,GACL,OAAOr1C,KAAKisD,iBACd,CAEO,aAAApU,GACL,OAAO73C,KAAKksD,mBACd,CAEO,iBAAAnU,GACL,OAAO/3C,KAAKosD,uBACd,CAEO,kCAAAnT,CAAmCpyC,GACxC,IAAK7G,KAAKisD,kBACR,OAAO,EAGT,MAAMiB,EAAwBrmD,EAAS7G,KAAK4rD,WAAa5rD,KAAKksD,oBAAsB,EACpF,OAAOv3C,KAAK6d,MAAM06B,EAAwBltD,KAAKmsD,qBACjD,CAEO,uCAAAnT,CAAwCnyC,GAC7C,IAAK7G,KAAKisD,kBACR,OAAO,EAGT,MAAMkB,EAAkBtmD,EAAS7G,KAAK4rD,WACtC,IAAIxR,EAAwBp6C,KAAK+rD,gBAMjC,OALIoB,EAAkBntD,KAAKosD,wBACzBhS,GAAyBp6C,KAAK6rD,aAE9BzR,GAAyBp6C,KAAK6rD,aAEzBzR,CACT,CAEO,iCAAAJ,CAAkCoK,GACvC,IAAKpkD,KAAKisD,kBACR,OAAO,EAGT,MAAMiB,EAAwBltD,KAAKosD,wBAA0BhI,EAC7D,OAAOzvC,KAAK6d,MAAM06B,EAAwBltD,KAAKmsD,qBACjD,0HC9OF,MAAAxpC,EAAAzjB,EAAA,MACAE,EAAAF,EAAA,MAGA,MAAA+1C,UAAmD71C,EAAAK,WAWjD,WAAAC,CAAYw1C,EAAiCkY,EAA0BC,GACrEttD,QACAC,KAAKstD,YAAcpY,EACnBl1C,KAAKutD,kBAAoBH,EACzBptD,KAAKwtD,oBAAsBH,EAC3BrtD,KAAKmoD,SAAW,KAChBnoD,KAAKytD,YAAa,EAClBztD,KAAK0tD,WAAY,EACjB1tD,KAAK2tD,qBAAsB,EAC3B3tD,KAAK4tD,kBAAmB,EACxB5tD,KAAK6tD,aAAe7tD,KAAK0B,UAAU,IAAIihB,EAAAomC,aACzC,CAEO,aAAAlL,CAAc3I,GACfl1C,KAAKstD,cAAgBpY,IACvBl1C,KAAKstD,YAAcpY,EACnBl1C,KAAK8tD,yBAET,CAEO,kBAAAvW,CAAmBwW,GACxB/tD,KAAK2tD,oBAAsBI,EAC3B/tD,KAAK8tD,wBACP,CAEQ,uBAAAE,GACN,OAAoB,IAAhBhuD,KAAKstD,cAGW,IAAhBttD,KAAKstD,aAGFttD,KAAK2tD,oBACd,CAEQ,sBAAAG,GACN,MAAMG,EAAkBjuD,KAAKguD,0BAEzBhuD,KAAK4tD,mBAAqBK,IAC5BjuD,KAAK4tD,iBAAmBK,EACxBjuD,KAAKkuD,mBAET,CAEO,WAAA9Y,CAAYC,GACbr1C,KAAK0tD,YAAcrY,IACrBr1C,KAAK0tD,UAAYrY,EACjBr1C,KAAKkuD,mBAET,CAEO,UAAAxY,CAAWp0B,GAChBthB,KAAKmoD,SAAW7mC,EAChBthB,KAAKmoD,SAAShS,aAAan2C,KAAKwtD,qBAEhCxtD,KAAKu3C,oBAAmB,EAC1B,CAEO,gBAAA2W,GAEAluD,KAAK0tD,UAKN1tD,KAAK4tD,iBACP5tD,KAAKqqD,UAELrqD,KAAK6qD,OAAM,GAPX7qD,KAAK6qD,OAAM,EASf,CAEQ,OAAAR,GACFrqD,KAAKytD,aAGTztD,KAAKytD,YAAa,EAElBztD,KAAK6tD,aAAaM,YAAY,KAC5BnuD,KAAKmoD,UAAUhS,aAAan2C,KAAKutD,oBAChC,GACL,CAEQ,KAAA1C,CAAMuD,GACZpuD,KAAK6tD,aAAazuC,SACbpf,KAAKytD,aAGVztD,KAAKytD,YAAa,EAClBztD,KAAKmoD,UAAUhS,aAAan2C,KAAKwtD,qBAAuBY,EAAe,cAAgB,KACzF,wvCC1GF,MAAYC,EAAQpvD,EAAAC,EAAA,OACpBE,EAAAF,EAAA,MAEMovD,EAAgC,iBAAXp3C,OAAsBA,OAASnY,WAE1D,SAASwvD,EAAQC,EAAqBC,EAAY,GAChD,OAAOD,EAAMA,EAAMjtD,QAAU,EAAIktD,GACnC,CAsCA,MAAMC,EAQJ,WAAAhvD,CAAmBoC,GACjB9B,KAAK8B,QAAUA,EACf9B,KAAKmiB,KAAOusC,EAAeC,UAC3B3uD,KAAK4uD,KAAOF,EAAeC,SAC7B,EAVuBD,EAAAC,UAAY,IAAID,OAAoB9pD,GAa7D,MAAMiqD,EAAN,WAAAnvD,GAEUM,KAAA8uD,OAA4BJ,EAAeC,UAC3C3uD,KAAA+uD,MAA2BL,EAAeC,SA4DpD,CA1DS,IAAA1qD,CAAKnC,GACV,OAAO9B,KAAKgvD,QAAQltD,GAAS,EAC/B,CAEQ,OAAAktD,CAAQltD,EAAYmtD,GAC1B,MAAMC,EAAU,IAAIR,EAAe5sD,GACnC,GAAI9B,KAAK8uD,SAAWJ,EAAeC,UACjC3uD,KAAK8uD,OAASI,EACdlvD,KAAK+uD,MAAQG,OAER,GAAID,EAAU,CACnB,MAAME,EAAUnvD,KAAK+uD,MACrB/uD,KAAK+uD,MAAQG,EACbA,EAAQN,KAAOO,EACfA,EAAQhtC,KAAO+sC,CAEjB,KAAO,CACL,MAAME,EAAWpvD,KAAK8uD,OACtB9uD,KAAK8uD,OAASI,EACdA,EAAQ/sC,KAAOitC,EACfA,EAASR,KAAOM,CAClB,CACA,IAAIG,GAAY,EAChB,MAAO,KACAA,IACHA,GAAY,EACZrvD,KAAKsvD,QAAQJ,IAGnB,CAEQ,OAAAI,CAAQ1oD,GACd,GAAIA,EAAKgoD,OAASF,EAAeC,WAAa/nD,EAAKub,OAASusC,EAAeC,UAAW,CACpF,MAAMx6B,EAASvtB,EAAKgoD,KACpBz6B,EAAOhS,KAAOvb,EAAKub,KACnBvb,EAAKub,KAAKysC,KAAOz6B,CAEnB,MAAWvtB,EAAKgoD,OAASF,EAAeC,WAAa/nD,EAAKub,OAASusC,EAAeC,WAChF3uD,KAAK8uD,OAASJ,EAAeC,UAC7B3uD,KAAK+uD,MAAQL,EAAeC,WAEnB/nD,EAAKub,OAASusC,EAAeC,WACtC3uD,KAAK+uD,MAAQ/uD,KAAK+uD,MAAMH,KACxB5uD,KAAK+uD,MAAM5sC,KAAOusC,EAAeC,WAExB/nD,EAAKgoD,OAASF,EAAeC,YACtC3uD,KAAK8uD,OAAS9uD,KAAK8uD,OAAO3sC,KAC1BniB,KAAK8uD,OAAOF,KAAOF,EAAeC,UAEtC,CAEO,EAAEY,OAAOC,YACd,IAAI5oD,EAAO5G,KAAK8uD,OAChB,KAAOloD,IAAS8nD,EAAeC,iBACvB/nD,EAAK9E,QACX8E,EAAOA,EAAKub,IAEhB,EAGF,IAAiBstC,GAAjB,SAAiBA,GACFA,EAAAC,IAAM,oBACND,EAAA1rC,OAAS,uBACT0rC,EAAAE,MAAQ,sBACRF,EAAAG,IAAM,qBACNH,EAAAI,aAAe,2BAC7B,CAND,CAAiBJ,IAAShxD,EAAAgxD,UAATA,EAAS,KA0D1B,MAAAK,UAA6B1wD,EAAAK,WAkB3B,WAAAC,GACEK,QAbMC,KAAA+vD,aAAc,EACL/vD,KAAAgwD,SAAW,IAAInB,EACf7uD,KAAAiwD,eAAiB,IAAIpB,EAapC7uD,KAAKkwD,eAAiB,GACtBlwD,KAAKmwD,QAAU,KACfnwD,KAAKowD,qBAAuB,EAE5B,MAAMxuC,EAAe0sC,EACrBtuD,KAAK0B,UAAU2sD,EAAS/qD,sBAAsBse,EAAaxJ,SAAU,aAAejX,GAAmBnB,KAAKqwD,kBAAkBlvD,GAAI,CAAEwoD,SAAS,KAC7I3pD,KAAK0B,UAAU2sD,EAAS/qD,sBAAsBse,EAAaxJ,SAAU,WAAajX,GAAmBnB,KAAKswD,gBAAgB1uC,EAAczgB,KACxInB,KAAK0B,UAAU2sD,EAAS/qD,sBAAsBse,EAAaxJ,SAAU,YAAcjX,GAAmBnB,KAAKuwD,iBAAiBpvD,GAAI,CAAEwoD,SAAS,IAC7I,CAEO,gBAAO6G,CAAU1uD,GACtB,IAAKguD,EAAQW,gBACX,OAAOrxD,EAAAK,WAAWixD,KAEfZ,EAAQa,YACXb,EAAQa,UAAY,IAAIb,GAG1B,MAAMpsD,EAASosD,EAAQa,UAAUX,SAAS/rD,KAAKnC,GAC/C,OAAO,EAAA1C,EAAAqE,cAAaC,EACtB,CAEO,mBAAOktD,CAAa9uD,GACzB,IAAKguD,EAAQW,gBACX,OAAOrxD,EAAAK,WAAWixD,KAEfZ,EAAQa,YACXb,EAAQa,UAAY,IAAIb,GAG1B,MAAMpsD,EAASosD,EAAQa,UAAUV,eAAehsD,KAAKnC,GACrD,OAAO,EAAA1C,EAAAqE,cAAaC,EACtB,CAGc,oBAAA+sD,GACZ,MAAO,iBAAkBnC,GAAcpO,UAAU2Q,eAAiB,CACpE,CAEgB,OAAAx3C,GACVrZ,KAAKmwD,UACPnwD,KAAKmwD,QAAQ92C,UACbrZ,KAAKmwD,QAAU,MAGjBpwD,MAAMsZ,SACR,CAEQ,iBAAAg3C,CAAkBlvD,GACxB,MAAM69C,EAAYC,KAAK3wB,MAEnBtuB,KAAKmwD,UACPnwD,KAAKmwD,QAAQ92C,UACbrZ,KAAKmwD,QAAU,MAGjB,IAAK,IAAIrxD,EAAI,EAAGgyD,EAAM3vD,EAAE4vD,cAAcxvD,OAAQzC,EAAIgyD,EAAKhyD,IAAK,CAC1D,MAAMkyD,EAAQ7vD,EAAE4vD,cAAc9uC,KAAKnjB,GAEnCkB,KAAKkwD,eAAec,EAAMC,YAAc,CACtC92B,GAAI62B,EAAMC,WACVC,cAAeF,EAAM7rD,OACrBgsD,iBAAkBnS,EAClBoS,aAAcJ,EAAMpY,MACpByY,aAAcL,EAAMnY,MACpByY,kBAAmB,CAACtS,GACpBuS,aAAc,CAACP,EAAMpY,OACrB4Y,aAAc,CAACR,EAAMnY,QAGvB,MAAM4Y,EAAMzxD,KAAK0xD,iBAAiBjC,EAAUE,MAAOqB,EAAM7rD,QACzDssD,EAAI7Y,MAAQoY,EAAMpY,MAClB6Y,EAAI5Y,MAAQmY,EAAMnY,MAClB74C,KAAK2xD,eAAeF,EACtB,CAEIzxD,KAAK+vD,cACP5uD,EAAE6E,iBACF7E,EAAEoK,kBACFvL,KAAK+vD,aAAc,EAEvB,CAEQ,eAAAO,CAAgB1uC,EAAsBzgB,GAC5C,MAAM69C,EAAYC,KAAK3wB,MAEjBsjC,EAAmBhpD,OAAOipD,KAAK7xD,KAAKkwD,gBAAgB3uD,OAE1D,IAAK,IAAIzC,EAAI,EAAGgyD,EAAM3vD,EAAE2wD,eAAevwD,OAAQzC,EAAIgyD,EAAKhyD,IAAK,CAE3D,MAAMkyD,EAAQ7vD,EAAE2wD,eAAe7vC,KAAKnjB,GAEpC,IAAKkB,KAAKkwD,eAAe6B,eAAe3xC,OAAO4wC,EAAMC,aAAc,CACjExqD,QAAQsB,KAAK,2BAA4BipD,GACzC,QACF,CAEA,MAAM/zC,EAAOjd,KAAKkwD,eAAec,EAAMC,YACjCe,EAAW/S,KAAK3wB,MAAQrR,EAAKk0C,iBAEnC,GAAIa,EAAWlC,EAAQmC,YAClBt9C,KAAK0qB,IAAIpiB,EAAKm0C,aAAe7C,EAAKtxC,EAAKs0C,eAAkB,IACzD58C,KAAK0qB,IAAIpiB,EAAKo0C,aAAe9C,EAAKtxC,EAAKu0C,eAAkB,GAAI,CAEhE,MAAMC,EAAMzxD,KAAK0xD,iBAAiBjC,EAAUC,IAAKzyC,EAAKi0C,eACtDO,EAAI7Y,MAAQ2V,EAAKtxC,EAAKs0C,cACtBE,EAAI5Y,MAAQ0V,EAAKtxC,EAAKu0C,cACtBxxD,KAAK2xD,eAAeF,EAEtB,MAAO,GAAIO,GAAYlC,EAAQmC,YAC9Bt9C,KAAK0qB,IAAIpiB,EAAKm0C,aAAe7C,EAAKtxC,EAAKs0C,eAAkB,IACzD58C,KAAK0qB,IAAIpiB,EAAKo0C,aAAe9C,EAAKtxC,EAAKu0C,eAAkB,GAAI,CAE5D,MAAMC,EAAMzxD,KAAK0xD,iBAAiBjC,EAAUI,aAAc5yC,EAAKi0C,eAC/DO,EAAI7Y,MAAQ2V,EAAKtxC,EAAKs0C,cACtBE,EAAI5Y,MAAQ0V,EAAKtxC,EAAKu0C,cACtBxxD,KAAK2xD,eAAeF,EAEtB,MAAO,GAAyB,IAArBG,EAAwB,CACjC,MAAMM,EAAS3D,EAAKtxC,EAAKs0C,cACnBY,EAAS5D,EAAKtxC,EAAKu0C,cAEnBY,EAAS7D,EAAKtxC,EAAKq0C,mBAAsBr0C,EAAKq0C,kBAAkB,GAChE3R,EAASuS,EAASj1C,EAAKs0C,aAAa,GACpC3R,EAASuS,EAASl1C,EAAKu0C,aAAa,GAEpCa,EAAa,IAAIryD,KAAKgwD,UAAUsC,OAAOhO,GAAKrnC,EAAKi0C,yBAAyBjqD,MAAQq9C,EAAEj+C,SAAS4W,EAAKi0C,gBACxGlxD,KAAKuyD,SAAS3wC,EAAcywC,EAAYrT,EACtCrqC,KAAK0qB,IAAIsgB,GAAUyS,EACnBzS,EAAS,EAAI,GAAK,EAClBuS,EACAv9C,KAAK0qB,IAAIugB,GAAUwS,EACnBxS,EAAS,EAAI,GAAK,EAClBuS,EAEJ,CAGAnyD,KAAK2xD,eAAe3xD,KAAK0xD,iBAAiBjC,EAAUG,IAAK3yC,EAAKi0C,uBACvDlxD,KAAKkwD,eAAec,EAAMC,WACnC,CAEIjxD,KAAK+vD,cACP5uD,EAAE6E,iBACF7E,EAAEoK,kBACFvL,KAAK+vD,aAAc,EAEvB,CAEQ,gBAAA2B,CAAiBlgD,EAAc0/C,GACrC,MAAM3iD,EAAQ6J,SAASo6C,YAAY,eAInC,OAHAjkD,EAAMkkD,UAAUjhD,GAAM,GAAO,GAC7BjD,EAAM2iD,cAAgBA,EACtB3iD,EAAMmkD,SAAW,EACVnkD,CACT,CAEQ,cAAAojD,CAAepjD,GACrB,GAAIA,EAAMiD,OAASi+C,EAAUC,IAAK,CAChC,MAAMiD,GAAc,IAAK1T,MAAQ2T,UACjC,IAAIC,EAEFA,EADEF,EAAc3yD,KAAKowD,qBAAuBN,EAAQgD,mBACtC,EAEA,EAGhB9yD,KAAKowD,qBAAuBuC,EAC5BpkD,EAAMmkD,SAAWG,CACnB,MAAWtkD,EAAMiD,OAASi+C,EAAU1rC,QAAUxV,EAAMiD,OAASi+C,EAAUI,eACrE7vD,KAAKowD,qBAAuB,GAG9B,GAAI7hD,EAAM2iD,yBAAyBjqD,KAAM,CACvC,IAAK,MAAM2pD,KAAgB5wD,KAAKiwD,eAC9B,GAAIW,EAAavqD,SAASkI,EAAM2iD,eAC9B,OAIJ,MAAM6B,EAAmC,GACzC,IAAK,MAAM5tD,KAAUnF,KAAKgwD,SACxB,GAAI7qD,EAAOkB,SAASkI,EAAM2iD,eAAgB,CACxC,IAAI8B,EAAQ,EACR1kC,EAAmB/f,EAAM2iD,cAC7B,KAAO5iC,GAAOA,IAAQnpB,GACpB6tD,IACA1kC,EAAMA,EAAI6H,cAEZ48B,EAAQ9uD,KAAK,CAAC+uD,EAAO7tD,GACvB,CAGF4tD,EAAQvwC,KAAK,CAAC3jB,EAAG0lB,IAAM1lB,EAAE,GAAK0lB,EAAE,IAEhC,IAAK,MAAO,CAAEpf,KAAW4tD,EACvB5tD,EAAOoR,cAAchI,GACrBvO,KAAK+vD,aAAc,CAEvB,CACF,CAEQ,QAAAwC,CAAS3wC,EAAsBywC,EAAwCY,EAAYC,EAAYC,EAAct+C,EAAWu+C,EAAYC,EAAcl/C,GACxJnU,KAAKmwD,QAAU9B,EAASt+B,6BAA6BnO,EAAc,KACjE,MAAM0M,EAAM2wB,KAAK3wB,MAEX8jC,EAAS9jC,EAAM2kC,EACrB,IAAIK,EAAY,EACZC,EAAY,EACZC,GAAU,EAEdN,GAAMpD,EAAQ2D,gBAAkBrB,EAChCgB,GAAMtD,EAAQ2D,gBAAkBrB,EAE5Bc,EAAK,IACPM,GAAU,EACVF,EAAYH,EAAOD,EAAKd,GAGtBgB,EAAK,IACPI,GAAU,EACVD,EAAYF,EAAOD,EAAKhB,GAG1B,MAAMX,EAAMzxD,KAAK0xD,iBAAiBjC,EAAU1rC,QAC5C0tC,EAAIiC,aAAeJ,EACnB7B,EAAI/+B,aAAe6gC,EACnBlB,EAAW7rC,QAAQinB,GAAKA,EAAEl3B,cAAck7C,IAEnC+B,GACHxzD,KAAKuyD,SAAS3wC,EAAcywC,EAAY/jC,EAAK4kC,EAAIC,EAAMt+C,EAAIy+C,EAAWF,EAAIC,EAAMl/C,EAAIo/C,IAG1F,CAEQ,gBAAAhD,CAAiBpvD,GACvB,MAAM69C,EAAYC,KAAK3wB,MAEvB,IAAK,IAAIxvB,EAAI,EAAGgyD,EAAM3vD,EAAE2wD,eAAevwD,OAAQzC,EAAIgyD,EAAKhyD,IAAK,CAE3D,MAAMkyD,EAAQ7vD,EAAE2wD,eAAe7vC,KAAKnjB,GAEpC,IAAKkB,KAAKkwD,eAAe6B,eAAe3xC,OAAO4wC,EAAMC,aAAc,CACjExqD,QAAQsB,KAAK,0BAA2BipD,GACxC,QACF,CAEA,MAAM/zC,EAAOjd,KAAKkwD,eAAec,EAAMC,YAEjCQ,EAAMzxD,KAAK0xD,iBAAiBjC,EAAU1rC,OAAQ9G,EAAKi0C,eACzDO,EAAIiC,aAAe1C,EAAMpY,MAAQ2V,EAAKtxC,EAAKs0C,cAC3CE,EAAI/+B,aAAes+B,EAAMnY,MAAQ0V,EAAKtxC,EAAKu0C,cAC3CC,EAAI7Y,MAAQoY,EAAMpY,MAClB6Y,EAAI5Y,MAAQmY,EAAMnY,MAClB4Y,EAAI1mD,QAAUimD,EAAMjmD,QACpB0mD,EAAIxmD,QAAU+lD,EAAM/lD,QACpBjL,KAAK2xD,eAAeF,GAEhBx0C,EAAKs0C,aAAahwD,OAAS,IAC7B0b,EAAKs0C,aAAa5tD,QAClBsZ,EAAKu0C,aAAa7tD,QAClBsZ,EAAKq0C,kBAAkB3tD,SAGzBsZ,EAAKs0C,aAAattD,KAAK+sD,EAAMpY,OAC7B37B,EAAKu0C,aAAavtD,KAAK+sD,EAAMnY,OAC7B57B,EAAKq0C,kBAAkBrtD,KAAK+6C,EAC9B,CAEIh/C,KAAK+vD,cACP5uD,EAAE6E,iBACF7E,EAAEoK,kBACFvL,KAAK+vD,aAAc,EAEvB,cArSwBD,EAAA2D,iBAAmB,KAEnB3D,EAAAmC,WAAa,IAWbnC,EAAAgD,mBAAqB,IAyC/BvpD,EAAA,CAtOhB,SAAiBoqD,EAAc1wD,EAAa2wD,GAC1C,IAAIC,EAAuB,KACvBC,EAAsB,KAc1B,GAZgC,mBAArBF,EAAWnpD,OACpBopD,EAAQ,QACRC,EAAKF,EAAWnpD,MAEG,IAAfqpD,EAAIvyD,QACNkF,QAAQsB,KAAK,kEAEoB,mBAAnB6rD,EAAW9vD,MAC3B+vD,EAAQ,MACRC,EAAKF,EAAW9vD,MAGbgwD,IAAOD,EACV,MAAM,IAAI9xD,MAAM,iBAGlB,MAAMgyD,EAAa,YAAY9wD,IACT2wD,EACRC,GAAS,YAAaG,GAUlC,OATKh0D,KAAK+xD,eAAegC,IACvBnrD,OAAOk5B,eAAe9hC,KAAM+zD,EAAY,CACtCE,cAAc,EACdC,YAAY,EACZC,UAAU,EACV1pD,MAAOqpD,EAAGM,MAAMp0D,KAAMg0D,KAIlBh0D,KAAgC+zD,EAC1C,CACF,oHC3CA,MAAArX,EAAAx9C,EAAA,MAEAy9C,EAAAz9C,EAAA,MAIA,MAAA+oD,UAAuCvL,EAAAtI,kBAKrC,WAAA10C,CAAYiwB,EAAwBzmB,EAA4CwrC,GAC9E,MAAMmI,EAAmBltB,EAAWmtB,sBAC9BC,EAAiBptB,EAAWqtB,2BAC5BqX,EAAYnrD,EAAQsnB,kBAC1BzwB,MAAM,CACJy0C,WAAYtrC,EAAQsrC,WACpBE,KAAMA,EACNK,eAAgB,IAAI4H,EAAAM,eACjBoX,EAAYnrD,EAAQ+oB,sBAAwB,EAC5B,IAAhB/oB,EAAQknB,SAA0C,EAAIlnB,EAAQ+oB,sBAC/D,EACA4qB,EAAiBl0C,OACjBk0C,EAAiB7rB,aACjB+rB,EAAe/qB,WAEjBkjB,WAAYhsC,EAAQknB,SACpB+kB,wBAAyB,iBACzBxlB,WAAYA,EACZklB,aAAc3rC,EAAQ2rC,eApBlB70C,KAAAs0D,kBAA4B,EAuBlCt0D,KAAKu0D,WAAWF,EAAWnrD,EAAQ+oB,uBAEnCjyB,KAAKi2C,cAAc,EAAGthC,KAAKkiB,OAAO3tB,EAAQ+oB,sBAAwB/oB,EAAQu+C,oBAAsB,GAAIv+C,EAAQu+C,wBAAoB7iD,EAClI,CAEU,aAAAgzC,CAAc2F,EAAoBC,GAC1Cx9C,KAAKk2C,OAAOK,UAAUgH,GACtBv9C,KAAKk2C,OAAOE,OAAOoH,EACrB,CAEU,cAAA/F,CAAegG,EAAmBC,GAC1C19C,KAAKshB,QAAQg1B,SAASoH,GACtB19C,KAAKshB,QAAQi1B,UAAUkH,GACvBz9C,KAAKshB,QAAQi6B,SAAS,GACtBv7C,KAAKshB,QAAQ80B,OAAO,EACtB,CAEO,YAAAuH,CAAax8C,GAIlB,OAHAnB,KAAKw1C,cAAgBx1C,KAAKi3C,yBAAyB91C,EAAE6vB,eAAiBhxB,KAAKw1C,cAC3Ex1C,KAAKw1C,cAAgBx1C,KAAKo3C,6BAA6Bj2C,EAAE6wB,YAAchyB,KAAKw1C,cAC5Ex1C,KAAKw1C,cAAgBx1C,KAAK62C,mBAAmB11C,EAAEwH,SAAW3I,KAAKw1C,cACxDx1C,KAAKw1C,aACd,CAEU,4BAAAsD,CAA6BN,EAAiBC,GACtD,OAAOA,CACT,CAEU,sBAAAF,CAAuBp3C,GAC/B,OAAOA,EAAE03C,KACX,CAEU,gCAAAQ,CAAiCl4C,GACzC,OAAOA,EAAEy3C,KACX,CAEU,oBAAA6B,CAAqBrzB,GAC7BpnB,KAAKk2C,OAAOI,SAASlvB,EACvB,CAEO,mBAAAizB,CAAoBl1C,EAA4B43C,GACrD53C,EAAO6sB,UAAY+qB,CACrB,CAEQ,YAAAyX,CAAapQ,GACnB,MAAMqQ,EAAkBz0D,KAAK20C,YAAYqI,2BACzCh9C,KAAK20C,YAAY2F,qBAAqB,CAAEtoB,UAAWyiC,EAAgBziC,UAAYoyB,GACjF,CAEQ,UAAAmQ,CAAW9jC,EAAqBrJ,GAEtC,GADApnB,KAAKs0D,kBAAoBltC,GACpBpnB,KAAK00D,WAAa10D,KAAK20D,WAAY,CACtC,MAAMC,EAAa,EACnB50D,KAAK00D,SAAW10D,KAAK61C,aAAa,CAChC7F,UAAW,4BACXhlC,IAAK4pD,EACL9pD,KAAM8pD,EACN3J,QAAS7jC,EACT8jC,SAAU9jC,EACV4jC,eAAgB,IAAMhrD,KAAKw0D,cAAcx0D,KAAKs0D,qBAEhDt0D,KAAK20D,WAAa30D,KAAK61C,aAAa,CAClC7F,UAAW,8BACXsL,OAAQsZ,EACR9pD,KAAM8pD,EACN3J,QAAS7jC,EACT8jC,SAAU9jC,EACV4jC,eAAgB,IAAMhrD,KAAKw0D,aAAax0D,KAAKs0D,oBAEjD,CAKA,GAHAt0D,KAAK60D,iBAAiB70D,KAAK00D,SAAUttC,GACrCpnB,KAAK60D,iBAAiB70D,KAAK20D,WAAYvtC,IAElCpnB,KAAK00D,WAAa10D,KAAK20D,WAC1B,OAGF,MAAM5gC,EAAUtD,EAAa,GAAK,OAClCzwB,KAAK00D,SAAS1e,UAAUltC,MAAMirB,QAAUA,EACxC/zB,KAAK00D,SAASpzC,QAAQxY,MAAMirB,QAAUA,EACtC/zB,KAAK20D,WAAW3e,UAAUltC,MAAMirB,QAAUA,EAC1C/zB,KAAK20D,WAAWrzC,QAAQxY,MAAMirB,QAAUA,CAC1C,CAEQ,gBAAA8gC,CAAiB/e,EAAmC1uB,GACrD0uB,IAGLA,EAAME,UAAUltC,MAAMC,MAAQ,GAAGqe,MACjC0uB,EAAME,UAAUltC,MAAMH,OAAS,GAAGye,MAClC0uB,EAAMx0B,QAAQxY,MAAMC,MAAQ,GAAGqe,MAC/B0uB,EAAMx0B,QAAQxY,MAAMH,OAAS,GAAGye,MAClC,CAEO,aAAAwJ,CAAc1nB,GACnB,MAAMiiD,EAAYjiD,EAAQsnB,kBAAoBtnB,EAAQ+oB,sBAAwB,EAC9EjyB,KAAK80C,gBAAgB2X,aAAatB,GAClCnrD,KAAKu0D,WAAWrrD,EAAQsnB,kBAAmBtnB,EAAQ+oB,uBACnDjyB,KAAKu6C,oBAAoC,IAAhBrxC,EAAQknB,SAA0C,EAAIlnB,EAAQ+oB,uBACvFjyB,KAAK80C,gBAAgB8I,yBAAyB,GAC9C59C,KAAKg1C,sBAAsB6I,cAAc30C,EAAQknB,UACjDpwB,KAAK40C,cAAgB1rC,EAAQ2rC,YAC/B,k4BCvIF,MAAYhB,EAAG50C,EAAAC,EAAA,OACfimD,EAAAjmD,EAAA,MACAE,EAAAF,EAAA,MAEA,MAAAm1C,UAAqCj1C,EAAAK,WAEzB,QAAAk3C,CAASr1B,EAAsBwzC,GACvC90D,KAAK0B,UAAUmyC,EAAIvwC,sBAAsBge,EAASuyB,EAAIxwB,UAAUC,MAAQniB,GAAkB2zD,EAAS,IAAI3P,EAAA4P,mBAAmBlhB,EAAIpyB,UAAUH,GAAUngB,KACpJ,CAEU,YAAAunD,CAAapnC,EAAsBwzC,GAC3C90D,KAAK0B,UAAUmyC,EAAIvwC,sBAAsBge,EAASuyB,EAAIxwB,UAAUG,WAAariB,GAAkB2zD,EAAS,IAAI3P,EAAA4P,mBAAmBlhB,EAAIpyB,UAAUH,GAAUngB,KACzJ,CAEU,aAAAynD,CAActnC,EAAsBwzC,GAC5C90D,KAAK0B,UAAUmyC,EAAIvwC,sBAAsBge,EAASuyB,EAAIxwB,UAAUI,YAActiB,GAAkB2zD,EAAS,IAAI3P,EAAA4P,mBAAmBlhB,EAAIpyB,UAAUH,GAAUngB,KAC1J,kHCVF,MAuBE,WAAAzB,CACUoS,GAAA9R,KAAA8R,eAAAA,EApBH9R,KAAAg1D,mBAA6B,EAO7Bh1D,KAAAi1D,qBAA+B,CAetC,CAKO,cAAA1uD,GACLvG,KAAKse,oBAAiB1Z,EACtB5E,KAAKue,kBAAe3Z,EACpB5E,KAAKg1D,mBAAoB,EACzBh1D,KAAKi1D,qBAAuB,CAC9B,CAKA,uBAAWC,GACT,OAAIl1D,KAAKg1D,kBACA,CAAC,EAAG,GAGRh1D,KAAKue,cAAiBve,KAAKse,gBAIzBte,KAAKm1D,6BAA+Bn1D,KAAKue,aAHvCve,KAAKse,cAIhB,CAMA,qBAAW82C,GACT,GAAIp1D,KAAKg1D,kBACP,MAAO,CAACh1D,KAAK8R,eAAe7J,KAAMjI,KAAK8R,eAAe3N,OAAOqQ,MAAQxU,KAAK8R,eAAe/Q,KAAO,GAGlG,GAAKf,KAAKse,eAAV,CAKA,IAAKte,KAAKue,cAAgBve,KAAKm1D,6BAA8B,CAC3D,MAAME,EAAkBr1D,KAAKse,eAAe,GAAKte,KAAKi1D,qBACtD,OAAII,EAAkBr1D,KAAK8R,eAAe7J,KAEpCotD,EAAkBr1D,KAAK8R,eAAe7J,OAAS,EAC1C,CAACjI,KAAK8R,eAAe7J,KAAMjI,KAAKse,eAAe,GAAK3J,KAAKkiB,MAAMw+B,EAAkBr1D,KAAK8R,eAAe7J,MAAQ,GAE/G,CAACotD,EAAkBr1D,KAAK8R,eAAe7J,KAAMjI,KAAKse,eAAe,GAAK3J,KAAKkiB,MAAMw+B,EAAkBr1D,KAAK8R,eAAe7J,OAEzH,CAACotD,EAAiBr1D,KAAKse,eAAe,GAC/C,CAGA,GAAIte,KAAKi1D,sBAEHj1D,KAAKue,aAAa,KAAOve,KAAKse,eAAe,GAAI,CAEnD,MAAM+2C,EAAkBr1D,KAAKse,eAAe,GAAKte,KAAKi1D,qBACtD,OAAII,EAAkBr1D,KAAK8R,eAAe7J,KACjC,CAACotD,EAAkBr1D,KAAK8R,eAAe7J,KAAMjI,KAAKse,eAAe,GAAK3J,KAAKkiB,MAAMw+B,EAAkBr1D,KAAK8R,eAAe7J,OAEzH,CAAC0M,KAAKkZ,IAAIwnC,EAAiBr1D,KAAKue,aAAa,IAAKve,KAAKue,aAAa,GAC7E,CAEF,OAAOve,KAAKue,YA3BZ,CA4BF,CAKO,0BAAA42C,GACL,MAAM9yD,EAAQrC,KAAKse,eACbhc,EAAMtC,KAAKue,aACjB,SAAKlc,IAAUC,KAGRD,EAAM,GAAKC,EAAI,IAAOD,EAAM,KAAOC,EAAI,IAAMD,EAAM,GAAKC,EAAI,GACrE,CAOO,UAAAgzD,CAAW76C,GAUhB,OARIza,KAAKse,iBACPte,KAAKse,eAAe,IAAM7D,GAExBza,KAAKue,eACPve,KAAKue,aAAa,IAAM9D,GAItBza,KAAKue,cAAgBve,KAAKue,aAAa,GAAK,GAC9Cve,KAAKuG,kBACE,MAILvG,KAAKse,gBAAkBte,KAAKse,eAAe,GAAK,KAClDte,KAAKse,eAAiB,CAAC,EAAG,IACnB,EAGX,+fC1IF,MAAAjf,EAAAH,EAAA,MAEAE,EAAAF,EAAA,MACA8O,EAAA9O,EAAA,MAEO,IAAMoZ,EAAN,cAA8BlZ,EAAAK,WAOnC,gBAAWihB,GAA0B,OAAO1gB,KAAK+I,MAAQ,GAAK/I,KAAK2I,OAAS,CAAG,CAK/E,WAAAjJ,CACE0Y,EACA+d,EACkCjM,GAElCnqB,QAFkCC,KAAAkqB,gBAAAA,EAZ7BlqB,KAAA+I,MAAgB,EAChB/I,KAAA2I,OAAiB,EAKP3I,KAAAu1D,kBAAoBv1D,KAAK0B,UAAU,IAAIsM,EAAAsB,SACxCtP,KAAAw1D,iBAAmBx1D,KAAKu1D,kBAAkBhnD,MAQxD,IACEvO,KAAKy1D,iBAAmBz1D,KAAK0B,UAAU,IAAIg0D,EAA2B11D,KAAKkqB,iBAC7E,CAAE,MACAlqB,KAAKy1D,iBAAmBz1D,KAAK0B,UAAU,IAAIi0D,EAAmBv9C,EAAU+d,EAAen2B,KAAKkqB,iBAC9F,CACAlqB,KAAK0B,UAAU1B,KAAKkqB,gBAAgByG,uBAAuB,CAAC,aAAc,YAAa,IAAM3wB,KAAKgc,WACpG,CAEO,OAAAA,GACL,MAAMgD,EAAShf,KAAKy1D,iBAAiBz5C,UACjCgD,EAAOjW,QAAU/I,KAAK+I,OAASiW,EAAOrW,SAAW3I,KAAK2I,SACxD3I,KAAK+I,MAAQiW,EAAOjW,MACpB/I,KAAK2I,OAASqW,EAAOrW,OACrB3I,KAAKu1D,kBAAkBtkD,OAE3B,yCAjCWqH,EAAe/O,EAAA,CAevBC,EAAA,EAAAnK,EAAA0tB,kBAfQzU,GAiDb,MAAes9C,UAA2Bx2D,EAAAK,WAA1C,WAAAC,uBACYM,KAAA61D,QAA0B,CAAE9sD,MAAO,EAAGJ,OAAQ,EAY1D,CAVY,eAAAmtD,CAAgB/sD,EAA2BJ,QAGrC/D,IAAVmE,GAAuBA,EAAQ,QAAgBnE,IAAX+D,GAAwBA,EAAS,IACvE3I,KAAK61D,QAAQ9sD,MAAQA,EACrB/I,KAAK61D,QAAQltD,OAASA,EAE1B,EAKF,MAAMgtD,UAA2BC,EAG/B,WAAAl2D,CACUyX,EACA4+C,EACA7rC,GAERnqB,uBAJQoX,sBACA4+C,uBACA7rC,EAGRlqB,KAAKg2D,gBAAkBh2D,KAAKmX,UAAU1W,cAAc,QACpDT,KAAKg2D,gBAAgBt1D,UAAUC,IAAI,8BACnCX,KAAKg2D,gBAAgBpyD,YAAc,IAAI67B,OAAM,IAC7Cz/B,KAAKg2D,gBAAgBn1D,aAAa,cAAe,QACjDb,KAAKg2D,gBAAgBltD,MAAMmtD,WAAa,MACxCj2D,KAAKg2D,gBAAgBltD,MAAMotD,YAAc,OACzCl2D,KAAK+1D,eAAe90D,YAAYjB,KAAKg2D,gBACvC,CAEO,OAAAh6C,GAOL,OANAhc,KAAKg2D,gBAAgBltD,MAAMg1B,WAAa99B,KAAKkqB,gBAAgB5f,WAAWwzB,WACxE99B,KAAKg2D,gBAAgBltD,MAAMG,SAAW,GAAGjJ,KAAKkqB,gBAAgB5f,WAAWrB,aAGzEjJ,KAAK81D,gBAAgBK,OAAOn2D,KAAKg2D,gBAAgBI,aAAY,GAAuCD,OAAOn2D,KAAKg2D,gBAAgBK,eAEzHr2D,KAAK61D,OACd,EAGF,MAAMH,UAAmCE,EAIvC,WAAAl2D,CACUwqB,GAERnqB,6BAFQmqB,EAIRlqB,KAAKi2B,QAAU,IAAI4b,gBAAgB,IAAK,KACxC7xC,KAAKu2B,KAAOv2B,KAAKi2B,QAAQK,WAAW,MACpC,MAAMz3B,EAAImB,KAAKu2B,KAAK0b,YAAY,KAChC,KAAM,UAAWpzC,GAAK,0BAA2BA,GAAK,2BAA4BA,GAChF,MAAM,IAAIkD,MAAM,sCAEpB,CAEO,OAAAia,GACLhc,KAAKu2B,KAAK8a,KAAO,GAAGrxC,KAAKkqB,gBAAgB5f,WAAWrB,cAAcjJ,KAAKkqB,gBAAgB5f,WAAWwzB,aAClG,MAAMw4B,EAAUt2D,KAAKu2B,KAAK0b,YAAY,KAEtC,OADAjyC,KAAK81D,gBAAgBQ,EAAQvtD,MAAOutD,EAAQC,sBAAwBD,EAAQE,wBACrEx2D,KAAK61D,OACd,whBCtHF,MAAAxqB,EAAAnsC,EAAA,MACAylC,EAAAzlC,EAAA,MACA+qB,EAAA/qB,EAAA,MACAG,EAAAH,EAAA,MAGA,MAAAguC,UAAoC7B,EAAAoD,cASlC,WAAA/uC,CAAY+2D,EAAsB/oB,EAAe3kC,GAC/ChJ,QANKC,KAAA02D,QAAkB,EAGlB12D,KAAA22D,aAAuB,GAI5B32D,KAAKiM,GAAKwqD,EAAUxqD,GACpBjM,KAAKgM,GAAKyqD,EAAUzqD,GACpBhM,KAAK22D,aAAejpB,EACpB1tC,KAAK21B,OAAS5sB,CAChB,CAEO,UAAA6tD,GAEL,cACF,CAEO,QAAA7hD,GACL,OAAO/U,KAAK21B,MACd,CAEO,QAAAgY,GACL,OAAO3tC,KAAK22D,YACd,CAEO,OAAAxmB,GAGL,OAAO,OACT,CAEO,eAAA0mB,CAAgBpsD,GACrB,MAAM,IAAI1I,MAAM,kBAClB,CAEO,aAAA+0D,GACL,MAAO,CAAC92D,KAAKiM,GAAIjM,KAAK2tC,WAAY3tC,KAAK+U,WAAY/U,KAAKmwC,UAC1D,qBAGK,IAAMr3B,EAAsBhM,EAA5B,MAOL,WAAApN,CAC0BoS,GAAA9R,KAAA8R,eAAAA,EALlB9R,KAAA+2D,kBAAwC,GACxC/2D,KAAAg3D,uBAAiC,EACjCh3D,KAAAoqB,UAAsB,IAAIH,EAAAI,QAI9B,CAEG,QAAA1M,CAASF,GACd,MAAMw5C,EAA2B,CAC/B98B,GAAIn6B,KAAKg3D,yBACTv5C,WAIF,OADAzd,KAAK+2D,kBAAkB9yD,KAAKgzD,GACrBA,EAAO98B,EAChB,CAEO,UAAAtc,CAAWH,GAChB,IAAK,IAAI5e,EAAI,EAAGA,EAAIkB,KAAK+2D,kBAAkBx1D,OAAQzC,IACjD,GAAIkB,KAAK+2D,kBAAkBj4D,GAAGq7B,KAAOzc,EAEnC,OADA1d,KAAK+2D,kBAAkBjvC,OAAOhpB,EAAG,IAC1B,EAIX,OAAO,CACT,CAEO,mBAAAktC,CAAoBpkC,GACzB,GAAsC,IAAlC5H,KAAK+2D,kBAAkBx1D,OACzB,MAAO,GAGT,MAAMgD,EAAOvE,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAI8D,GAClD,IAAKrD,GAAwB,IAAhBA,EAAKhD,OAChB,MAAO,GAGT,MAAM21D,EAA6B,GAC7BC,EAAU5yD,EAAKI,mBAAkB,GACjCyyD,EAAgB7yD,EAAKkmB,mBAM3B,IAAI4sC,EAAmB,EACnBC,EAAqB,EACrBC,EAAwB,EACxBC,EAAcjzD,EAAKkzD,MAAM,GACzBC,EAAcnzD,EAAKozD,MAAM,GAE7B,IAAK,IAAI9iD,EAAI,EAAGA,EAAIuiD,EAAeviD,IAGjC,GAFAtQ,EAAKumB,SAASjW,EAAG7U,KAAKoqB,WAEY,IAA9BpqB,KAAKoqB,UAAUrV,WAAnB,CAMA,GAAI/U,KAAKoqB,UAAUne,KAAOurD,GAAex3D,KAAKoqB,UAAUpe,KAAO0rD,EAAa,CAG1E,GAAI7iD,EAAIwiD,EAAmB,EAAG,CAC5B,MAAMtrB,EAAe/rC,KAAK43D,iBACxBT,EACAI,EACAD,EACA/yD,EACA8yD,GAEF,IAAK,IAAIv4D,EAAI,EAAGA,EAAIitC,EAAaxqC,OAAQzC,IACvCo4D,EAAOjzD,KAAK8nC,EAAajtC,GAE7B,CAGAu4D,EAAmBxiD,EACnB0iD,EAAwBD,EACxBE,EAAcx3D,KAAKoqB,UAAUne,GAC7ByrD,EAAc13D,KAAKoqB,UAAUpe,EAC/B,CAEAsrD,GAAsBt3D,KAAKoqB,UAAUujB,WAAWpsC,QAAUojC,EAAAiJ,qBAAqBrsC,MA1B/E,CA8BF,GAAI61D,EAAgBC,EAAmB,EAAG,CACxC,MAAMtrB,EAAe/rC,KAAK43D,iBACxBT,EACAI,EACAD,EACA/yD,EACA8yD,GAEF,IAAK,IAAIv4D,EAAI,EAAGA,EAAIitC,EAAaxqC,OAAQzC,IACvCo4D,EAAOjzD,KAAK8nC,EAAajtC,GAE7B,CAEA,OAAOo4D,CACT,CAUQ,gBAAAU,CAAiBrzD,EAAcszD,EAAoBC,EAAkBpzD,EAAuBm7B,GAClG,MAAMh2B,EAAOtF,EAAKy1B,UAAU69B,EAAYC,GAIxC,IAAIC,EAAsC,GAC1C,IACEA,EAAkB/3D,KAAK+2D,kBAAkB,GAAGt5C,QAAQ5T,EACtD,CAAE,MAAOnD,GACPD,QAAQC,MAAMA,EAChB,CACA,IAAK,IAAI5H,EAAI,EAAGA,EAAIkB,KAAK+2D,kBAAkBx1D,OAAQzC,IAEjD,IACE,MAAMk5D,EAAeh4D,KAAK+2D,kBAAkBj4D,GAAG2e,QAAQ5T,GACvD,IAAK,IAAIme,EAAI,EAAGA,EAAIgwC,EAAaz2D,OAAQymB,IACvClb,EAAuBmrD,aAAaF,EAAiBC,EAAahwC,GAEtE,CAAE,MAAOthB,GACPD,QAAQC,MAAMA,EAChB,CAGF,OADA1G,KAAKk4D,0BAA0BH,EAAiBrzD,EAAUm7B,GACnDk4B,CACT,CAUQ,yBAAAG,CAA0BhB,EAA4B3yD,EAAmBs7B,GAC/E,IAAIs4B,EAAoB,EACpBC,GAAsB,EACtBd,EAAqB,EACrBe,EAAenB,EAAOiB,GAG1B,IAAKE,EACH,OAGF,MAAMjB,EAAgB7yD,EAAKkmB,mBAC3B,IAAK,IAAI5V,EAAIgrB,EAAUhrB,EAAIuiD,EAAeviD,IAAK,CAC7C,MAAM9L,EAAQxE,EAAKwQ,SAASF,GACtBtT,EAASgD,EAAK+zD,UAAUzjD,GAAGtT,QAAUojC,EAAAiJ,qBAAqBrsC,OAIhE,GAAc,IAAVwH,EAAJ,CAWA,IANKqvD,GAAuBC,EAAa,IAAMf,IAC7Ce,EAAa,GAAKxjD,EAClBujD,GAAsB,GAIpBC,EAAa,IAAMf,EAAoB,CAOzC,GANAe,EAAa,GAAKxjD,EAGlBwjD,EAAenB,IAASiB,IAGnBE,EACH,MAOEA,EAAa,IAAMf,GACrBe,EAAa,GAAKxjD,EAClBujD,GAAsB,GAEtBA,GAAsB,CAE1B,CAIAd,GAAsB/1D,CAlCtB,CAmCF,CAII82D,IACFA,EAAa,GAAKjB,EAEtB,CAUQ,mBAAOa,CAAaf,EAA4BqB,GACtD,IAAIC,GAAU,EACd,IAAK,IAAI15D,EAAI,EAAGA,EAAIo4D,EAAO31D,OAAQzC,IAAK,CACtC,MAAM6oB,EAAQuvC,EAAOp4D,GACrB,GAAK05D,EAAL,CAwBE,GAAID,EAAS,IAAM5wC,EAAM,GAIvB,OADAuvC,EAAOp4D,EAAI,GAAG,GAAKy5D,EAAS,GACrBrB,EAGT,GAAIqB,EAAS,IAAM5wC,EAAM,GAKvB,OAFAuvC,EAAOp4D,EAAI,GAAG,GAAK6V,KAAKkZ,IAAI0qC,EAAS,GAAI5wC,EAAM,IAC/CuvC,EAAOpvC,OAAOhpB,EAAG,GACVo4D,EAKTA,EAAOpvC,OAAOhpB,EAAG,GACjBA,GACF,KA3CA,CACE,GAAIy5D,EAAS,IAAM5wC,EAAM,GAGvB,OADAuvC,EAAOpvC,OAAOhpB,EAAG,EAAGy5D,GACbrB,EAGT,GAAIqB,EAAS,IAAM5wC,EAAM,GAIvB,OADAA,EAAM,GAAKhT,KAAKC,IAAI2jD,EAAS,GAAI5wC,EAAM,IAChCuvC,EAGLqB,EAAS,GAAK5wC,EAAM,KAGtBA,EAAM,GAAKhT,KAAKC,IAAI2jD,EAAS,GAAI5wC,EAAM,IACvC6wC,GAAU,EAyBd,CACF,CAUA,OARIA,EAEFtB,EAAOA,EAAO31D,OAAS,GAAG,GAAKg3D,EAAS,GAGxCrB,EAAOjzD,KAAKs0D,GAGPrB,CACT,uDAzRWp+C,EAAsBhM,EAAAvD,EAAA,CAQ9BC,EAAA,EAAAnK,EAAAyqB,iBARQhR,6FCpDb,MAAA9K,EAAA9O,EAAA,MACAK,EAAAL,EAAA,MACAE,EAAAF,EAAA,MAEA,MAAAiZ,UAAwC/Y,EAAAK,WAYtC,WAAAC,CACUi5B,EACA8/B,EACQl4D,GAEhBR,QAJQC,KAAA24B,UAAAA,EACA34B,KAAAy4D,QAAAA,EACQz4D,KAAAO,aAAAA,EAZVP,KAAA04D,YAAa,EACb14D,KAAA24D,sBAAwC/zD,EAG/B5E,KAAA44D,aAAe54D,KAAK0B,UAAU,IAAIsM,EAAAsB,SACnCtP,KAAAwD,YAAcxD,KAAK44D,aAAarqD,MAC/BvO,KAAA64D,gBAAkB74D,KAAK0B,UAAU,IAAIsM,EAAAsB,SACtCtP,KAAA84D,eAAiB94D,KAAK64D,gBAAgBtqD,MASpDvO,KAAK+4D,kBAAoB/4D,KAAK0B,UAAU,IAAIs3D,EAAiBh5D,KAAKy4D,UAGlEz4D,KAAK0B,UAAU1B,KAAK84D,eAAe9a,GAAKh+C,KAAK+4D,kBAAkBE,UAAUjb,KACzEh+C,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+4D,kBAAkBv1D,YAAaxD,KAAK44D,eAE3E54D,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK24B,UAAW,QAAS,IAAM34B,KAAK04D,YAAa,IACtF14D,KAAK0B,WAAU,EAAAnC,EAAA+D,uBAAsBtD,KAAK24B,UAAW,OAAQ,IAAM34B,KAAK04D,YAAa,GACvF,CAEA,UAAWxhD,GACT,OAAOlX,KAAKy4D,OACd,CAEA,UAAWvhD,CAAOzM,GACZzK,KAAKy4D,UAAYhuD,IACnBzK,KAAKy4D,QAAUhuD,EACfzK,KAAK64D,gBAAgB5nD,KAAKjR,KAAKy4D,SAEnC,CAEA,OAAWzhC,GACT,OAAOh3B,KAAKkX,OAAOqpC,gBACrB,CAEA,aAAWxV,GAKT,YAJ8BnmC,IAA1B5E,KAAK24D,mBACP34D,KAAK24D,iBAAmB34D,KAAK04D,YAAc14D,KAAK24B,UAAU3hB,cAAckiD,WACxEC,eAAe,IAAMn5D,KAAK24D,sBAAmB/zD,IAExC5E,KAAK24D,gBACd,yBAcF,MAAMK,UAAyB55D,EAAAK,WAS7B,WAAAC,CAAoB05D,GAClBr5D,QADkBC,KAAAo5D,cAAAA,EALZp5D,KAAAq5D,sBAAwBr5D,KAAK0B,UAAU,IAAItC,EAAA0P,mBAElC9O,KAAA44D,aAAe54D,KAAK0B,UAAU,IAAIsM,EAAAsB,SACnCtP,KAAAwD,YAAcxD,KAAK44D,aAAarqD,MAM9CvO,KAAKs5D,eAAiB,IAAMt5D,KAAKu5D,0BACjCv5D,KAAKw5D,yBAA2Bx5D,KAAKo5D,cAAc7Y,iBACnDvgD,KAAKy5D,aAGLz5D,KAAK05D,2BAGL15D,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAK25D,iBACzC,CAGO,SAAAV,CAAUW,GACf55D,KAAKo5D,cAAgBQ,EACrB55D,KAAK05D,2BACL15D,KAAKu5D,yBACP,CAEQ,wBAAAG,GACN15D,KAAKq5D,sBAAsB5uD,OAAQ,EAAAlL,EAAA+D,uBAAsBtD,KAAKo5D,cAAe,SAAU,IAAMp5D,KAAKu5D,0BACpG,CAEQ,uBAAAA,GACFv5D,KAAKo5D,cAAc7Y,mBAAqBvgD,KAAKw5D,0BAC/Cx5D,KAAK44D,aAAa3nD,KAAKjR,KAAKo5D,cAAc7Y,kBAE5CvgD,KAAKy5D,YACP,CAEQ,UAAAA,GACDz5D,KAAKs5D,iBAKVt5D,KAAK65D,2BAA2BC,eAAe95D,KAAKs5D,gBAGpDt5D,KAAKw5D,yBAA2Bx5D,KAAKo5D,cAAc7Y,iBACnDvgD,KAAK65D,0BAA4B75D,KAAKo5D,cAAcW,WAAW,2BAA2B/5D,KAAKo5D,cAAc7Y,yBAC7GvgD,KAAK65D,0BAA0BG,YAAYh6D,KAAKs5D,gBAClD,CAEO,aAAAK,GACA35D,KAAK65D,2BAA8B75D,KAAKs5D,iBAG7Ct5D,KAAK65D,0BAA0BC,eAAe95D,KAAKs5D,gBACnDt5D,KAAK65D,+BAA4Bj1D,EACjC5E,KAAKs5D,oBAAiB10D,EACxB,+fCnIF,MAAAq1D,EAAA/6D,EAAA,KACAg7D,EAAAh7D,EAAA,MACAi7D,EAAAj7D,EAAA,MACAk7D,EAAAl7D,EAAA,KACAG,EAAAH,EAAA,MAGO,IAAMsR,EAAN,MAML,WAAA9Q,CACiC0vB,EACGlF,qBADHkF,uBACGlF,CAEpC,CAEQ,kBAAAmwC,GAEN,OADAr6D,KAAKs6D,kBAAoB,IAAIH,EAAAI,eACtBv6D,KAAKs6D,eACd,CAEQ,iBAAAE,GAEN,OADAx6D,KAAKy6D,iBAAmB,IAAIP,EAAAQ,cACrB16D,KAAKy6D,cACd,CAEO,eAAAx7C,CAAgB1Q,GAErB,GAAIvO,KAAKsf,kBACP,OAAOtf,KAAKq6D,qBAAqBM,sBAAsBpsD,GAAO,GAEhE,MAAMqsD,EAAa56D,KAAKovB,aAAayrC,cAAcC,MACnD,OAAO96D,KAAKqf,SACRrf,KAAKw6D,oBAAoBO,SAASxsD,EAAOqsD,EAAYrsD,EAAMkxB,OAAQ,EAAgC,EAA+B26B,EAAAz7C,OAAS3e,KAAKkqB,gBAAgB5f,WAAWsU,kBAC3K,EAAAq7C,EAAAU,uBAAsBpsD,EAAOvO,KAAKovB,aAAa/kB,gBAAgB24B,sBAAuBo3B,EAAAz7C,MAAO3e,KAAKkqB,gBAAgB5f,WAAWsU,gBACnI,CAEO,aAAAqB,CAAc1R,GAEnB,GAAIvO,KAAKsf,kBACP,OAAOtf,KAAKq6D,qBAAqBM,sBAAsBpsD,GAAO,GAEhE,MAAMqsD,EAAa56D,KAAKovB,aAAayrC,cAAcC,MACnD,OAAI96D,KAAKqf,UAAuB,EAAVu7C,EACb56D,KAAKw6D,oBAAoBO,SAASxsD,EAAOqsD,EAAU,EAAkCR,EAAAz7C,OAAS3e,KAAKkqB,gBAAgB5f,WAAWsU,sBADvI,CAIF,CAEA,YAAWS,GACT,MAAMu7C,EAAa56D,KAAKovB,aAAayrC,cAAcC,MACnD,SAAU96D,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,gBAAiBX,EAAAQ,cAAcO,kBAAkBL,GAC3G,CAEA,qBAAWt7C,GACT,SAAUtf,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcp3B,iBAAkB5jC,KAAKovB,aAAa/kB,gBAAgBu5B,eAC9G,yCApDWpzB,EAAejH,EAAA,CAOvBC,EAAA,EAAAnK,EAAAszB,cACAnpB,EAAA,EAAAnK,EAAA0tB,kBARQvc,8FCZb,MAAApR,EAAAF,EAAA,MAGA,MAAAyR,UAAyCvR,EAAAK,WAKvC,WAAAC,GACEK,QAHcC,KAAA4mB,cAAiC,GAI/C5mB,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAK4mB,cAAcrlB,OAAS,GAChE,CAEO,oBAAAsP,CAAqB0M,GAE1B,OADAvd,KAAK4mB,cAAc3iB,KAAKsZ,GACjB,CACLlE,QAAS,KAEP,MAAM6hD,EAAgBl7D,KAAK4mB,cAAcu0C,QAAQ59C,IAE1B,IAAnB29C,GACFl7D,KAAK4mB,cAAckB,OAAOozC,EAAe,IAIjD,yhBCrBF,MAAA37D,EAAAL,EAAA,MACAk8D,EAAAl8D,EAAA,MACAG,EAAAH,EAAA,MAEO,IAAMqa,EAAN,MAGL,WAAA7Z,CACqC2Y,EACFvY,yBADEuY,sBACFvY,CAEnC,CAEO,SAAA2pB,CAAUlb,EAA2CzM,EAAsB48B,EAAkBjR,EAAkBqR,GACpH,OAAO,EAAAs8B,EAAA3xC,YACL,EAAAlqB,EAAAkiB,WAAU3f,GACVyM,EACAzM,EACA48B,EACAjR,EACAztB,KAAKqY,iBAAiBqI,aACtB1gB,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,MACxC/I,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,OACxCm2B,EAEJ,CAEO,oBAAAu8B,CAAqB9sD,EAAmBzM,GAC7C,MAAM0nB,GAAS,EAAA4xC,EAAAj9B,6BAA2B,EAAA5+B,EAAAkiB,WAAU3f,GAAUyM,EAAOzM,GACrE,GAAK9B,KAAKqY,iBAAiBqI,aAK3B,OAFA8I,EAAO,GAAK7U,KAAKC,IAAID,KAAKkZ,IAAIrE,EAAO,GAAI,GAAIxpB,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOD,MAAQ,GAC/FygB,EAAO,GAAK7U,KAAKC,IAAID,KAAKkZ,IAAIrE,EAAO,GAAI,GAAIxpB,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOL,OAAS,GACzF,CACL2yD,IAAK3mD,KAAKkiB,MAAMrN,EAAO,GAAKxpB,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKK,OACpEnB,IAAK+M,KAAKkiB,MAAMrN,EAAO,GAAKxpB,KAAKF,eAAe0I,WAAWC,IAAIC,KAAKC,QACpEkM,EAAGF,KAAKkiB,MAAMrN,EAAO,IACrBrV,EAAGQ,KAAKkiB,MAAMrN,EAAO,IAEzB,+CApCWjQ,EAAkBhQ,EAAA,CAI1BC,EAAA,EAAAnK,EAAAkZ,kBACA/O,EAAA,EAAAnK,EAAAsK,iBALQ4P,uhBCJb,MAAAha,EAAAL,EAAA,MACAG,EAAAH,EAAA,MAGAE,EAAAF,EAAA,MACAI,EAAAJ,EAAA,MACAq8D,EAAAr8D,EAAA,MAcO,IAAMqb,EAAN,MAQL,WAAA7a,CACmCI,EACKwZ,EACDkiD,EACNpsC,EACEtd,EACCoY,EACE1U,EACNsB,EACQjX,GARLG,KAAAF,eAAAA,EACKE,KAAAsZ,oBAAAA,EACDtZ,KAAAw7D,mBAAAA,EACNx7D,KAAAovB,aAAAA,EACEpvB,KAAA8R,eAAAA,EACC9R,KAAAkqB,gBAAAA,EACElqB,KAAAwV,kBAAAA,EACNxV,KAAA8W,YAAAA,EACQ9W,KAAAH,oBAAAA,EAdhCG,KAAAy7D,WAAqC,KACrCz7D,KAAA07D,oBAA8B,EAC9B17D,KAAA27D,wBAAkC,CAc1C,CAEO,SAAA1/C,CAAU9W,EAA6BwY,EAA6C5X,GACzF,MAAMjE,QAAEA,EAAOsW,SAAEA,GAAajT,EAUxBy2D,EAAwC,CAC5CC,QAAS,KACTC,MAAO,KACPC,UAAW,KACXC,UAAW,MAEP3lC,EAAyB,CAAElxB,SAAQY,QAAO61D,mBAC1CK,EAAyF,CAC7FJ,QAAUlxD,GAAc3K,KAAK+lB,eAAesQ,EAAK1rB,GACjDmxD,MAAQnxD,GAAc3K,KAAKk8D,aAAa7lC,EAAK1rB,GAC7CoxD,UAAYpxD,GAAc3K,KAAKm8D,iBAAiB9lC,EAAK1rB,GACrDqxD,UAAYrxD,GAAc3K,KAAK6lB,iBAAiBwQ,EAAK1rB,IAEvD3K,KAAKo8D,gBAAkB,IAAIC,EACzBv6D,EACAsW,EACA,IAAMpY,KAAKw7D,mBAAmBngD,wBACvBrb,KAAKkqB,gBAAgB5f,WAAWgR,uBAEzCqC,EAAS3d,KAAKo8D,iBACdz+C,EAAS3d,KAAKw7D,mBAAmB3qC,iBAAiByrC,IAChDt8D,KAAKu8D,sBAAsBlmC,EAAK4lC,EAAgBK,MAElD3+C,EAAS3d,KAAKkqB,gBAAgBzS,uBAAuB,wBAAyB,KAC5EzX,KAAKw8D,oBAAoB16D,GACzB9B,KAAKo8D,iBAAiB//C,UAGxBrc,KAAKw7D,mBAAmB14B,eAAiB9iC,KAAKw7D,mBAAmB14B,eAGjEnlB,GAAS,EAAAve,EAAAqE,cAAa,KAChBm4D,EAAgBC,SAClBzjD,EAASzS,oBAAoB,UAAWi2D,EAAgBC,SAEtDD,EAAgBG,WAClB3jD,EAASzS,oBAAoB,YAAai2D,EAAgBG,cAO9Dp+C,GAAS,EAAApe,EAAA+D,uBAAsBxB,EAAS,YAAc6I,GAAmB3K,KAAK8lB,iBAAiBuQ,EAAK1rB,KACpGgT,GAAS,EAAApe,EAAA+D,uBAAsBxB,EAAS,QAAU6I,GAAmB3K,KAAKy8D,oBAAoBpmC,EAAK1rB,GAAK,CAAEg/C,SAAS,KACnHhsC,EAAS49C,EAAAzL,QAAQU,UAAUrrD,EAAOyF,gBAClC+S,GAAS,EAAApe,EAAA+D,uBAAsB6B,EAAOyF,cAAe2wD,EAAA9L,UAAiBE,MAAO,IAAM3vD,KAAKqwD,sBACxF1yC,GAAS,EAAApe,EAAA+D,uBAAsB6B,EAAOyF,cAAe2wD,EAAA9L,UAAiB1rC,OAAS5iB,GAAqBnB,KAAK08D,mBAAmBrmC,EAAKl1B,IACnI,CAEQ,UAAAw7D,CAAWtmC,EAAwB1rB,GAEzC,MAAME,EAAM7K,KAAKsZ,oBAAoB+hD,qBAAqB1wD,EAAkB0rB,EAAIlxB,OAAOyF,eACvF,IAAKC,EACH,OAAO,EAGT,IAAI+xD,EACAC,EACJ,OAASlyD,EAA8CmyD,cAAgBnyD,EAAG6G,MACxE,IAAK,YACHqrD,EAAM,QACaj4D,IAAf+F,EAAGgvC,SAELijB,EAAG,OACeh4D,IAAd+F,EAAGiL,SACLgnD,EAAMjyD,EAAGiL,OAAS,EAAIjL,EAAGiL,OAAQ,IAInCgnD,EAAmB,EAAbjyD,EAAGgvC,QAAa,EACP,EAAbhvC,EAAGgvC,QAAa,EACD,EAAbhvC,EAAGgvC,QAAa,EAAwB,EAG9C,MACF,IAAK,UACHkjB,EAAM,EACND,EAAMjyD,EAAGiL,OAAS,EAAIjL,EAAGiL,OAAQ,EACjC,MACF,IAAK,YACHinD,EAAM,EACND,EAAMjyD,EAAGiL,OAAS,EAAIjL,EAAGiL,OAAQ,EACjC,MACF,IAAK,QACH,IAAK5V,KAAKw7D,mBAAmBuB,sBAAsBpyD,GACjD,OAAO,EAET,MAAMi1C,EAAUj1C,EAAkBi1C,OAClC,GAAe,IAAXA,EACF,OAAO,EAOT,GAAc,IALA5/C,KAAKg9D,mBACjBryD,EACA3K,KAAKF,gBAAgB0I,YAAYqG,QAAQnG,MAAMC,OAC/C3I,KAAKH,qBAAqBm3B,KAG1B,OAAO,EAET6lC,EAASjd,EAAS,EAAG,EAAqB,EAC1Cgd,EAAG,EACH,MACF,QAEE,OAAO,EAKX,QAAeh4D,IAAXi4D,QAAgCj4D,IAARg4D,GAAqBA,EAAG,EAClD,OAAO,EAGT,GAAO,IAAHA,GACC58D,KAAKkqB,gBAAgB5f,WAAWgR,uBAChCtb,KAAKw7D,mBAAmBngD,uBACvB1Q,EAAGkU,OACP,OAAO,EAKT,MAAMo+C,EAAwB,IAAHL,GACtB58D,KAAKkqB,gBAAgB5f,WAAWgR,uBAChCtb,KAAKw7D,mBAAmBngD,qBAE7B,OAAOrb,KAAKk9D,mBAAmB,CAC7B5B,IAAKzwD,EAAIywD,IACT1zD,IAAKiD,EAAIjD,IACTiN,EAAGhK,EAAIgK,EACPV,EAAGtJ,EAAIsJ,EACPyB,OAAQgnD,EACRC,SACAM,KAAMxyD,EAAG4U,QACT6T,KAAK6pC,GAA6BtyD,EAAGkU,OACrClb,MAAOgH,EAAG00C,UAEd,CAEQ,cAAAt5B,CAAesQ,EAAwB1rB,GAC7C3K,KAAK28D,WAAWtmC,EAAK1rB,GAChBA,EAAGgvC,UAEFtjB,EAAIulC,gBAAgBC,SACtBxlC,EAAIlxB,OAAOiT,SAASzS,oBAAoB,UAAW0wB,EAAIulC,gBAAgBC,SAErExlC,EAAIulC,gBAAgBG,WACtB1lC,EAAIlxB,OAAOiT,SAASzS,oBAAoB,YAAa0wB,EAAIulC,gBAAgBG,WAG/E,CAEQ,YAAAG,CAAa7lC,EAAwB1rB,GAI3C,OAHA3K,KAAK28D,WAAWtmC,EAAK1rB,GACrBA,EAAG3E,iBACH2E,EAAGY,mBACI,CACT,CAEQ,gBAAA4wD,CAAiB9lC,EAAwB1rB,GAE3CA,EAAGgvC,SACL35C,KAAK28D,WAAWtmC,EAAK1rB,EAEzB,CAEQ,gBAAAkb,CAAiBwQ,EAAwB1rB,GAE1CA,EAAGgvC,SACN35C,KAAK28D,WAAWtmC,EAAK1rB,EAEzB,CAEQ,gBAAAmb,CAAiBuQ,EAAwB1rB,GAC/CA,EAAG3E,iBACHqwB,EAAItwB,QAKC/F,KAAKw7D,mBAAmBngD,uBAAwBrb,KAAKwV,kBAAkB4nD,qBAAqBzyD,KAIjG3K,KAAK28D,WAAWtmC,EAAK1rB,GAMjB0rB,EAAIulC,gBAAgBC,SACtBxlC,EAAIlxB,OAAOiT,SAAS9W,iBAAiB,UAAW+0B,EAAIulC,gBAAgBC,SAElExlC,EAAIulC,gBAAgBG,WACtB1lC,EAAIlxB,OAAOiT,SAAS9W,iBAAiB,YAAa+0B,EAAIulC,gBAAgBG,WAE1E,CAEQ,mBAAAU,CAAoBpmC,EAAwB1rB,GAElD,IAAI0rB,EAAIulC,gBAAgBE,MAAxB,CAIA,IAAK97D,KAAKw7D,mBAAmBuB,sBAAsBpyD,GACjD,OAAO,EAGT,IAAK3K,KAAK8R,eAAe3N,OAAOm8B,cAAe,CAU7C,GAAe,IADA31B,EAAGi1C,OAEhB,OAAO,EAQT,GAAc,IALA5/C,KAAKg9D,mBACjBryD,EACA3K,KAAKF,gBAAgB0I,YAAYqG,QAAQnG,MAAMC,OAC/C3I,KAAKH,qBAAqBm3B,KAK1B,OAFArsB,EAAG3E,iBACH2E,EAAGY,mBACI,EAIT,MAAMm0B,EAAW,KAAU1/B,KAAKovB,aAAa/kB,gBAAgB24B,sBAAwB,IAAM,MAAQr4B,EAAGi1C,OAAS,EAAI,IAAM,KAIzH,OAHA5/C,KAAKovB,aAAa5kB,iBAAiBk1B,GAAU,GAC7C/0B,EAAG3E,iBACH2E,EAAGY,mBACI,CACT,CArCA,CAsCF,CAEQ,iBAAA8kD,GACNrwD,KAAK27D,wBAA0B,CACjC,CAEQ,kBAAAe,CAAmBrmC,EAAwBl1B,GACjDA,EAAE6E,iBACF7E,EAAEoK,kBAGE8qB,EAAIulC,gBAAgBE,MACtB97D,KAAKq9D,0BAA0BhnC,EAAKl1B,GAKjCnB,KAAK8R,eAAe3N,OAAOm8B,cAMhCjK,EAAIlxB,OAAO+W,oBAAoB/a,EAAEuxB,cAL/B1yB,KAAKs9D,yBAAyBn8D,EAMlC,CAEQ,wBAAAm8D,CAAyBn8D,GAC/B,MAAM2T,EAAa9U,KAAKF,gBAAgB0I,WAAWC,IAAIC,KAAKC,OAC5D,IAAKmM,EACH,OAGF9U,KAAK27D,yBAA2Bx6D,EAAEuxB,aAClC,MAAMruB,EAAQsQ,KAAK4oD,MAAMv9D,KAAK27D,wBAA0B7mD,GACxD,GAAc,IAAVzQ,EACF,OAGFrE,KAAK27D,yBAA2Bt3D,EAAQyQ,EACxC,MAAM4qB,EAAW,KACZ1/B,KAAKovB,aAAa/kB,gBAAgB24B,sBAAwB,IAAM,MAChE3+B,EAAQ,EAAI,IAAM,KACvB,IAAK,IAAIvF,EAAI,EAAGA,EAAI6V,KAAK0qB,IAAIh7B,GAAQvF,IACnCkB,KAAKovB,aAAa5kB,iBAAiBk1B,GAAU,EAEjD,CAEQ,yBAAA29B,CAA0BhnC,EAAwBl1B,GACxD,MAAM2T,EAAa9U,KAAKF,gBAAgB0I,WAAWC,IAAIC,KAAKC,OAC5D,IAAKmM,EACH,OAGF9U,KAAK27D,yBAA2Bx6D,EAAEuxB,aAClC,MAAMruB,EAAQsQ,KAAK4oD,MAAMv9D,KAAK27D,wBAA0B7mD,GACxD,GAAc,IAAVzQ,EACF,OAGFrE,KAAK27D,yBAA2Bt3D,EAAQyQ,EACxC,MAAMjK,EAAM7K,KAAKsZ,oBAAoB+hD,qBAAqBl6D,EAAGk1B,EAAIlxB,OAAOyF,eACxE,GAAKC,EAIL,IAAK,IAAI/L,EAAI,EAAGA,EAAI6V,KAAK0qB,IAAIh7B,GAAQvF,IACnCkB,KAAKk9D,mBAAmB,CACtB5B,IAAKzwD,EAAIywD,IACT1zD,IAAKiD,EAAIjD,IACTiN,EAAGhK,EAAIgK,EACPV,EAAGtJ,EAAIsJ,EACPyB,OAAM,EACNinD,OAAQx4D,EAAQ,EAAG,EAAqB,EACxC84D,MAAM,EACN/pC,KAAK,EACLzvB,OAAO,GAGb,CAEO,KAAA2N,GACLtR,KAAKy7D,WAAa,KAClBz7D,KAAK07D,oBAAsB,EAC3B17D,KAAK27D,wBAA0B,CACjC,CAEQ,mBAAAa,CAAoB16D,GACtB9B,KAAKw7D,mBAAmBngD,qBACtBrb,KAAKkqB,gBAAgB5f,WAAWgR,uBAClCtb,KAAKo8D,iBAAiBoB,aACtBx9D,KAAKwV,kBAAkBgG,WAEvB1Z,EAAQpB,UAAUC,IAAG,uBACrBX,KAAKwV,kBAAkB+F,YAGzBzZ,EAAQpB,UAAUgD,OAAM,uBACxB1D,KAAKwV,kBAAkBgG,SAE3B,CAEQ,qBAAA+gD,CAAsBlmC,EAAwB4lC,EAAwFK,GAC5I,MAAMx6D,QAAEA,EAAOsW,SAAEA,GAAaie,EAAIlxB,QAC5By2D,gBAAEA,GAAoBvlC,EAExBimC,EAC+C,UAA7Ct8D,KAAKkqB,gBAAgB5f,WAAWmzD,UAClCz9D,KAAK8W,YAAYC,MAAM,2BAA4B/W,KAAK09D,eAAepB,IAGzEt8D,KAAK8W,YAAYC,MAAM,gCAEzB/W,KAAKw8D,oBAAoB16D,GACzB9B,KAAKo8D,iBAAiB//C,OAGV,EAANigD,EAKMV,EAAgBI,YAC1Bl6D,EAAQR,iBAAiB,YAAa26D,EAAeD,WACrDJ,EAAgBI,UAAYC,EAAeD,YANvCJ,EAAgBI,WAClBl6D,EAAQ6D,oBAAoB,YAAai2D,EAAgBI,WAE3DJ,EAAgBI,UAAY,MAMlB,GAANM,EAKMV,EAAgBE,QAC1Bh6D,EAAQR,iBAAiB,QAAS26D,EAAeH,MAAO,CAAEnS,SAAS,IACnEiS,EAAgBE,MAAQG,EAAeH,QANnCF,EAAgBE,OAClBh6D,EAAQ6D,oBAAoB,QAASi2D,EAAgBE,OAEvDF,EAAgBE,MAAQ,MAMd,EAANQ,EAMJV,EAAgBC,UAAYI,EAAeJ,SALvCD,EAAgBC,SAClBzjD,EAASzS,oBAAoB,UAAWi2D,EAAgBC,SAE1DD,EAAgBC,QAAU,MAKhB,EAANS,EAMJV,EAAgBG,YAAcE,EAAeF,WALzCH,EAAgBG,WAClB3jD,EAASzS,oBAAoB,YAAai2D,EAAgBG,WAE5DH,EAAgBG,UAAY,KAIhC,CAEQ,oBAAA4B,CAAqBljD,EAAgB9P,GAE3C,OAAIA,EAAGkU,QAAUlU,EAAG4U,SAAW5U,EAAG00C,SACzB5kC,EAASza,KAAKkqB,gBAAgB5f,WAAW8nB,sBAAwBpyB,KAAKkqB,gBAAgB5f,WAAW6nB,kBAEnG1X,EAASza,KAAKkqB,gBAAgB5f,WAAW6nB,iBAClD,CAMQ,kBAAA6qC,CAAmBryD,EAAgBmK,EAAqBkiB,GAE9D,GAAkB,IAAdrsB,EAAGi1C,QAAgBj1C,EAAG00C,SACxB,OAAO,EAGT,QAAmBz6C,IAAfkQ,QAAoClQ,IAARoyB,EAC9B,OAAO,EAGT,MAAM4mC,EAAyB9oD,EAAakiB,EAC5C,IAAIvc,EAASza,KAAK29D,qBAAqBhzD,EAAGi1C,OAAQj1C,GAgBlD,OAdIA,EAAGg2C,YAAckd,WAAWC,iBAC9BrjD,GAAWmjD,EAAyB,EAEXjpD,KAAK0qB,IAAI10B,EAAGi1C,QAAU,KAE7CnlC,GAAU,IAGZza,KAAK07D,qBAAuBjhD,EAC5BA,EAAS9F,KAAKkiB,MAAMliB,KAAK0qB,IAAIr/B,KAAK07D,uBAAyB17D,KAAK07D,oBAAsB,EAAI,GAAK,GAC/F17D,KAAK07D,qBAAuB,GACnB/wD,EAAGg2C,YAAckd,WAAWE,iBACrCtjD,GAAUza,KAAK8R,eAAe/Q,MAEzB0Z,CACT,CAYQ,kBAAAyiD,CAAmB/7D,GAEzB,GAAIA,EAAEm6D,IAAM,GAAKn6D,EAAEm6D,KAAOt7D,KAAK8R,eAAe7J,MACzC9G,EAAEyG,IAAM,GAAKzG,EAAEyG,KAAO5H,KAAK8R,eAAe/Q,KAC7C,OAAO,EAIT,GAAY,IAARI,EAAEyU,QAA4C,KAARzU,EAAE07D,OAC1C,OAAO,EAET,GAAY,IAAR17D,EAAEyU,QAA2C,KAARzU,EAAE07D,OACzC,OAAO,EAET,GAAY,IAAR17D,EAAEyU,SAA6C,IAARzU,EAAE07D,QAA2C,IAAR17D,EAAE07D,QAChF,OAAO,EAQT,GAJA17D,EAAEm6D,MACFn6D,EAAEyG,MAGU,KAARzG,EAAE07D,QACD78D,KAAKy7D,YACLz7D,KAAKg+D,aAAah+D,KAAKy7D,WAAYt6D,EAAGnB,KAAKw7D,mBAAmByC,iBAEjE,OAAO,EAIT,IAAKj+D,KAAKw7D,mBAAmB0C,mBAAmB/8D,GAC9C,OAAO,EAIT,MAAMg9D,EAASn+D,KAAKw7D,mBAAmB4C,iBAAiBj9D,GAUxD,OATIg9D,IACEn+D,KAAKw7D,mBAAmB6C,kBAC1Br+D,KAAKovB,aAAakvC,mBAAmBH,GAErCn+D,KAAKovB,aAAa5kB,iBAAiB2zD,GAAQ,IAI/Cn+D,KAAKy7D,WAAat6D,GACX,CACT,CAEQ,cAAAu8D,CAAepB,GACrB,MAAO,CACLiC,QAAe,EAANjC,GACTkC,MAAa,EAANlC,GACPmC,QAAe,EAANnC,GACToC,QAAe,EAANpC,GACTR,SAAgB,GAANQ,GAEd,CAEQ,YAAA0B,CAAa3d,EAAqBC,EAAqBqe,GAC7D,GAAIA,EAAQ,CACV,GAAIte,EAAGxrC,IAAMyrC,EAAGzrC,EAAG,OAAO,EAC1B,GAAIwrC,EAAGlsC,IAAMmsC,EAAGnsC,EAAG,OAAO,CAC5B,KAAO,CACL,GAAIksC,EAAGib,MAAQhb,EAAGgb,IAAK,OAAO,EAC9B,GAAIjb,EAAGz4C,MAAQ04C,EAAG14C,IAAK,OAAO,CAChC,CACA,OAAIy4C,EAAGzqC,SAAW0qC,EAAG1qC,QACjByqC,EAAGwc,SAAWvc,EAAGuc,QACjBxc,EAAG8c,OAAS7c,EAAG6c,MACf9c,EAAGjtB,MAAQktB,EAAGltB,KACditB,EAAG18C,QAAU28C,EAAG38C,KAEtB,mCAziBW4W,EAAYhR,EAAA,CASpBC,EAAA,EAAAlK,EAAAqK,gBACAH,EAAA,EAAAlK,EAAAka,qBACAhQ,EAAA,EAAAnK,EAAAuzB,oBACAppB,EAAA,EAAAnK,EAAAszB,cACAnpB,EAAA,EAAAnK,EAAAyqB,gBACAtgB,EAAA,EAAAnK,EAAA0tB,iBACAvjB,EAAA,EAAAlK,EAAA+a,mBACA7Q,EAAA,EAAAnK,EAAAu/D,aACAp1D,EAAA,EAAAlK,EAAAoK,sBAjBQ6Q,GAijBb,MAAA8hD,EAGE,WAAA38D,CACmBulB,EACA9N,EACA0nD,GAFA7+D,KAAAilB,SAAAA,EACAjlB,KAAAmX,UAAAA,EACAnX,KAAA6+D,UAAAA,EALF7+D,KAAA8+D,WAAa,IAAI1/D,EAAA0P,iBAOlC,CAEO,OAAAuK,GACLrZ,KAAK8+D,WAAWzlD,SAClB,CAEO,IAAAgD,GAGL,GAFArc,KAAK8+D,WAAWzyD,SAEXrM,KAAK6+D,YACR,OAGF,MAAME,EAAQ,IAAI3/D,EAAAy8C,gBACZmjB,EAAoBr0D,GAAyC3K,KAAKg/D,iBAAiBr0D,GACzFo0D,EAAMp+D,KAAI,EAAApB,EAAA+D,uBAAsBtD,KAAKmX,UAAW,UAAW6nD,IAC3DD,EAAMp+D,KAAI,EAAApB,EAAA+D,uBAAsBtD,KAAKmX,UAAW,QAAS6nD,IACzDD,EAAMp+D,KAAI,EAAApB,EAAA+D,uBAAsBtD,KAAKilB,SAAU,YAAa+5C,IAC5D,MAAMp9C,EAAe5hB,KAAKilB,SAASjO,eAAeC,YAC9C2K,GACFm9C,EAAMp+D,KAAI,EAAApB,EAAA+D,uBAAsBse,EAAc,OAAQ,KAChD5hB,KAAK6+D,aACP7+D,KAAKw9D,gBAIXx9D,KAAK8+D,WAAWr0D,MAAQs0D,CAC1B,CAEO,UAAAvB,GACLx9D,KAAKi/D,cAAa,EACpB,CAEO,gBAAAD,CAAiBr0D,GACjB3K,KAAK6+D,aAGV7+D,KAAKi/D,aAAat0D,EAAGoV,iBAAiB,OACxC,CAEQ,YAAAk/C,CAAaC,GACfA,EACFl/D,KAAKilB,SAASvkB,UAAUC,IAAG,uBAE3BX,KAAKilB,SAASvkB,UAAUgD,OAAM,sBAElC,yhBC3nBF,MAAAy7D,EAAAjgE,EAAA,MAGAG,EAAAH,EAAA,MACAE,EAAAF,EAAA,MACAkgE,EAAAlgE,EAAA,MACAI,EAAAJ,EAAA,MACA8O,EAAA9O,EAAA,MAYO,IAAM8Z,EAAN,cAA4B5Z,EAAAK,WA+BjC,cAAW+I,GAAkC,OAAOxI,KAAKq/D,UAAU50D,MAAOjC,UAAY,CAEtF,WAAA9I,CACUguB,EACR9iB,EACkCsf,EACJpT,EACKuB,EACJ+W,EACXkwC,EACJrgC,EACsBp/B,EACvBwvB,GAEftvB,QAXQC,KAAA0tB,UAAAA,EAE0B1tB,KAAAkqB,gBAAAA,EACJlqB,KAAA8W,YAAAA,EACK9W,KAAAqY,iBAAAA,EACJrY,KAAAovB,aAAAA,EAGOpvB,KAAAH,oBAAAA,EAvChCG,KAAAq/D,UAA0Cr/D,KAAK0B,UAAU,IAAItC,EAAA0P,mBAG7D9O,KAAAu/D,oBAAsBv/D,KAAK0B,UAAU,IAAItC,EAAA0P,mBAGzC9O,KAAAw/D,WAAqB,EACrBx/D,KAAAy/D,mBAA6B,EAC7Bz/D,KAAA0/D,yBAAmC,EACnC1/D,KAAA2/D,wBAAkC,EAClC3/D,KAAA4/D,aAAuB,EACvB5/D,KAAA6/D,cAAwB,EAExB7/D,KAAA8/D,gBAAmC,CACzCz9D,WAAOuC,EACPtC,SAAKsC,EACLiW,kBAAkB,GAGH7a,KAAA+P,oBAAsB/P,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC1CtP,KAAAoD,mBAAqBpD,KAAK+P,oBAAoBxB,MAC7CvO,KAAA+/D,0BAA4B//D,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChDtP,KAAAiZ,yBAA2BjZ,KAAK+/D,0BAA0BxxD,MACzDvO,KAAAkZ,UAAYlZ,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAmC,SAAWnC,KAAKkZ,UAAU3K,MACzBvO,KAAAggE,kBAAoBhgE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACxCtP,KAAAigE,iBAAmBjgE,KAAKggE,kBAAkBzxD,MAkBxDvO,KAAKkgE,kBAAoBlgE,KAAK0B,UAAU,IAAI09D,EAAAe,kBAAkBngE,KAAK8W,cAEnE9W,KAAKogE,iBAAmB,IAAIjB,EAAAkB,gBAAgB,CAACh+D,EAAOC,IAAQtC,KAAK4B,YAAYS,EAAOC,GAAMtC,KAAKH,qBAC/FG,KAAK0B,UAAU1B,KAAKogE,kBAEpBpgE,KAAKsgE,mBAAqB,IAAIC,EAC5BvgE,KAAKH,oBACLG,KAAKovB,aACL,IAAMpvB,KAAKwgE,gBAEbxgE,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKsgE,mBAAmBjnD,YAE1DrZ,KAAK0B,UAAU1B,KAAKH,oBAAoB2D,YAAY,IAAMxD,KAAKgoC,iCAE/DhoC,KAAK0B,UAAUu9B,EAAch9B,SAAS,IAAMjC,KAAKwgE,iBACjDxgE,KAAK0B,UAAUu9B,EAAczrB,QAAQie,iBAAiB,IAAMzxB,KAAKq/D,UAAU50D,OAAO4B,UAClFrM,KAAK0B,UAAU1B,KAAKkqB,gBAAgB0b,eAAe,IAAM5lC,KAAK6lC,0BAC9D7lC,KAAK0B,UAAU1B,KAAKqY,iBAAiBm9C,iBAAiB,IAAMx1D,KAAKioC,0BAKjEjoC,KAAK0B,UAAU49D,EAAkBjsC,uBAAuB,IAAMrzB,KAAKwgE,iBACnExgE,KAAK0B,UAAU49D,EAAkBhsC,oBAAoB,IAAMtzB,KAAKwgE,iBAGhExgE,KAAK0B,UAAU1B,KAAKkqB,gBAAgByG,uBAAuB,CACzD,6BACA,gBACA,aACA,aACA,WACA,aACA,iBACA,uBACA,4BACC,KACD3wB,KAAKqM,QACLrM,KAAK8Z,aAAamlB,EAAch3B,KAAMg3B,EAAcl+B,MACpDf,KAAKwgE,kBAIPxgE,KAAK0B,UAAU1B,KAAKkqB,gBAAgByG,uBAAuB,CACzD,cACA,eACC,IAAM3wB,KAAKsc,YAAY2iB,EAAc96B,OAAOgQ,EAAG8qB,EAAc96B,OAAOgQ,OAAGvP,GAAW,KAErF5E,KAAK0B,UAAU2tB,EAAa1W,eAAe,IAAM3Y,KAAKwgE,iBAEtDxgE,KAAKygE,8BAA8BzgE,KAAKH,oBAAoBqX,OAAQtM,GACpE5K,KAAK0B,UAAU1B,KAAKH,oBAAoBi5D,eAAgB9a,GAAMh+C,KAAKygE,8BAA8BziB,EAAGpzC,IACtG,CAEQ,6BAAA61D,CAA8BziB,EAA+BpzC,GAGnE,GAAI,yBAA0BozC,EAAG,CAC/B,MAAM0iB,EAAW,IAAI1iB,EAAE2iB,qBAAqBx/D,GAAKnB,KAAK4gE,0BAA0Bz/D,EAAEA,EAAEI,OAAS,IAAK,CAAEs/D,UAAW,IAC/G7gE,KAAKu/D,oBAAoB90D,OAAQ,EAAArL,EAAAqE,cAAa,KAC5CzD,KAAK8gE,uBAAuBC,aAC5B/gE,KAAK8gE,2BAAwBl8D,IAE/B5E,KAAK8gE,sBAAwBJ,EAC7BA,EAASM,QAAQp2D,EACnB,CACF,CAEQ,yBAAAg2D,CAA0BK,GAChCjhE,KAAKw/D,eAAqC56D,IAAzBq8D,EAAMC,eAA4D,IAA5BD,EAAME,mBAA4BF,EAAMC,eAC/FlhE,KAAKq/D,UAAU50D,OAAO49B,kCAAkCroC,KAAKw/D,WAGxDx/D,KAAKw/D,WAAcx/D,KAAKqY,iBAAiBqI,cAC5C1gB,KAAKqY,iBAAiB2D,WAGnBhc,KAAKw/D,WAAax/D,KAAKy/D,oBAC1Bz/D,KAAKkgE,kBAAkBkB,QACvBphE,KAAKsc,YAAY,EAAGtc,KAAK0tB,UAAY,GACrC1tB,KAAKy/D,mBAAoB,EAE7B,CAEO,WAAAnjD,CAAYja,EAAeC,EAAa+Z,GAAgB,EAAOglD,GAAwB,GAC5F,GAAIrhE,KAAKw/D,UAEP,YADAx/D,KAAKy/D,mBAAoB,GAI3B,GAAIz/D,KAAKovB,aAAa/kB,gBAAgBioB,mBAEpC,YADAtyB,KAAKsgE,mBAAmBgB,WAAWj/D,EAAOC,GAI5C,MAAMi/D,EAAWvhE,KAAKsgE,mBAAmBc,QACrCG,IACFl/D,EAAQsS,KAAKC,IAAIvS,EAAOk/D,EAASl/D,OACjCC,EAAMqS,KAAKkZ,IAAIvrB,EAAKi/D,EAASj/D,MAG1B++D,IACHrhE,KAAK0/D,yBAA0B,GAG7BrjD,EACFrc,KAAK4B,YAAYS,EAAOC,GAExBtC,KAAKogE,iBAAiBl8D,QAAQ7B,EAAOC,EAAKtC,KAAK0tB,UAEnD,CAEQ,WAAA9rB,CAAYS,EAAeC,GAC5BtC,KAAKq/D,UAAU50D,QAMhBzK,KAAKovB,aAAa/kB,gBAAgBioB,mBACpCtyB,KAAKsgE,mBAAmBgB,WAAWj/D,EAAOC,IAO5CD,EAAQsS,KAAKC,IAAIvS,EAAOrC,KAAK0tB,UAAY,GACzCprB,EAAMqS,KAAKC,IAAItS,EAAKtC,KAAK0tB,UAAY,GAGrC1tB,KAAKq/D,UAAU50D,MAAM09B,WAAW9lC,EAAOC,GAGnCtC,KAAK2/D,yBACP3/D,KAAKq/D,UAAU50D,MAAMmQ,uBAAuB5a,KAAK8/D,gBAAgBz9D,MAAOrC,KAAK8/D,gBAAgBx9D,IAAKtC,KAAK8/D,gBAAgBjlD,kBACvH7a,KAAK2/D,wBAAyB,GAI3B3/D,KAAK0/D,yBACR1/D,KAAK+/D,0BAA0B9uD,KAAK,CAAE5O,QAAOC,QAE/CtC,KAAKkZ,UAAUjI,KAAK,CAAE5O,QAAOC,QAC7BtC,KAAK0/D,yBAA0B,GACjC,CAEO,MAAAvmD,CAAOlR,EAAclH,GAC1Bf,KAAK0tB,UAAY3sB,EACjBf,KAAKwhE,qBACP,CAEQ,qBAAA37B,GACD7lC,KAAKq/D,UAAU50D,QAGpBzK,KAAKsc,YAAY,EAAGtc,KAAK0tB,UAAY,GACrC1tB,KAAKwhE,sBACP,CAEQ,mBAAAA,GACDxhE,KAAKq/D,UAAU50D,QAIhBzK,KAAKq/D,UAAU50D,MAAMjC,WAAWC,IAAIO,OAAOD,QAAU/I,KAAK4/D,cAAgB5/D,KAAKq/D,UAAU50D,MAAMjC,WAAWC,IAAIO,OAAOL,SAAW3I,KAAK6/D,eAGzI7/D,KAAK+P,oBAAoBkB,KAAKjR,KAAKq/D,UAAU50D,MAAMjC,YACrD,CAEO,WAAAkR,GACL,QAAS1Z,KAAKq/D,UAAU50D,KAC1B,CAEO,WAAAkP,CAAY8nD,GACjBzhE,KAAKq/D,UAAU50D,MAAQg3D,EAEnBzhE,KAAKq/D,UAAU50D,QACjBzK,KAAKq/D,UAAU50D,MAAMkQ,gBAAgBxZ,GAAKnB,KAAKsc,YAAYnb,EAAEkB,MAAOlB,EAAEmB,IAAKnB,EAAEkb,MAAM,IAGnFrc,KAAK2/D,wBAAyB,EAC9B3/D,KAAKwgE,eAET,CAEO,kBAAAnzC,CAAmB/C,GACxB,OAAOtqB,KAAKogE,iBAAiB/yC,mBAAmB/C,EAClD,CAEQ,YAAAk2C,GACFxgE,KAAKw/D,UACPx/D,KAAKy/D,mBAAoB,EAEzBz/D,KAAKsc,YAAY,EAAGtc,KAAK0tB,UAAY,EAEzC,CAEO,iBAAA5M,GACA9gB,KAAKq/D,UAAU50D,QAGpBzK,KAAKq/D,UAAU50D,MAAMqW,sBACrB9gB,KAAKwgE,eACP,CAEO,4BAAAx4B,GAGLhoC,KAAKqY,iBAAiB2D,UAEjBhc,KAAKq/D,UAAU50D,QAGpBzK,KAAKq/D,UAAU50D,MAAMu9B,+BACrBhoC,KAAKsc,YAAY,EAAGtc,KAAK0tB,UAAY,GACvC,CAEO,YAAA5T,CAAa7R,EAAclH,GAC3Bf,KAAKq/D,UAAU50D,QAGhBzK,KAAKw/D,UACPx/D,KAAKkgE,kBAAkBp7D,IAAI,IAAM9E,KAAKq/D,UAAU50D,OAAOqP,aAAa7R,EAAMlH,IAE1Ef,KAAKq/D,UAAU50D,MAAMqP,aAAa7R,EAAMlH,GAE1Cf,KAAKwgE,eACP,CAGO,qBAAAv4B,GACLjoC,KAAKq/D,UAAU50D,OAAOw9B,uBACxB,CAEO,UAAAluB,GACL/Z,KAAKq/D,UAAU50D,OAAOsP,YACxB,CAEO,WAAAC,GACLha,KAAKq/D,UAAU50D,OAAOuP,aACxB,CAEO,sBAAAY,CAAuBvY,EAAqCC,EAAmCuY,GACpG7a,KAAK8/D,gBAAgBz9D,MAAQA,EAC7BrC,KAAK8/D,gBAAgBx9D,IAAMA,EAC3BtC,KAAK8/D,gBAAgBjlD,iBAAmBA,EACxC7a,KAAKq/D,UAAU50D,OAAOmQ,uBAAuBvY,EAAOC,EAAKuY,EAC3D,CAEO,gBAAAhB,GACL7Z,KAAKq/D,UAAU50D,OAAOoP,kBACxB,CAEO,KAAAxN,GACLrM,KAAKq/D,UAAU50D,OAAO4B,OACxB,qCAhTW2M,EAAazP,EAAA,CAoCrBC,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,EAAAlK,EAAAs/D,aACAp1D,EAAA,EAAAnK,EAAAkZ,kBACA/O,EAAA,EAAAlK,EAAAqzB,cACAnpB,EAAA,EAAAlK,EAAAgR,oBACA9G,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAnK,EAAAqK,qBACAF,EAAA,EAAAnK,EAAAoZ,gBA3CQO,GAwTb,MAAMunD,EAMJ,WAAA7gE,CACmBG,EACAuvB,EACAsyC,GAFA1hE,KAAAH,oBAAAA,EACAG,KAAAovB,aAAAA,EACApvB,KAAA0hE,WAAAA,EARX1hE,KAAA2hE,OAAiB,EACjB3hE,KAAA4hE,KAAe,EAEf5hE,KAAA6hE,cAAwB,CAM7B,CAEI,UAAAP,CAAWj/D,EAAeC,GAC1BtC,KAAK6hE,cAKR7hE,KAAK2hE,OAAShtD,KAAKC,IAAI5U,KAAK2hE,OAAQt/D,GACpCrC,KAAK4hE,KAAOjtD,KAAKkZ,IAAI7tB,KAAK4hE,KAAMt/D,KALhCtC,KAAK2hE,OAASt/D,EACdrC,KAAK4hE,KAAOt/D,EACZtC,KAAK6hE,cAAe,GAMtB7hE,KAAK8hE,WAAa9hE,KAAKH,oBAAoBqX,OAAOuX,WAAW,KAC3DzuB,KAAK8hE,cAAWl9D,EAChB5E,KAAKovB,aAAa/kB,gBAAgBioB,oBAAqB,EACvDtyB,KAAK0hE,cACN,IACH,CAEO,KAAAN,GAML,QALsBx8D,IAAlB5E,KAAK8hE,WACP9hE,KAAKH,oBAAoBqX,OAAOiX,aAAanuB,KAAK8hE,UAClD9hE,KAAK8hE,cAAWl9D,IAGb5E,KAAK6hE,aACR,OAGF,MAAM7iD,EAAS,CAAE3c,MAAOrC,KAAK2hE,OAAQr/D,IAAKtC,KAAK4hE,MAE/C,OADA5hE,KAAK6hE,cAAe,EACb7iD,CACT,CAEO,OAAA3F,QACiBzU,IAAlB5E,KAAK8hE,WACP9hE,KAAKH,oBAAoBqX,OAAOiX,aAAanuB,KAAK8hE,UAClD9hE,KAAK8hE,cAAWl9D,EAEpB,wxCC3XF,MAAAw2D,EAAAl8D,EAAA,MACA6iE,EAAA7iE,EAAA,MACA8iE,EAAA9iE,EAAA,MAEAG,EAAAH,EAAA,MACAE,EAAAF,EAAA,MACYuO,EAAOxO,EAAAC,EAAA,MAGnB+iE,EAAA/iE,EAAA,MACA+qB,EAAA/qB,EAAA,MACAI,EAAAJ,EAAA,MACA8O,EAAA9O,EAAA,MAuBMgjE,EAA0B9hD,OAAOC,aAAa,KAC9C8hD,EAA+B,IAAIC,OAAOF,EAAyB,KA4BlE,IAAM9nD,EAAN,cAA+Bhb,EAAAK,WAmDpC,WAAAC,CACmBulB,EACA4N,EACAzkB,EACgB0D,EACFsd,EACO9V,EACJ4Q,EACGsxC,EACJ17D,EACKD,GAEtCE,QAXiBC,KAAAilB,SAAAA,EACAjlB,KAAA6yB,eAAAA,EACA7yB,KAAAoO,WAAAA,EACgBpO,KAAA8R,eAAAA,EACF9R,KAAAovB,aAAAA,EACOpvB,KAAAsZ,oBAAAA,EACJtZ,KAAAkqB,gBAAAA,EACGlqB,KAAAw7D,mBAAAA,EACJx7D,KAAAF,eAAAA,EACKE,KAAAH,oBAAAA,EApDhCG,KAAAqiE,kBAA4B,EAqB5BriE,KAAAsiE,UAAW,EAIFtiE,KAAAuiE,cAAgBviE,KAAK0B,UAAU,IAAItC,EAAA0P,mBAC5C9O,KAAAoqB,UAAsB,IAAIH,EAAAI,SAE1BrqB,KAAAwiE,oBAA8B,EAC9BxiE,KAAAyiE,kBAA4B,EAC5BziE,KAAA0iE,wBAAmD99D,EACnD5E,KAAA2iE,sBAAiD/9D,EAExC5E,KAAA4iE,uBAAyB5iE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC7CtP,KAAA8a,sBAAwB9a,KAAK4iE,uBAAuBr0D,MACnDvO,KAAA6iE,iBAAmB7iE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACvCtP,KAAA2a,gBAAkB3a,KAAK6iE,iBAAiBt0D,MACvCvO,KAAAyP,mBAAqBzP,KAAK0B,UAAU,IAAIsM,EAAAsB,SACzCtP,KAAA0P,kBAAoB1P,KAAKyP,mBAAmBlB,MAC3CvO,KAAAsvB,sBAAwBtvB,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC5CtP,KAAAma,qBAAuBna,KAAKsvB,sBAAsB/gB,MAiBhEvO,KAAK8iE,mBAAqBv0D,GAASvO,KAAK6lB,iBAAiBtX,GACzDvO,KAAK+iE,iBAAmBx0D,GAASvO,KAAK+lB,eAAexX,GACrDvO,KAAKovB,aAAa4zC,YAAY,KACxBhjE,KAAKsV,cACPtV,KAAKuG,mBAGTvG,KAAKuiE,cAAc93D,MAAQzK,KAAK8R,eAAe3N,OAAOE,MAAM4+D,OAAOxoD,GAAUza,KAAKkjE,YAAYzoD,IAC9Fza,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiBtwB,GAAKnB,KAAKmjE,sBAAsBhiE,KAE5FnB,KAAKwb,SAELxb,KAAKojE,OAAS,IAAIpB,EAAAqB,eAAerjE,KAAK8R,gBACtC9R,KAAKsjE,qBAAoB,EAEzBtjE,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKujE,+BAKPvjE,KAAK0B,UAAU1B,KAAK8R,eAAe7P,SAASd,IACtCA,EAAEqiE,aACJxjE,KAAKuG,mBAGX,CAEO,KAAA+K,GACLtR,KAAKuG,gBACP,CAMO,OAAAgV,GACLvb,KAAKuG,iBACLvG,KAAKsiE,UAAW,CAClB,CAKO,MAAA9mD,GACLxb,KAAKsiE,UAAW,CAClB,CAEA,kBAAWhkD,GAAiD,OAAOte,KAAKojE,OAAOlO,mBAAqB,CACpG,gBAAW32C,GAA+C,OAAOve,KAAKojE,OAAOhO,iBAAmB,CAKhG,gBAAW9/C,GACT,MAAMjT,EAAQrC,KAAKojE,OAAOlO,oBACpB5yD,EAAMtC,KAAKojE,OAAOhO,kBACxB,SAAK/yD,IAAUC,GAGRD,EAAM,KAAOC,EAAI,IAAMD,EAAM,KAAOC,EAAI,GACjD,CAKA,iBAAWgJ,GACT,MAAMjJ,EAAQrC,KAAKojE,OAAOlO,oBACpB5yD,EAAMtC,KAAKojE,OAAOhO,kBACxB,IAAK/yD,IAAUC,EACb,MAAO,GAGT,MAAM6B,EAASnE,KAAK8R,eAAe3N,OAC7B6a,EAAmB,GAEzB,GAA6B,IAAzBhf,KAAKsjE,qBAA+C,CAEtD,GAAIjhE,EAAM,KAAOC,EAAI,GACnB,MAAO,GAKT,MAAMu9B,EAAWx9B,EAAM,GAAKC,EAAI,GAAKD,EAAM,GAAKC,EAAI,GAC9Cw9B,EAASz9B,EAAM,GAAKC,EAAI,GAAKA,EAAI,GAAKD,EAAM,GAClD,IAAK,IAAIvD,EAAIuD,EAAM,GAAIvD,GAAKwD,EAAI,GAAIxD,IAAK,CACvC,MAAM2kE,EAAWt/D,EAAO87B,4BAA4BnhC,GAAG,EAAM+gC,EAAUC,GACvE9gB,EAAO/a,KAAKw/D,EACd,CACF,KAAO,CAEL,MAAMC,EAAiBrhE,EAAM,KAAOC,EAAI,GAAKA,EAAI,QAAKsC,EACtDoa,EAAO/a,KAAKE,EAAO87B,4BAA4B59B,EAAM,IAAI,EAAMA,EAAM,GAAIqhE,IAGzE,IAAK,IAAI5kE,EAAIuD,EAAM,GAAK,EAAGvD,GAAKwD,EAAI,GAAK,EAAGxD,IAAK,CAC/C,MAAM2V,EAAatQ,EAAOE,MAAMP,IAAIhF,GAC9B2kE,EAAWt/D,EAAO87B,4BAA4BnhC,GAAG,GACnD2V,GAAYyX,UACdlN,EAAOA,EAAOzd,OAAS,IAAMkiE,EAE7BzkD,EAAO/a,KAAKw/D,EAEhB,CAGA,GAAIphE,EAAM,KAAOC,EAAI,GAAI,CACvB,MAAMmS,EAAatQ,EAAOE,MAAMP,IAAIxB,EAAI,IAClCmhE,EAAWt/D,EAAO87B,4BAA4B39B,EAAI,IAAI,EAAM,EAAGA,EAAI,IACrEmS,GAAcA,EAAYyX,UAC5BlN,EAAOA,EAAOzd,OAAS,IAAMkiE,EAE7BzkD,EAAO/a,KAAKw/D,EAEhB,CACF,CAQA,OAJwBzkD,EAAOmI,IAAI5iB,GAC1BA,EAAKuF,QAAQq4D,EAA8B,MACjD3wC,KAAK/jB,EAAQqS,UAAY,OAAS,KAGvC,CAKO,cAAAvZ,GACLvG,KAAKojE,OAAO78D,iBACZvG,KAAKujE,4BACLvjE,KAAKkE,UACLlE,KAAKyP,mBAAmBwB,MAC1B,CAOO,OAAA/M,CAAQy/D,GAER3jE,KAAK4jE,yBACR5jE,KAAK4jE,uBAAyB5jE,KAAKH,oBAAoBqX,OAAOmL,sBAAsB,IAAMriB,KAAK6jE,aAK7Fp2D,EAAQsI,SAAW4tD,GACC3jE,KAAKsL,cACT/J,QAChBvB,KAAK4iE,uBAAuB3xD,KAAKjR,KAAKsL,cAG5C,CAMQ,QAAAu4D,GACN7jE,KAAK4jE,4BAAyBh/D,EAC9B5E,KAAK6iE,iBAAiB5xD,KAAK,CACzB5O,MAAOrC,KAAKojE,OAAOlO,oBACnB5yD,IAAKtC,KAAKojE,OAAOhO,kBACjBv6C,iBAA2C,IAAzB7a,KAAKsjE,sBAE3B,CAMQ,mBAAAQ,CAAoBv1D,GAC1B,MAAMib,EAASxpB,KAAK+jE,sBAAsBx1D,GACpClM,EAAQrC,KAAKojE,OAAOlO,oBACpB5yD,EAAMtC,KAAKojE,OAAOhO,kBAExB,SAAK/yD,GAAUC,GAAQknB,IAIhBxpB,KAAKgkE,sBAAsBx6C,EAAQnnB,EAAOC,EACnD,CAEO,iBAAA2hE,CAAkBpvD,EAAWV,GAClC,MAAM9R,EAAQrC,KAAKojE,OAAOlO,oBACpB5yD,EAAMtC,KAAKojE,OAAOhO,kBACxB,SAAK/yD,IAAUC,IAGRtC,KAAKgkE,sBAAsB,CAACnvD,EAAGV,GAAI9R,EAAOC,EACnD,CAEU,qBAAA0hE,CAAsBx6C,EAA0BnnB,EAAyBC,GACjF,OAAQknB,EAAO,GAAKnnB,EAAM,IAAMmnB,EAAO,GAAKlnB,EAAI,IAC3CD,EAAM,KAAOC,EAAI,IAAMknB,EAAO,KAAOnnB,EAAM,IAAMmnB,EAAO,IAAMnnB,EAAM,IAAMmnB,EAAO,GAAKlnB,EAAI,IAC1FD,EAAM,GAAKC,EAAI,IAAMknB,EAAO,KAAOlnB,EAAI,IAAMknB,EAAO,GAAKlnB,EAAI,IAC7DD,EAAM,GAAKC,EAAI,IAAMknB,EAAO,KAAOnnB,EAAM,IAAMmnB,EAAO,IAAMnnB,EAAM,EACzE,CAMQ,mBAAA6hE,CAAoB31D,EAAmB41D,GAE7C,MAAMx8C,EAAQ3nB,KAAKoO,WAAW2W,aAAauB,MAAMqB,MACjD,GAAIA,EAIF,OAHA3nB,KAAKojE,OAAO9kD,eAAiB,CAACqJ,EAAMtlB,MAAMwS,EAAI,EAAG8S,EAAMtlB,MAAM8R,EAAI,GACjEnU,KAAKojE,OAAOnO,sBAAuB,EAAAgN,EAAAmC,gBAAez8C,EAAO3nB,KAAK8R,eAAe7J,MAC7EjI,KAAKojE,OAAO7kD,kBAAe3Z,GACpB,EAGT,MAAM4kB,EAASxpB,KAAK+jE,sBAAsBx1D,GAC1C,QAAIib,IACFxpB,KAAKqkE,cAAc76C,EAAQ26C,GAC3BnkE,KAAKojE,OAAO7kD,kBAAe3Z,GACpB,EAGX,CAKO,SAAA4Z,GACLxe,KAAKojE,OAAOpO,mBAAoB,EAChCh1D,KAAKkE,UACLlE,KAAKyP,mBAAmBwB,MAC1B,CAEO,WAAAwN,CAAYpc,EAAeC,GAChCtC,KAAKojE,OAAO78D,iBACZlE,EAAQsS,KAAKkZ,IAAIxrB,EAAO,GACxBC,EAAMqS,KAAKC,IAAItS,EAAKtC,KAAK8R,eAAe3N,OAAOE,MAAM9C,OAAS,GAC9DvB,KAAKojE,OAAO9kD,eAAiB,CAAC,EAAGjc,GACjCrC,KAAKojE,OAAO7kD,aAAe,CAACve,KAAK8R,eAAe7J,KAAM3F,GACtDtC,KAAKkE,UACLlE,KAAKyP,mBAAmBwB,MAC1B,CAMQ,WAAAiyD,CAAYzoD,GACGza,KAAKojE,OAAO9N,WAAW76C,IAE1Cza,KAAKkE,SAET,CAMQ,qBAAA6/D,CAAsBx1D,GAC5B,MAAMib,EAASxpB,KAAKsZ,oBAAoBmQ,UAAUlb,EAAOvO,KAAK6yB,eAAgB7yB,KAAK8R,eAAe7J,KAAMjI,KAAK8R,eAAe/Q,MAAM,GAClI,GAAKyoB,EAUL,OALAA,EAAO,KACPA,EAAO,KAGPA,EAAO,IAAMxpB,KAAK8R,eAAe3N,OAAOK,MACjCglB,CACT,CAOQ,0BAAA86C,CAA2B/1D,GACjC,IAAI1H,GAAS,EAAAu0D,EAAAj9B,4BAA2Bn+B,KAAKH,oBAAoBqX,OAAQ3I,EAAOvO,KAAK6yB,gBAAgB,GACrG,MAAM0xC,EAAiBvkE,KAAKF,eAAe0I,WAAWC,IAAIO,OAAOL,OACjE,OAAI9B,GAAU,GAAKA,GAAU09D,EACpB,GAEL19D,EAAS09D,IACX19D,GAAU09D,GAGZ19D,EAAS8N,KAAKC,IAAID,KAAKkZ,IAAIhnB,GAAQ,IAAqC,IACxEA,GAAM,GACEA,EAAS8N,KAAK0qB,IAAIx4B,GAAW8N,KAAK6d,MAAe,GAAT3rB,GAClD,CAOO,oBAAAu2D,CAAqB7uD,GAC1B,OAAIvO,KAAKkqB,gBAAgB5f,WAAWgR,uBAAyBtb,KAAKw7D,mBAAmBngD,sBAC3E9M,EAAMsQ,OAGZpR,EAAQkR,MACHpQ,EAAMsQ,QAAU7e,KAAKkqB,gBAAgB5f,WAAWk6D,8BAGlDj2D,EAAM8wC,QACf,CAMO,eAAAlkC,CAAgB5M,GAIrB,GAHAvO,KAAKwiE,oBAAsBj0D,EAAM0sB,YAGZ,IAAjB1sB,EAAMqH,QAAgB5V,KAAKsV,cAKV,IAAjB/G,EAAMqH,QAIN5V,KAAKkqB,gBAAgB5f,WAAWgR,uBAAyBtb,KAAKw7D,mBAAmBngD,sBAAwB9M,EAAMsQ,QAAnH,CAKA,IAAK7e,KAAKsiE,SAAU,CAClB,IAAKtiE,KAAKo9D,qBAAqB7uD,GAC7B,OAIFA,EAAMhD,iBACR,CAGAgD,EAAMvI,iBAGNhG,KAAKqiE,kBAAoB,EAErBriE,KAAKsiE,UAAY/zD,EAAM8wC,SACzBr/C,KAAKykE,wBAAwBl2D,GAER,IAAjBA,EAAM2rB,OACRl6B,KAAK0kE,mBAAmBn2D,GACE,IAAjBA,EAAM2rB,OACfl6B,KAAK2kE,mBAAmBp2D,GACE,IAAjBA,EAAM2rB,QACfl6B,KAAK4kE,mBAAmBr2D,GAI5BvO,KAAK6kE,yBACL7kE,KAAKkE,SAAQ,EA/Bb,CAgCF,CAKQ,sBAAA2gE,GAEF7kE,KAAK6yB,eAAe7b,gBACtBhX,KAAK6yB,eAAe7b,cAAc1V,iBAAiB,YAAatB,KAAK8iE,oBACrE9iE,KAAK6yB,eAAe7b,cAAc1V,iBAAiB,UAAWtB,KAAK+iE,mBAErE/iE,KAAK8kE,yBAA2B9kE,KAAKH,oBAAoBqX,OAAOy8B,YAAY,IAAM3zC,KAAK+kE,cAAa,GACtG,CAKQ,yBAAAxB,GACFvjE,KAAK6yB,eAAe7b,gBACtBhX,KAAK6yB,eAAe7b,cAAcrR,oBAAoB,YAAa3F,KAAK8iE,oBACxE9iE,KAAK6yB,eAAe7b,cAAcrR,oBAAoB,UAAW3F,KAAK+iE,mBAExE/iE,KAAKH,oBAAoBqX,OAAO08B,cAAc5zC,KAAK8kE,0BACnD9kE,KAAK8kE,8BAA2BlgE,CAClC,CAOQ,uBAAA6/D,CAAwBl2D,GAC1BvO,KAAKojE,OAAO9kD,iBACdte,KAAKojE,OAAO7kD,aAAeve,KAAK+jE,sBAAsBx1D,GAE1D,CAOQ,kBAAAm2D,CAAmBn2D,GAEzB,MAAMy2D,EAAehlE,KAAKsV,aAQ1B,GANAtV,KAAKojE,OAAOnO,qBAAuB,EACnCj1D,KAAKojE,OAAOpO,mBAAoB,EAChCh1D,KAAKsjE,qBAAuBtjE,KAAKuc,mBAAmBhO,GAAQ,EAAuB,EAGnFvO,KAAKojE,OAAO9kD,eAAiBte,KAAK+jE,sBAAsBx1D,IACnDvO,KAAKojE,OAAO9kD,eACf,OAEFte,KAAKojE,OAAO7kD,kBAAe3Z,EAGvBogE,GACFhlE,KAAKilE,uBAAuBjlE,KAAKojE,OAAOlO,oBAAqBl1D,KAAKojE,OAAOhO,mBAAmB,GAI9F,MAAM7wD,EAAOvE,KAAK8R,eAAe3N,OAAOE,MAAMP,IAAI9D,KAAKojE,OAAO9kD,eAAe,IACxE/Z,GAKDA,EAAKhD,SAAWvB,KAAKojE,OAAO9kD,eAAe,IAMM,IAAjD/Z,EAAK2gE,SAASllE,KAAKojE,OAAO9kD,eAAe,KAC3Cte,KAAKojE,OAAO9kD,eAAe,IAE/B,CAMQ,kBAAAqmD,CAAmBp2D,GACrBvO,KAAKkkE,oBAAoB31D,GAAO,KAClCvO,KAAKsjE,qBAAoB,EAE7B,CAOQ,kBAAAsB,CAAmBr2D,GACzB,MAAMib,EAASxpB,KAAK+jE,sBAAsBx1D,GACtCib,IACFxpB,KAAKsjE,qBAAoB,EACzBtjE,KAAKmlE,cAAc37C,EAAO,IAE9B,CAMO,kBAAAjN,CAAmBhO,GACxB,QAAIvO,KAAKkqB,gBAAgB5f,WAAWgR,wBAAyBtb,KAAKw7D,mBAAmBngD,uBAG9E9M,EAAMsQ,UAAYpR,EAAQkR,OAAS3e,KAAKkqB,gBAAgB5f,WAAWk6D,8BAC5E,CAOQ,gBAAA3+C,CAAiBtX,GAQvB,GAJAA,EAAMtI,4BAIDjG,KAAKojE,OAAO9kD,eACf,OAKF,MAAM8mD,EAAuBplE,KAAKojE,OAAO7kD,aAAe,CAACve,KAAKojE,OAAO7kD,aAAa,GAAIve,KAAKojE,OAAO7kD,aAAa,IAAM,KAIrH,GADAve,KAAKojE,OAAO7kD,aAAeve,KAAK+jE,sBAAsBx1D,IACjDvO,KAAKojE,OAAO7kD,aAEf,YADAve,KAAKkE,SAAQ,GAKc,IAAzBlE,KAAKsjE,qBACHtjE,KAAKojE,OAAO7kD,aAAa,GAAKve,KAAKojE,OAAO9kD,eAAe,GAC3Dte,KAAKojE,OAAO7kD,aAAa,GAAK,EAE9Bve,KAAKojE,OAAO7kD,aAAa,GAAKve,KAAK8R,eAAe7J,KAElB,IAAzBjI,KAAKsjE,sBACdtjE,KAAKqlE,gBAAgBrlE,KAAKojE,OAAO7kD,cAInCve,KAAKqiE,kBAAoBriE,KAAKskE,2BAA2B/1D,GAK5B,IAAzBvO,KAAKsjE,uBACHtjE,KAAKqiE,kBAAoB,EAC3BriE,KAAKojE,OAAO7kD,aAAa,GAAKve,KAAK8R,eAAe7J,KACzCjI,KAAKqiE,kBAAoB,IAClCriE,KAAKojE,OAAO7kD,aAAa,GAAK,IAOlC,MAAMpa,EAASnE,KAAK8R,eAAe3N,OACnC,GAAInE,KAAKojE,OAAO7kD,aAAa,GAAKpa,EAAOE,MAAM9C,OAAQ,CACrD,MAAMgD,EAAOJ,EAAOE,MAAMP,IAAI9D,KAAKojE,OAAO7kD,aAAa,IACnDha,GAAuD,IAA/CA,EAAK2gE,SAASllE,KAAKojE,OAAO7kD,aAAa,KAC7Cve,KAAKojE,OAAO7kD,aAAa,GAAKve,KAAK8R,eAAe7J,MACpDjI,KAAKojE,OAAO7kD,aAAa,IAG/B,CAGK6mD,GACHA,EAAqB,KAAOplE,KAAKojE,OAAO7kD,aAAa,IACrD6mD,EAAqB,KAAOplE,KAAKojE,OAAO7kD,aAAa,IACrDve,KAAKkE,SAAQ,EAEjB,CAMQ,WAAA6gE,GACN,GAAK/kE,KAAKojE,OAAO7kD,cAAiBve,KAAKojE,OAAO9kD,gBAG1Cte,KAAKqiE,kBAAmB,CAC1BriE,KAAKsvB,sBAAsBre,KAAK,CAAEwJ,OAAQza,KAAKqiE,kBAAmB3nD,qBAAqB,IAKvF,MAAMvW,EAASnE,KAAK8R,eAAe3N,OAC/BnE,KAAKqiE,kBAAoB,GACE,IAAzBriE,KAAKsjE,uBACPtjE,KAAKojE,OAAO7kD,aAAa,GAAKve,KAAK8R,eAAe7J,MAEpDjI,KAAKojE,OAAO7kD,aAAa,GAAK5J,KAAKC,IAAIzQ,EAAOK,MAAQxE,KAAK8R,eAAe/Q,KAAO,EAAGoD,EAAOE,MAAM9C,OAAS,KAE7E,IAAzBvB,KAAKsjE,uBACPtjE,KAAKojE,OAAO7kD,aAAa,GAAK,GAEhCve,KAAKojE,OAAO7kD,aAAa,GAAKpa,EAAOK,OAEvCxE,KAAKkE,SACP,CACF,CAMQ,cAAA6hB,CAAexX,GACrB,MAAM+2D,EAAc/2D,EAAM0sB,UAAYj7B,KAAKwiE,oBAI3C,GAFAxiE,KAAKujE,4BAEDvjE,KAAKsL,cAAc/J,QAAU,GAAK+jE,EAAW,KAA2C/2D,EAAMsQ,QAAU7e,KAAKkqB,gBAAgB5f,WAAWi7D,qBAC1I,GAAIvlE,KAAK8R,eAAe3N,OAAOqQ,QAAUxU,KAAK8R,eAAe3N,OAAOK,MAAO,CACzE,MAAMghE,EAAcxlE,KAAKsZ,oBAAoBmQ,UAC3Clb,EACAvO,KAAKilB,SACLjlB,KAAK8R,eAAe7J,KACpBjI,KAAK8R,eAAe/Q,MACpB,GAEF,GAAIykE,QAAkC5gE,IAAnB4gE,EAAY,SAAuC5gE,IAAnB4gE,EAAY,GAAkB,CAC/E,MAAM9lC,GAAW,EAAAqiC,EAAA0D,oBAAmBD,EAAY,GAAK,EAAGA,EAAY,GAAK,EAAGxlE,KAAK8R,eAAgB9R,KAAKovB,aAAa/kB,gBAAgB24B,uBACnIhjC,KAAKovB,aAAa5kB,iBAAiBk1B,GAAU,EAC/C,CACF,OAEA1/B,KAAK0lE,8BAET,CAEQ,4BAAAA,GACN,MAAMrjE,EAAQrC,KAAKojE,OAAOlO,oBACpB5yD,EAAMtC,KAAKojE,OAAOhO,kBAClB9/C,KAAiBjT,IAAWC,GAAQD,EAAM,KAAOC,EAAI,IAAMD,EAAM,KAAOC,EAAI,IAE7EgT,EAQAjT,GAAUC,IAIVtC,KAAK0iE,oBAAuB1iE,KAAK2iE,kBACpCtgE,EAAM,KAAOrC,KAAK0iE,mBAAmB,IAAMrgE,EAAM,KAAOrC,KAAK0iE,mBAAmB,IAChFpgE,EAAI,KAAOtC,KAAK2iE,iBAAiB,IAAMrgE,EAAI,KAAOtC,KAAK2iE,iBAAiB,IAExE3iE,KAAKilE,uBAAuB5iE,EAAOC,EAAKgT,IAfpCtV,KAAKyiE,kBACPziE,KAAKilE,uBAAuB5iE,EAAOC,EAAKgT,EAgB9C,CAEQ,sBAAA2vD,CAAuB5iE,EAAqCC,EAAmCgT,GACrGtV,KAAK0iE,mBAAqBrgE,EAC1BrC,KAAK2iE,iBAAmBrgE,EACxBtC,KAAKyiE,iBAAmBntD,EACxBtV,KAAKyP,mBAAmBwB,MAC1B,CAEQ,qBAAAkyD,CAAsBhiE,GAC5BnB,KAAKuG,iBAKLvG,KAAKuiE,cAAc93D,MAAQtJ,EAAEwkE,aAAathE,MAAM4+D,OAAOxoD,GAAUza,KAAKkjE,YAAYzoD,GACpF,CAQQ,mCAAAmrD,CAAoCnxD,EAAyBI,GACnE,IAAIgxD,EAAYhxD,EAChB,IAAK,IAAI/V,EAAI,EAAG+V,GAAK/V,EAAGA,IAAK,CAC3B,MAAMyC,EAASkT,EAAWqW,SAAShsB,EAAGkB,KAAKoqB,WAAWujB,WAAWpsC,OAC/B,IAA9BvB,KAAKoqB,UAAUrV,WAGjB8wD,IACStkE,EAAS,GAAKsT,IAAM/V,IAI7B+mE,GAAatkE,EAAS,EAE1B,CACA,OAAOskE,CACT,CAEO,YAAAznD,CAAak9C,EAAa1zD,EAAarG,GAC5CvB,KAAKojE,OAAO78D,iBACZvG,KAAKujE,4BACLvjE,KAAKojE,OAAO9kD,eAAiB,CAACg9C,EAAK1zD,GACnC5H,KAAKojE,OAAOnO,qBAAuB1zD,EACnCvB,KAAKkE,UACLlE,KAAK0lE,8BACP,CAEO,gBAAAh6D,CAAiBf,GACjB3K,KAAK8jE,oBAAoBn5D,KACxB3K,KAAKkkE,oBAAoBv5D,GAAI,IAC/B3K,KAAKkE,SAAQ,GAEflE,KAAK0lE,+BAET,CAMQ,UAAAI,CAAWt8C,EAA0B26C,EAAuC4B,GAAmC,EAAMC,GAAmC,GAE9J,GAAIx8C,EAAO,IAAMxpB,KAAK8R,eAAe7J,KACnC,OAGF,MAAM9D,EAASnE,KAAK8R,eAAe3N,OAC7BsQ,EAAatQ,EAAOE,MAAMP,IAAI0lB,EAAO,IAC3C,IAAK/U,EACH,OAGF,MAAMlQ,EAAOJ,EAAO87B,4BAA4BzW,EAAO,IAAI,GAG3D,IAAIquC,EAAa73D,KAAK4lE,oCAAoCnxD,EAAY+U,EAAO,IACzEsuC,EAAWD,EAGf,MAAMoO,EAAaz8C,EAAO,GAAKquC,EAC/B,IAAIqO,EAAoB,EACpBC,EAAqB,EACrBC,EAAqB,EACrBC,EAAsB,EAE1B,GAAgC,MAA5B9hE,EAAK+hE,OAAOzO,GAAqB,CAEnC,KAAOA,EAAa,GAAqC,MAAhCtzD,EAAK+hE,OAAOzO,EAAa,IAChDA,IAEF,KAAOC,EAAWvzD,EAAKhD,QAAwC,MAA9BgD,EAAK+hE,OAAOxO,EAAW,IACtDA,GAEJ,KAAO,CAKL,IAAIj4B,EAAWrW,EAAO,GAClBsW,EAAStW,EAAO,GAIkB,IAAlC/U,EAAWM,SAAS8qB,KACtBqmC,IACArmC,KAEkC,IAAhCprB,EAAWM,SAAS+qB,KACtBqmC,IACArmC,KAIF,MAAMv+B,EAASkT,EAAW6jD,UAAUx4B,GAAQv+B,OAO5C,IANIA,EAAS,IACX8kE,GAAuB9kE,EAAS,EAChCu2D,GAAYv2D,EAAS,GAIhBs+B,EAAW,GAAKg4B,EAAa,IAAM73D,KAAKumE,qBAAqB9xD,EAAWqW,SAAS+U,EAAW,EAAG7/B,KAAKoqB,aAAa,CACtH3V,EAAWqW,SAAS+U,EAAW,EAAG7/B,KAAKoqB,WACvC,MAAM7oB,EAASvB,KAAKoqB,UAAUujB,WAAWpsC,OACP,IAA9BvB,KAAKoqB,UAAUrV,YAEjBmxD,IACArmC,KACSt+B,EAAS,IAGlB6kE,GAAsB7kE,EAAS,EAC/Bs2D,GAAct2D,EAAS,GAEzBs2D,IACAh4B,GACF,CACA,KAAOC,EAASrrB,EAAWlT,QAAUu2D,EAAW,EAAIvzD,EAAKhD,SAAWvB,KAAKumE,qBAAqB9xD,EAAWqW,SAASgV,EAAS,EAAG9/B,KAAKoqB,aAAa,CAC9I3V,EAAWqW,SAASgV,EAAS,EAAG9/B,KAAKoqB,WACrC,MAAM7oB,EAASvB,KAAKoqB,UAAUujB,WAAWpsC,OACP,IAA9BvB,KAAKoqB,UAAUrV,YAEjBoxD,IACArmC,KACSv+B,EAAS,IAGlB8kE,GAAuB9kE,EAAS,EAChCu2D,GAAYv2D,EAAS,GAEvBu2D,IACAh4B,GACF,CACF,CAGAg4B,IAIA,IAAIz1D,EACFw1D,EACEoO,EACAC,EACAE,EAIA7kE,EAASoT,KAAKC,IAAI5U,KAAK8R,eAAe7J,KACxC6vD,EACED,EACAqO,EACAC,EACAC,EACAC,GAEJ,GAAKlC,GAA4E,KAA5C5/D,EAAKgD,MAAMswD,EAAYC,GAAU9lB,OAAtE,CAKA,GAAI+zB,GACY,IAAV1jE,GAA8C,KAA/BoS,EAAW+xD,aAAa,GAAqB,CAC9D,MAAMC,EAAqBtiE,EAAOE,MAAMP,IAAI0lB,EAAO,GAAK,GACxD,GAAIi9C,GAAsBhyD,EAAWyX,WAA+E,KAAlEu6C,EAAmBD,aAAaxmE,KAAK8R,eAAe7J,KAAO,GAAqB,CAChI,MAAMy+D,EAA2B1mE,KAAK8lE,WAAW,CAAC9lE,KAAK8R,eAAe7J,KAAO,EAAGuhB,EAAO,GAAK,IAAI,GAAO,GAAM,GAC7G,GAAIk9C,EAA0B,CAC5B,MAAM7/D,EAAS7G,KAAK8R,eAAe7J,KAAOy+D,EAAyBrkE,MACnEA,GAASwE,EACTtF,GAAUsF,CACZ,CACF,CACF,CAIF,GAAIm/D,GACE3jE,EAAQd,IAAWvB,KAAK8R,eAAe7J,MAAkE,KAA1DwM,EAAW+xD,aAAaxmE,KAAK8R,eAAe7J,KAAO,GAAqB,CACzH,MAAM0+D,EAAiBxiE,EAAOE,MAAMP,IAAI0lB,EAAO,GAAK,GACpD,GAAIm9C,GAAgBz6C,WAAgD,KAAnCy6C,EAAeH,aAAa,GAAqB,CAChF,MAAMI,EAAuB5mE,KAAK8lE,WAAW,CAAC,EAAGt8C,EAAO,GAAK,IAAI,GAAO,GAAO,GAC3Eo9C,IACFrlE,GAAUqlE,EAAqBrlE,OAEnC,CACF,CAGF,MAAO,CAAEc,QAAOd,SA9BhB,CA+BF,CAOU,aAAA8iE,CAAc76C,EAA0B26C,GAChD,MAAM0C,EAAe7mE,KAAK8lE,WAAWt8C,EAAQ26C,GAC7C,GAAI0C,EAAc,CAEhB,KAAOA,EAAaxkE,MAAQ,GAC1BwkE,EAAaxkE,OAASrC,KAAK8R,eAAe7J,KAC1CuhB,EAAO,KAETxpB,KAAKojE,OAAO9kD,eAAiB,CAACuoD,EAAaxkE,MAAOmnB,EAAO,IACzDxpB,KAAKojE,OAAOnO,qBAAuB4R,EAAatlE,MAClD,CACF,CAMQ,eAAA8jE,CAAgB77C,GACtB,MAAMq9C,EAAe7mE,KAAK8lE,WAAWt8C,GAAQ,GAC7C,GAAIq9C,EAAc,CAChB,IAAIt+C,EAASiB,EAAO,GAGpB,KAAOq9C,EAAaxkE,MAAQ,GAC1BwkE,EAAaxkE,OAASrC,KAAK8R,eAAe7J,KAC1CsgB,IAKF,IAAKvoB,KAAKojE,OAAOjO,6BACf,KAAO0R,EAAaxkE,MAAQwkE,EAAatlE,OAASvB,KAAK8R,eAAe7J,MACpE4+D,EAAatlE,QAAUvB,KAAK8R,eAAe7J,KAC3CsgB,IAIJvoB,KAAKojE,OAAO7kD,aAAe,CAACve,KAAKojE,OAAOjO,6BAA+B0R,EAAaxkE,MAAQwkE,EAAaxkE,MAAQwkE,EAAatlE,OAAQgnB,EACxI,CACF,CAOQ,oBAAAg+C,CAAqB79D,GAG3B,OAAwB,IAApBA,EAAKqM,YAGF/U,KAAKkqB,gBAAgB5f,WAAWw8D,cAAc3L,QAAQzyD,EAAKilC,aAAe,CACnF,CAMU,aAAAw3B,CAAc5gE,GACtB,MAAMwiE,EAAe/mE,KAAK8R,eAAe3N,OAAO6iE,uBAAuBziE,GACjEojB,EAAsB,CAC1BtlB,MAAO,CAAEwS,EAAG,EAAGV,EAAG4yD,EAAaE,OAC/B3kE,IAAK,CAAEuS,EAAG7U,KAAK8R,eAAe7J,KAAO,EAAGkM,EAAG4yD,EAAaG,OAE1DlnE,KAAKojE,OAAO9kD,eAAiB,CAAC,EAAGyoD,EAAaE,OAC9CjnE,KAAKojE,OAAO7kD,kBAAe3Z,EAC3B5E,KAAKojE,OAAOnO,sBAAuB,EAAAgN,EAAAmC,gBAAez8C,EAAO3nB,KAAK8R,eAAe7J,KAC/E,2CAz9BWmS,EAAgB7Q,EAAA,CAuDxBC,EAAA,EAAAlK,EAAAwqB,gBACAtgB,EAAA,EAAAlK,EAAAqzB,cACAnpB,EAAA,EAAAnK,EAAAma,qBACAhQ,EAAA,EAAAlK,EAAAytB,iBACAvjB,EAAA,EAAAlK,EAAAszB,oBACAppB,EAAA,EAAAnK,EAAAsK,gBACAH,EAAA,EAAAnK,EAAAqK,sBA7DQ0Q,gRC9Db,MAAA+sD,EAAAjoE,EAAA,MAIaT,EAAA8Z,kBAAmB,EAAA4uD,EAAAC,iBAAkC,mBAarD3oE,EAAAiL,qBAAsB,EAAAy9D,EAAAC,iBAAqC,sBA0B3D3oE,EAAA+a,qBAAsB,EAAA2tD,EAAAC,iBAAqC,sBAQ3D3oE,EAAA+b,eAAgB,EAAA2sD,EAAAC,iBAA+B,gBAc/C3oE,EAAAkL,gBAAiB,EAAAw9D,EAAAC,iBAAgC,iBAmCjD3oE,EAAA4b,mBAAoB,EAAA8sD,EAAAC,iBAAmC,oBA6BvD3oE,EAAAsa,yBAA0B,EAAAouD,EAAAC,iBAAyC,0BASnE3oE,EAAAga,eAAgB,EAAA0uD,EAAAC,iBAA+B,gBAiB/C3oE,EAAAmS,sBAAuB,EAAAu2D,EAAAC,iBAAsC,uBAU7D3oE,EAAAgS,kBAAmB,EAAA02D,EAAAC,iBAAkC,4gBCxKlE,MAAAC,EAAAnoE,EAAA,MAEAooE,EAAApoE,EAAA,MACAqO,EAAArO,EAAA,MACAE,EAAAF,EAAA,MACAG,EAAAH,EAAA,MAEA8O,EAAA9O,EAAA,MAUMqoE,EAAqBh6D,EAAA9E,IAAIqK,QAAQ,WACjC00D,EAAqBj6D,EAAA9E,IAAIqK,QAAQ,WACjC20D,EAAiBl6D,EAAA9E,IAAIqK,QAAQ,WAC7B40D,EAAwBF,EACxBG,EAAoB,CACxBl/D,IAAK,2BACL6K,KAAM,YAEFs0D,EAAgCL,EAE/B,IAAM/uD,EAAN,cAA2BpZ,EAAAK,WAQhC,UAAWgT,GAA6B,OAAOzS,KAAK6nE,OAAS,CAK7D,WAAAnoE,CACoCwqB,GAElCnqB,QAFkCC,KAAAkqB,gBAAAA,EAV5BlqB,KAAA8nE,eAAsC,IAAIT,EAAAU,mBAC1C/nE,KAAAgoE,mBAA0C,IAAIX,EAAAU,mBAKrC/nE,KAAAioE,gBAAkBjoE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACtCtP,KAAA2Y,eAAiB3Y,KAAKioE,gBAAgB15D,MAOpDvO,KAAK6nE,QAAU,CACbt0D,WAAYg0D,EACZl0D,WAAYm0D,EACZjgC,OAAQkgC,EACRjgC,aAAckgC,EACdz5B,yBAAqBrpC,EACrBsjE,+BAAgCP,EAChCjgC,0BAA2Bn6B,EAAAgF,MAAM41D,MAAMX,EAAoBG,GAC3DS,uCAAwCT,EACxChgC,kCAAmCp6B,EAAAgF,MAAM41D,MAAMX,EAAoBG,GACnEt2C,0BAA2B9jB,EAAAgF,MAAM81D,QAAQd,EAAoB,IAC7Dj2C,+BAAgC/jB,EAAAgF,MAAM81D,QAAQd,EAAoB,IAClEh2C,gCAAiChkB,EAAAgF,MAAM81D,QAAQd,EAAoB,IACnE1vC,oBAAqB0vC,EACrB70D,KAAM40D,EAAA54C,oBAAoBnnB,QAC1BmpC,cAAe1wC,KAAK8nE,eACpBr3B,kBAAmBzwC,KAAKgoE,oBAE1BhoE,KAAKsoE,uBACLtoE,KAAKuoE,UAAUvoE,KAAKkqB,gBAAgB5f,WAAWk+D,OAE/CxoE,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,uBAAwB,IAAMzX,KAAK8nE,eAAez7D,UAC7GrM,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,QAAS,IAAMzX,KAAKuoE,UAAUvoE,KAAKkqB,gBAAgB5f,WAAWk+D,QAC3H,CAOQ,SAAAD,CAAUC,EAAgB,IAChC,MAAM/1D,EAASzS,KAAK6nE,QAkBpB,GAjBAp1D,EAAOc,WAAak1D,EAAWD,EAAMj1D,WAAYg0D,GACjD90D,EAAOY,WAAao1D,EAAWD,EAAMn1D,WAAYm0D,GACjD/0D,EAAO80B,OAASh6B,EAAAgF,MAAM41D,MAAM11D,EAAOY,WAAYo1D,EAAWD,EAAMjhC,OAAQkgC,IACxEh1D,EAAO+0B,aAAej6B,EAAAgF,MAAM41D,MAAM11D,EAAOY,WAAYo1D,EAAWD,EAAMhhC,aAAckgC,IACpFj1D,EAAOy1D,+BAAiCO,EAAWD,EAAME,oBAAqBf,GAC9El1D,EAAOi1B,0BAA4Bn6B,EAAAgF,MAAM41D,MAAM11D,EAAOY,WAAYZ,EAAOy1D,gCACzEz1D,EAAO21D,uCAAyCK,EAAWD,EAAMG,4BAA6Bl2D,EAAOy1D,gCACrGz1D,EAAOk1B,kCAAoCp6B,EAAAgF,MAAM41D,MAAM11D,EAAOY,WAAYZ,EAAO21D,wCACjF31D,EAAOw7B,oBAAsBu6B,EAAMv6B,oBAAsBw6B,EAAWD,EAAMv6B,oBAAqB1gC,EAAAq7D,iBAAchkE,EACzG6N,EAAOw7B,sBAAwB1gC,EAAAq7D,aACjCn2D,EAAOw7B,yBAAsBrpC,GAO3B2I,EAAAgF,MAAMs2D,SAASp2D,EAAOy1D,gCAAiC,CACzD,MAAMG,EAAU,GAChB51D,EAAOy1D,+BAAiC36D,EAAAgF,MAAM81D,QAAQ51D,EAAOy1D,+BAAgCG,EAC/F,CACA,GAAI96D,EAAAgF,MAAMs2D,SAASp2D,EAAO21D,wCAAyC,CACjE,MAAMC,EAAU,GAChB51D,EAAO21D,uCAAyC76D,EAAAgF,MAAM81D,QAAQ51D,EAAO21D,uCAAwCC,EAC/G,CAsBA,GArBA51D,EAAO4e,0BAA4Bo3C,EAAWD,EAAMn3C,0BAA2B9jB,EAAAgF,MAAM81D,QAAQ51D,EAAOc,WAAY,KAChHd,EAAO6e,+BAAiCm3C,EAAWD,EAAMl3C,+BAAgC/jB,EAAAgF,MAAM81D,QAAQ51D,EAAOc,WAAY,KAC1Hd,EAAO8e,gCAAkCk3C,EAAWD,EAAMj3C,gCAAiChkB,EAAAgF,MAAM81D,QAAQ51D,EAAOc,WAAY,KAC5Hd,EAAOolB,oBAAsB4wC,EAAWD,EAAM3wC,oBAAqB+vC,GACnEn1D,EAAOC,KAAO40D,EAAA54C,oBAAoBnnB,QAClCkL,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMM,MAAOxB,EAAA54C,oBAAoB,IAC7Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMO,IAAKzB,EAAA54C,oBAAoB,IAC3Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMQ,MAAO1B,EAAA54C,oBAAoB,IAC7Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMS,OAAQ3B,EAAA54C,oBAAoB,IAC9Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMU,KAAM5B,EAAA54C,oBAAoB,IAC5Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMW,QAAS7B,EAAA54C,oBAAoB,IAC/Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMY,KAAM9B,EAAA54C,oBAAoB,IAC5Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMa,MAAO/B,EAAA54C,oBAAoB,IAC7Djc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMc,YAAahC,EAAA54C,oBAAoB,IACnEjc,EAAOC,KAAK,GAAK+1D,EAAWD,EAAMe,UAAWjC,EAAA54C,oBAAoB,IACjEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMgB,YAAalC,EAAA54C,oBAAoB,KACpEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMiB,aAAcnC,EAAA54C,oBAAoB,KACrEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMkB,WAAYpC,EAAA54C,oBAAoB,KACnEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMmB,cAAerC,EAAA54C,oBAAoB,KACtEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMoB,WAAYtC,EAAA54C,oBAAoB,KACnEjc,EAAOC,KAAK,IAAM+1D,EAAWD,EAAMqB,YAAavC,EAAA54C,oBAAoB,KAChE85C,EAAMsB,aAAc,CACtB,MAAMC,EAAap1D,KAAKC,IAAInC,EAAOC,KAAKnR,OAAS,GAAIinE,EAAMsB,aAAavoE,QACxE,IAAK,IAAIzC,EAAI,EAAGA,EAAIirE,EAAYjrE,IAC9B2T,EAAOC,KAAK5T,EAAI,IAAM2pE,EAAWD,EAAMsB,aAAahrE,GAAIwoE,EAAA54C,oBAAoB5vB,EAAI,IAEpF,CAEAkB,KAAK8nE,eAAez7D,QACpBrM,KAAKgoE,mBAAmB37D,QACxBrM,KAAKsoE,uBACLtoE,KAAKioE,gBAAgBh3D,KAAKjR,KAAKyS,OACjC,CAEO,YAAAO,CAAag3D,GAClBhqE,KAAKiqE,cAAcD,GACnBhqE,KAAKioE,gBAAgBh3D,KAAKjR,KAAKyS,OACjC,CAEQ,aAAAw3D,CAAcD,GAEpB,QAAaplE,IAATolE,EAMJ,OAAQA,GACN,SACEhqE,KAAK6nE,QAAQt0D,WAAavT,KAAKkqE,eAAe32D,WAC9C,MACF,SACEvT,KAAK6nE,QAAQx0D,WAAarT,KAAKkqE,eAAe72D,WAC9C,MACF,SACErT,KAAK6nE,QAAQtgC,OAASvnC,KAAKkqE,eAAe3iC,OAC1C,MACF,QACEvnC,KAAK6nE,QAAQn1D,KAAKs3D,GAAQhqE,KAAKkqE,eAAex3D,KAAKs3D,QAhBrD,IAAK,IAAIlrE,EAAI,EAAGA,EAAIkB,KAAKkqE,eAAex3D,KAAKnR,SAAUzC,EACrDkB,KAAK6nE,QAAQn1D,KAAK5T,GAAKkB,KAAKkqE,eAAex3D,KAAK5T,EAiBtD,CAEO,YAAA8T,CAAa0X,GAClBA,EAAStqB,KAAK6nE,SAEd7nE,KAAKioE,gBAAgBh3D,KAAKjR,KAAKyS,OACjC,CAEQ,oBAAA61D,GACNtoE,KAAKkqE,eAAiB,CACpB32D,WAAYvT,KAAK6nE,QAAQt0D,WACzBF,WAAYrT,KAAK6nE,QAAQx0D,WACzBk0B,OAAQvnC,KAAK6nE,QAAQtgC,OACrB70B,KAAM1S,KAAK6nE,QAAQn1D,KAAKnL,QAE5B,GAGF,SAASkhE,EACP0B,EACAC,GAEA,QAAkBxlE,IAAdulE,EACF,IACE,OAAO58D,EAAA9E,IAAIqK,QAAQq3D,EACrB,CAAE,MAEF,CAEF,OAAOC,CACT,iCArKa5xD,EAAYjP,EAAA,CAcpBC,EAAA,EAAAnK,EAAA0tB,kBAdQvU,kICvBb,SAAwB6xD,GACtB,OAAO,IAAIC,QAAQC,GAAW97C,WAAW87C,EAASF,GACpD,sBASA,SAAkC5sD,EAAqB+sD,EAAU,EAAGzL,GAClE,MAAMjkC,EAAQrM,WAAW,KACvBhR,IACIshD,GACF5iD,EAAW9C,WAEZmxD,GACGruD,GAAa,EAAA/c,EAAAqE,cAAa,KAC9B0qB,aAAa2M,KAGf,OADAikC,GAAOp+D,IAAIwb,GACJA,CACT,EAzBA,MAAA/c,EAAAF,EAAA,qBA2BA,iBAAAQ,GACUM,KAAAyqE,QAAe,EACfzqE,KAAA0qE,aAAc,CAqCxB,CAnCS,OAAArxD,GACLrZ,KAAKof,SACLpf,KAAK0qE,aAAc,CACrB,CAEO,MAAAtrD,IACgB,IAAjBpf,KAAKyqE,SACPt8C,aAAanuB,KAAKyqE,QAClBzqE,KAAKyqE,QAAU,EAEnB,CAEO,YAAA5lD,CAAahD,EAAoB2oD,GACtC,GAAIxqE,KAAK0qE,YACP,MAAM,IAAI3oE,MAAM,mDAElB/B,KAAKof,SACLpf,KAAKyqE,OAASh8C,WAAW,KACvBzuB,KAAKyqE,QAAU,EACf5oD,KACC2oD,EACL,CAEO,WAAArc,CAAYtsC,EAAoB2oD,GACrC,GAAIxqE,KAAK0qE,YACP,MAAM,IAAI3oE,MAAM,mDAEG,IAAjB/B,KAAKyqE,SAGTzqE,KAAKyqE,OAASh8C,WAAW,KACvBzuB,KAAKyqE,QAAU,EACf5oD,KACC2oD,GACL,oBAQF,iBAAA9qE,GACUM,KAAA2qE,cAAe,EACf3qE,KAAA0qE,aAAc,CA2BxB,CAzBS,OAAArxD,GACLrZ,KAAKof,SACLpf,KAAK0qE,aAAc,CACrB,CAEO,MAAAtrD,GACLpf,KAAK2qE,cAAe,CACtB,CAEO,GAAA7lE,CAAI+c,GACT,GAAI7hB,KAAK0qE,YACP,MAAM,IAAI3oE,MAAM,4CAEd/B,KAAK2qE,eAGT3qE,KAAK2qE,cAAe,EACpBxR,eAAe,KACRn5D,KAAK2qE,eAGV3qE,KAAK2qE,cAAe,EACpB9oD,OAEJ,mBAGF,iBAAAniB,GAEUM,KAAA0qE,aAAc,CA2BxB,CAzBS,MAAAtrD,GACLpf,KAAK4qE,aAAavxD,UAClBrZ,KAAK4qE,iBAAchmE,CACrB,CAEO,YAAAigB,CAAahD,EAAoBiD,EAAkB+lD,EAAsC9rE,YAC9F,GAAIiB,KAAK0qE,YACP,MAAM,IAAI3oE,MAAM,oDAElB/B,KAAKof,SACL,MAAM0rD,EAASD,EAAQl3B,YAAY,KACjC9xB,KACCiD,GACH9kB,KAAK4qE,YAAc,CACjBvxD,QAAS,KACPwxD,EAAQj3B,cAAck3B,GACtB9qE,KAAK4qE,iBAAchmE,GAGzB,CAEO,OAAAyU,GACLrZ,KAAKof,SACLpf,KAAK0qE,aAAc,CACrB,uFCtIF,MAAAtrE,EAAAF,EAAA,MACA8O,EAAA9O,EAAA,MAsCA,MAAA6rE,UAAqC3rE,EAAAK,WAYnC,WAAAC,CACUsrE,GAERjrE,QAFQC,KAAAgrE,WAAAA,EARMhrE,KAAAirE,gBAAkBjrE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAAkrE,SAAWlrE,KAAKirE,gBAAgB18D,MAChCvO,KAAAmrE,gBAAkBnrE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAAorE,SAAWprE,KAAKmrE,gBAAgB58D,MAChCvO,KAAAqrE,cAAgBrrE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACnCtP,KAAAijE,OAASjjE,KAAKqrE,cAAc98D,MAM1CvO,KAAKsrE,OAAS,IAAIC,MAASvrE,KAAKgrE,YAChChrE,KAAKwrE,YAAc,EACnBxrE,KAAKyrE,QAAU,CACjB,CAEA,aAAWC,GACT,OAAO1rE,KAAKgrE,UACd,CAEA,aAAWU,CAAUC,GAEnB,GAAI3rE,KAAKgrE,aAAeW,EACtB,OAKF,MAAMC,EAAW,IAAIL,MAAqBI,GAC1C,IAAK,IAAI7sE,EAAI,EAAGA,EAAI6V,KAAKC,IAAI+2D,EAAc3rE,KAAKuB,QAASzC,IACvD8sE,EAAS9sE,GAAKkB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB/sE,IAEjDkB,KAAKsrE,OAASM,EACd5rE,KAAKgrE,WAAaW,EAClB3rE,KAAKwrE,YAAc,CACrB,CAEA,UAAWjqE,GACT,OAAOvB,KAAKyrE,OACd,CAEA,UAAWlqE,CAAOuqE,GAChB,GAAIA,EAAY9rE,KAAKyrE,QACnB,IAAK,IAAI3sE,EAAIkB,KAAKyrE,QAAS3sE,EAAIgtE,EAAWhtE,IACxCkB,KAAKsrE,OAAOxsE,QAAK8F,EAGrB5E,KAAKyrE,QAAUK,CACjB,CAUO,GAAAhoE,CAAIuO,GACT,OAAOrS,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgBx5D,GAC1C,CAUO,GAAAvN,CAAIuN,EAAe5H,GACxBzK,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgBx5D,IAAU5H,CAC7C,CAOO,IAAAxG,CAAKwG,GACVzK,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB7rE,KAAKyrE,UAAYhhE,EAC9CzK,KAAKyrE,UAAYzrE,KAAKgrE,YACxBhrE,KAAKwrE,cAAgBxrE,KAAKwrE,YAAcxrE,KAAKgrE,WAC7ChrE,KAAKqrE,cAAcp6D,KAAK,IAExBjR,KAAKyrE,SAET,CAOO,OAAAM,GACL,GAAI/rE,KAAKyrE,UAAYzrE,KAAKgrE,WACxB,MAAM,IAAIjpE,MAAM,4CAIlB,OAFA/B,KAAKwrE,cAAgBxrE,KAAKwrE,YAAcxrE,KAAKgrE,WAC7ChrE,KAAKqrE,cAAcp6D,KAAK,GACjBjR,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB7rE,KAAKyrE,QAAU,GACzD,CAKA,UAAWO,GACT,OAAOhsE,KAAKyrE,UAAYzrE,KAAKgrE,UAC/B,CAMO,GAAAvlE,GACL,OAAOzF,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB7rE,KAAKyrE,UAAY,GAC3D,CAWO,MAAA3jD,CAAOzlB,EAAe4pE,KAAwBC,GAEnD,GAAID,EAAa,CACf,IAAK,IAAIntE,EAAIuD,EAAOvD,EAAIkB,KAAKyrE,QAAUQ,EAAantE,IAClDkB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB/sE,IAAMkB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB/sE,EAAImtE,IAE9EjsE,KAAKyrE,SAAWQ,EAChBjsE,KAAKirE,gBAAgBh6D,KAAK,CAAEoB,MAAOhQ,EAAOoY,OAAQwxD,GACpD,CAGA,IAAK,IAAIntE,EAAIkB,KAAKyrE,QAAU,EAAG3sE,GAAKuD,EAAOvD,IACzCkB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB/sE,EAAIotE,EAAM3qE,SAAWvB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgB/sE,IAEzF,IAAK,IAAIA,EAAI,EAAGA,EAAIotE,EAAM3qE,OAAQzC,IAChCkB,KAAKsrE,OAAOtrE,KAAK6rE,gBAAgBxpE,EAAQvD,IAAMotE,EAAMptE,GAOvD,GALIotE,EAAM3qE,QACRvB,KAAKmrE,gBAAgBl6D,KAAK,CAAEoB,MAAOhQ,EAAOoY,OAAQyxD,EAAM3qE,SAItDvB,KAAKyrE,QAAUS,EAAM3qE,OAASvB,KAAKgrE,WAAY,CACjD,MAAMmB,EAAensE,KAAKyrE,QAAUS,EAAM3qE,OAAUvB,KAAKgrE,WACzDhrE,KAAKwrE,aAAeW,EACpBnsE,KAAKyrE,QAAUzrE,KAAKgrE,WACpBhrE,KAAKqrE,cAAcp6D,KAAKk7D,EAC1B,MACEnsE,KAAKyrE,SAAWS,EAAM3qE,MAE1B,CAMO,SAAA6qE,CAAUlsC,GACXA,EAAQlgC,KAAKyrE,UACfvrC,EAAQlgC,KAAKyrE,SAEfzrE,KAAKwrE,aAAetrC,EACpBlgC,KAAKyrE,SAAWvrC,EAChBlgC,KAAKqrE,cAAcp6D,KAAKivB,EAC1B,CAEO,aAAAmsC,CAAchqE,EAAe69B,EAAer5B,GACjD,KAAIq5B,GAAS,GAAb,CAGA,GAAI79B,EAAQ,GAAKA,GAASrC,KAAKyrE,QAC7B,MAAM,IAAI1pE,MAAM,+BAElB,GAAIM,EAAQwE,EAAS,EACnB,MAAM,IAAI9E,MAAM,gDAGlB,GAAI8E,EAAS,EAAG,CACd,IAAK,IAAI/H,EAAIohC,EAAQ,EAAGphC,GAAK,EAAGA,IAC9BkB,KAAK8E,IAAIzC,EAAQvD,EAAI+H,EAAQ7G,KAAK8D,IAAIzB,EAAQvD,IAEhD,MAAMwtE,EAAgBjqE,EAAQ69B,EAAQr5B,EAAU7G,KAAKyrE,QACrD,GAAIa,EAAe,EAEjB,IADAtsE,KAAKyrE,SAAWa,EACTtsE,KAAKyrE,QAAUzrE,KAAKgrE,YACzBhrE,KAAKyrE,UACLzrE,KAAKwrE,cACLxrE,KAAKqrE,cAAcp6D,KAAK,EAG9B,MACE,IAAK,IAAInS,EAAI,EAAGA,EAAIohC,EAAOphC,IACzBkB,KAAK8E,IAAIzC,EAAQvD,EAAI+H,EAAQ7G,KAAK8D,IAAIzB,EAAQvD,GAvBlD,CA0BF,CAQQ,eAAA+sE,CAAgBx5D,GACtB,OAAQrS,KAAKwrE,YAAcn5D,GAASrS,KAAKgrE,UAC3C,2KC7PF,IAAIuB,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EAUT,IAAiB75D,EA0BAN,EAuEA9J,EA+GA0K,EAoCAG,EAuGjB,SAAAq5D,EAA4B39C,GAC1B,MAAM49C,EAAI59C,EAAE1qB,SAAS,IACrB,OAAOsoE,EAAErrE,OAAS,EAAI,IAAMqrE,EAAIA,CAClC,CAQA,SAAAC,EAA8BC,EAAYC,GACxC,OAAID,EAAKC,GACCA,EAAK,MAASD,EAAK,MAErBA,EAAK,MAASC,EAAK,IAC7B,CAnXatuE,EAAAmqE,WAAqB,CAChCngE,IAAK,YACL6K,KAAM,GAMR,SAAiBT,GACCA,EAAAic,MAAhB,SAAsBF,EAAWC,EAAWtK,EAAW1lB,GACrD,YAAU+F,IAAN/F,EACK,IAAI8tE,EAAY/9C,KAAK+9C,EAAY99C,KAAK89C,EAAYpoD,KAAKooD,EAAY9tE,KAErE,IAAI8tE,EAAY/9C,KAAK+9C,EAAY99C,KAAK89C,EAAYpoD,IAC3D,EAEgB1R,EAAAkc,OAAhB,SAAuBH,EAAWC,EAAWtK,EAAW1lB,EAAY,KAIlE,OAAQ+vB,GAAK,GAAKC,GAAK,GAAKtK,GAAK,EAAI1lB,KAAO,CAC9C,EAEgBgU,EAAAC,QAAhB,SAAwB8b,EAAWC,EAAWtK,EAAW1lB,GACvD,MAAO,CACL4J,IAAKoK,EAASic,MAAMF,EAAGC,EAAGtK,EAAG1lB,GAC7ByU,KAAMT,EAASkc,OAAOH,EAAGC,EAAGtK,EAAG1lB,GAEnC,CACD,CArBD,CAAiBgU,IAAQpU,EAAAoU,SAARA,EAAQ,KA0BzB,SAAiBm6D,GAgDf,SAAgB3E,EAAQ91D,EAAe81D,GAGrC,OAFAqE,EAAK/3D,KAAK6d,MAAgB,IAAV61C,IACfkE,EAAIC,EAAIC,GAAMn5D,EAAK25D,WAAW16D,EAAMe,MAC9B,CACL7K,IAAKoK,EAASic,MAAMy9C,EAAIC,EAAIC,EAAIC,GAChCp5D,KAAMT,EAASkc,OAAOw9C,EAAIC,EAAIC,EAAIC,GAEtC,CAtDgBM,EAAA7E,MAAhB,SAAsBn8D,EAAYC,GAEhC,GADAygE,GAAgB,IAAVzgE,EAAGqH,MAAe,IACb,IAAPo5D,EACF,MAAO,CACLjkE,IAAKwD,EAAGxD,IACR6K,KAAMrH,EAAGqH,MAGb,MAAM45D,EAAOjhE,EAAGqH,MAAQ,GAAM,IACxB65D,EAAOlhE,EAAGqH,MAAQ,GAAM,IACxB85D,EAAOnhE,EAAGqH,MAAQ,EAAK,IACvB+5D,EAAOrhE,EAAGsH,MAAQ,GAAM,IACxBg6D,EAAOthE,EAAGsH,MAAQ,GAAM,IACxBi6D,EAAOvhE,EAAGsH,MAAQ,EAAK,IAM7B,OALAi5D,EAAKc,EAAM14D,KAAK6d,OAAO06C,EAAMG,GAAOX,GACpCF,EAAKc,EAAM34D,KAAK6d,OAAO26C,EAAMG,GAAOZ,GACpCD,EAAKc,EAAM54D,KAAK6d,OAAO46C,EAAMG,GAAOb,GAG7B,CAAEjkE,IAFGoK,EAASic,MAAMy9C,EAAIC,EAAIC,GAErBn5D,KADDT,EAASkc,OAAOw9C,EAAIC,EAAIC,GAEvC,EAEgBO,EAAAnE,SAAhB,SAAyBt2D,GACvB,QAA+B,KAAvBA,EAAMe,KAChB,EAEgB05D,EAAAx8B,oBAAhB,SAAoCxkC,EAAYC,EAAYskC,GAC1D,MAAMvxB,EAAS1L,EAAKk9B,oBAAoBxkC,EAAGsH,KAAMrH,EAAGqH,KAAMi9B,GAC1D,GAAKvxB,EAGL,OAAOnM,EAASC,QACbkM,GAAU,GAAK,IACfA,GAAU,GAAK,IACfA,GAAU,EAAK,IAEpB,EAEgBguD,EAAAnlC,OAAhB,SAAuBt1B,GACrB,MAAMi7D,GAA0B,IAAbj7D,EAAMe,QAAiB,EAE1C,OADCi5D,EAAIC,EAAIC,GAAMn5D,EAAK25D,WAAWO,GACxB,CACL/kE,IAAKoK,EAASic,MAAMy9C,EAAIC,EAAIC,GAC5Bn5D,KAAMk6D,EAEV,EAEgBR,EAAA3E,QAAOA,EASP2E,EAAA7lC,gBAAhB,SAAgC50B,EAAek7D,GAE7C,OADAf,EAAkB,IAAbn6D,EAAMe,KACJ+0D,EAAQ91D,EAAQm6D,EAAKe,EAAU,IACxC,EAEgBT,EAAAx6D,WAAhB,SAA2BD,GACzB,MAAO,CAAEA,EAAMe,MAAQ,GAAM,IAAOf,EAAMe,MAAQ,GAAM,IAAOf,EAAMe,MAAQ,EAAK,IACpF,CACD,CAjED,CAAiBf,IAAK9T,EAAA8T,MAALA,EAAK,KAuEtB,SAAiBm7D,GAEf,IAAIC,EACAC,EACJ,IAEE,MAAM5kE,EAASoP,SAAS3X,cAAc,UACtCuI,EAAOD,MAAQ,EACfC,EAAOL,OAAS,EAChB,MAAM0tB,EAAMrtB,EAAOstB,WAAW,KAAM,CAClCu3C,oBAAoB,IAElBx3C,IACFs3C,EAAOt3C,EACPs3C,EAAKG,yBAA2B,OAChCF,EAAeD,EAAKI,qBAAqB,EAAG,EAAG,EAAG,GAEtD,CACA,MAEA,CASgBL,EAAA56D,QAAhB,SAAwBrK,GAEtB,GAAIA,EAAI23C,MAAM,kBACZ,OAAQ33C,EAAIlH,QACV,KAAK,EAIH,OAHAgrE,EAAK1kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IACzC+sC,EAAK3kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IACzCgtC,EAAK5kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IAClC5sB,EAASC,QAAQy5D,EAAIC,EAAIC,GAElC,KAAK,EAKH,OAJAF,EAAK1kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IACzC+sC,EAAK3kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IACzCgtC,EAAK5kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IACzCitC,EAAK7kE,SAASY,EAAIlB,MAAM,EAAG,GAAGk4B,OAAO,GAAI,IAClC5sB,EAASC,QAAQy5D,EAAIC,EAAIC,EAAIC,GAEtC,KAAK,EACH,MAAO,CACLjkE,MACA6K,MAAOzL,SAASY,EAAIlB,MAAM,GAAI,KAAO,EAAI,OAAU,GAEvD,KAAK,EACH,MAAO,CACLkB,MACA6K,KAAMzL,SAASY,EAAIlB,MAAM,GAAI,MAAQ,GAM7C,MAAMymE,EAAYvlE,EAAI23C,MAAM,sFAC5B,GAAI4tB,EAKF,OAJAzB,EAAK1kE,SAASmmE,EAAU,GAAI,IAC5BxB,EAAK3kE,SAASmmE,EAAU,GAAI,IAC5BvB,EAAK5kE,SAASmmE,EAAU,GAAI,IAC5BtB,EAAK/3D,KAAK6d,MAAoE,UAA5C5tB,IAAjBopE,EAAU,GAAmB,EAAIC,WAAWD,EAAU,MAChEn7D,EAASC,QAAQy5D,EAAIC,EAAIC,EAAIC,GAItC,GAAY,gBAARjkE,EACF,MAAO,CACLA,IAAK,cACL6K,KAAM,GAKV,IAAKq6D,IAASC,EACZ,MAAM,IAAI7rE,MAAM,uCAOlB,GAFA4rE,EAAK/1C,UAAYg2C,EACjBD,EAAK/1C,UAAYnvB,EACa,iBAAnBklE,EAAK/1C,UACd,MAAM,IAAI71B,MAAM,uCAOlB,GAJA4rE,EAAK71C,SAAS,EAAG,EAAG,EAAG,IACtBy0C,EAAIC,EAAIC,EAAIC,GAAMiB,EAAKO,aAAa,EAAG,EAAG,EAAG,GAAGjxD,KAGtC,MAAPyvD,EACF,MAAM,IAAI3qE,MAAM,uCAMlB,MAAO,CACLuR,KAAMT,EAASkc,OAAOw9C,EAAIC,EAAIC,EAAIC,GAClCjkE,MAEJ,CACD,CA1GD,CAAiBA,IAAGhK,EAAAgK,IAAHA,EAAG,KA+GpB,SAAiB0lE,GAsBf,SAAgBC,EAAmBx/C,EAAWC,EAAWtK,GACvD,MAAM8pD,EAAKz/C,EAAI,IACT0/C,EAAKz/C,EAAI,IACT0/C,EAAKhqD,EAAI,IAIf,MAAY,OAHD8pD,GAAM,OAAUA,EAAK,MAAQ15D,KAAK4vC,KAAK8pB,EAAK,MAAS,MAAO,MAG7C,OAFfC,GAAM,OAAUA,EAAK,MAAQ35D,KAAK4vC,KAAK+pB,EAAK,MAAS,MAAO,MAE/B,OAD7BC,GAAM,OAAUA,EAAK,MAAQ55D,KAAK4vC,KAAKgqB,EAAK,MAAS,MAAO,KAEzE,CAvBgBJ,EAAA/6D,kBAAhB,SAAkCD,GAChC,OAAOi7D,EACJj7D,GAAO,GAAM,IACbA,GAAO,EAAM,IACA,IAAd,EACJ,EAUgBg7D,EAAAC,mBAAkBA,CASnC,CA/BD,CAAiBj7D,IAAG1U,EAAA0U,IAAHA,EAAG,KAoCpB,SAAiBG,GA0Df,SAAgBk7D,EAAgBC,EAAgBC,EAAgBn+B,GAG9D,MAAM88B,EAAOoB,GAAU,GAAM,IACvBnB,EAAOmB,GAAU,GAAM,IACvBlB,EAAOkB,GAAW,EAAK,IAC7B,IAAIvB,EAAOwB,GAAU,GAAM,IACvBvB,EAAOuB,GAAU,GAAM,IACvBtB,EAAOsB,GAAW,EAAK,IACvBC,EAAK9B,EAAc15D,EAAIi7D,mBAAmBlB,EAAKC,EAAKC,GAAMj6D,EAAIi7D,mBAAmBf,EAAKC,EAAKC,IAC/F,KAAOoB,EAAKp+B,IAAU28B,EAAM,GAAKC,EAAM,GAAKC,EAAM,IAEhDF,GAAOv4D,KAAKkZ,IAAI,EAAGlZ,KAAKoiB,KAAW,GAANm2C,IAC7BC,GAAOx4D,KAAKkZ,IAAI,EAAGlZ,KAAKoiB,KAAW,GAANo2C,IAC7BC,GAAOz4D,KAAKkZ,IAAI,EAAGlZ,KAAKoiB,KAAW,GAANq2C,IAC7BuB,EAAK9B,EAAc15D,EAAIi7D,mBAAmBlB,EAAKC,EAAKC,GAAMj6D,EAAIi7D,mBAAmBf,EAAKC,EAAKC,IAE7F,OAAQL,GAAO,GAAKC,GAAO,GAAKC,GAAO,EAAI,OAAU,CACvD,CAEA,SAAgBwB,EAAkBH,EAAgBC,EAAgBn+B,GAGhE,MAAM88B,EAAOoB,GAAU,GAAM,IACvBnB,EAAOmB,GAAU,GAAM,IACvBlB,EAAOkB,GAAW,EAAK,IAC7B,IAAIvB,EAAOwB,GAAU,GAAM,IACvBvB,EAAOuB,GAAU,GAAM,IACvBtB,EAAOsB,GAAW,EAAK,IACvBC,EAAK9B,EAAc15D,EAAIi7D,mBAAmBlB,EAAKC,EAAKC,GAAMj6D,EAAIi7D,mBAAmBf,EAAKC,EAAKC,IAC/F,KAAOoB,EAAKp+B,IAAU28B,EAAM,KAAQC,EAAM,KAAQC,EAAM,MAEtDF,EAAMv4D,KAAKC,IAAI,IAAMs4D,EAAMv4D,KAAKoiB,KAAmB,IAAb,IAAMm2C,KAC5CC,EAAMx4D,KAAKC,IAAI,IAAMu4D,EAAMx4D,KAAKoiB,KAAmB,IAAb,IAAMo2C,KAC5CC,EAAMz4D,KAAKC,IAAI,IAAMw4D,EAAMz4D,KAAKoiB,KAAmB,IAAb,IAAMq2C,KAC5CuB,EAAK9B,EAAc15D,EAAIi7D,mBAAmBlB,EAAKC,EAAKC,GAAMj6D,EAAIi7D,mBAAmBf,EAAKC,EAAKC,IAE7F,OAAQL,GAAO,GAAKC,GAAO,GAAKC,GAAO,EAAI,OAAU,CACvD,CA/FgB95D,EAAA60D,MAAhB,SAAsBn8D,EAAYC,GAEhC,GADAygE,GAAW,IAALzgE,GAAa,IACR,IAAPygE,EACF,OAAOzgE,EAET,MAAMihE,EAAOjhE,GAAM,GAAM,IACnBkhE,EAAOlhE,GAAM,GAAM,IACnBmhE,EAAOnhE,GAAM,EAAK,IAClBohE,EAAOrhE,GAAM,GAAM,IACnBshE,EAAOthE,GAAM,GAAM,IACnBuhE,EAAOvhE,GAAM,EAAK,IAIxB,OAHAugE,EAAKc,EAAM14D,KAAK6d,OAAO06C,EAAMG,GAAOX,GACpCF,EAAKc,EAAM34D,KAAK6d,OAAO26C,EAAMG,GAAOZ,GACpCD,EAAKc,EAAM54D,KAAK6d,OAAO46C,EAAMG,GAAOb,GAC7B75D,EAASkc,OAAOw9C,EAAIC,EAAIC,EACjC,EAegBn5D,EAAAk9B,oBAAhB,SAAoCi+B,EAAgBC,EAAgBn+B,GAClE,MAAMs+B,EAAM17D,EAAIC,kBAAkBq7D,GAAU,GACtCK,EAAM37D,EAAIC,kBAAkBs7D,GAAU,GAE5C,GADW7B,EAAcgC,EAAKC,GACrBv+B,EAAO,CACd,GAAIu+B,EAAMD,EAAK,CACb,MAAME,EAAUP,EAAgBC,EAAQC,EAAQn+B,GAC1Cy+B,EAAenC,EAAcgC,EAAK17D,EAAIC,kBAAkB27D,GAAW,IACzE,GAAIC,EAAez+B,EAAO,CACxB,MAAM0+B,EAAUL,EAAkBH,EAAQC,EAAQn+B,GAElD,OAAOy+B,EADcnC,EAAcgC,EAAK17D,EAAIC,kBAAkB67D,GAAW,IACpCF,EAAUE,CACjD,CACA,OAAOF,CACT,CACA,MAAMA,EAAUH,EAAkBH,EAAQC,EAAQn+B,GAC5Cy+B,EAAenC,EAAcgC,EAAK17D,EAAIC,kBAAkB27D,GAAW,IACzE,GAAIC,EAAez+B,EAAO,CACxB,MAAM0+B,EAAUT,EAAgBC,EAAQC,EAAQn+B,GAEhD,OAAOy+B,EADcnC,EAAcgC,EAAK17D,EAAIC,kBAAkB67D,GAAW,IACpCF,EAAUE,CACjD,CACA,OAAOF,CACT,CAEF,EAEgBz7D,EAAAk7D,gBAAeA,EAoBfl7D,EAAAs7D,kBAAiBA,EAoBjBt7D,EAAA25D,WAAhB,SAA2BxiE,GACzB,MAAO,CAAEA,GAAS,GAAM,IAAOA,GAAS,GAAM,IAAOA,GAAS,EAAK,IAAc,IAARA,EAC3E,CACD,CArGD,CAAiB6I,IAAI7U,EAAA6U,KAAJA,EAAI,yFCjPrB,MAAAjU,EAAAH,EAAA,MACAgwE,EAAAhwE,EAAA,MACAiwE,EAAAjwE,EAAA,MACAkwE,EAAAlwE,EAAA,MACAmwE,EAAAnwE,EAAA,IAGAowE,EAAApwE,EAAA,MACAqwE,EAAArwE,EAAA,MACAswE,EAAAtwE,EAAA,MACAuwE,EAAAvwE,EAAA,MACAwwE,EAAAxwE,EAAA,MACAywE,EAAAzwE,EAAA,MAEA2O,EAAA3O,EAAA,MACA0wE,EAAA1wE,EAAA,MACA2wE,EAAA3wE,EAAA,MACA8O,EAAA9O,EAAA,MACAE,EAAAF,EAAA,MAGA,IAAI4wE,GAA2B,EAgB/B,MAAA5hE,UAA2C9O,EAAAK,WAmCzC,YAAW8C,GAOT,OANKvC,KAAK+vE,eACR/vE,KAAK+vE,aAAe/vE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACvCtP,KAAKgb,UAAUzM,MAAM5D,IACnB3K,KAAK+vE,cAAc9+D,KAAKtG,EAAG1F,aAGxBjF,KAAK+vE,aAAaxhE,KAC3B,CAEA,QAAWtG,GAAiB,OAAOjI,KAAK8R,eAAe7J,IAAM,CAC7D,QAAWlH,GAAiB,OAAOf,KAAK8R,eAAe/Q,IAAM,CAC7D,WAAWyS,GAAwB,OAAOxT,KAAK8R,eAAe0B,OAAS,CACvE,WAAWtK,GAAwC,OAAOlJ,KAAKoK,eAAelB,OAAS,CACvF,WAAWA,CAAQA,GACjB,IAAK,MAAMjG,KAAOiG,EAChBlJ,KAAKoK,eAAelB,QAAQjG,GAAOiG,EAAQjG,EAE/C,CAEA,WAAAvD,CACEwJ,GAEAnJ,QA5CMC,KAAAgwE,2BAA6BhwE,KAAK0B,UAAU,IAAItC,EAAA0P,mBAEvC9O,KAAAiwE,UAAYjwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAiiC,SAAWjiC,KAAKiwE,UAAU1hE,MACzBvO,KAAAkwE,QAAUlwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC9BtP,KAAAkiC,OAASliC,KAAKkwE,QAAQ3hE,MAC5BvO,KAAAmwE,YAAcnwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC3BtP,KAAA2C,WAAa3C,KAAKmwE,YAAY5hE,MAC3BvO,KAAAkZ,UAAYlZ,KAAK0B,UAAU,IAAIsM,EAAAsB,SAClCtP,KAAAmC,SAAWnC,KAAKkZ,UAAU3K,MACzBvO,KAAAowE,UAAYpwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAiC,SAAWjC,KAAKowE,UAAU7hE,MACvBvO,KAAAqwE,eAAiBrwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACvCtP,KAAAmiC,cAAgBniC,KAAKqwE,eAAe9hE,MAO1CvO,KAAAgb,UAAYhb,KAAK0B,UAAU,IAAIsM,EAAAsB,SA2BvCtP,KAAKkQ,sBAAwB,IAAIg/D,EAAAoB,qBACjCtwE,KAAKoK,eAAiBpK,KAAK0B,UAAU,IAAI2tE,EAAAkB,eAAernE,IACxDlJ,KAAKkQ,sBAAsBG,WAAWhR,EAAA0tB,gBAAiB/sB,KAAKoK,gBAC5DpK,KAAK8W,YAAc9W,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAeg/D,EAAAqB,aAC5ExwE,KAAKkQ,sBAAsBG,WAAWhR,EAAAu/D,YAAa5+D,KAAK8W,aACxD9W,KAAK8R,eAAiB9R,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAei/D,EAAAqB,gBAC/EzwE,KAAKkQ,sBAAsBG,WAAWhR,EAAAyqB,eAAgB9pB,KAAK8R,gBAC3D9R,KAAKmK,YAAcnK,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAem/D,EAAAoB,cAC5E1wE,KAAKkQ,sBAAsBG,WAAWhR,EAAAszB,aAAc3yB,KAAKmK,aACzDnK,KAAKob,kBAAoBpb,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAeo/D,EAAAoB,oBAClF3wE,KAAKkQ,sBAAsBG,WAAWhR,EAAAuzB,mBAAoB5yB,KAAKob,mBAC/Dpb,KAAK4wE,eAAiB5wE,KAAK0B,UAAU1B,KAAKkQ,sBAAsBC,eAAes/D,EAAAoB,iBAC/E7wE,KAAK4wE,eAAejzD,SAAS,IAAI6xD,EAAAsB,WACjC9wE,KAAKkQ,sBAAsBG,WAAWhR,EAAA0xE,gBAAiB/wE,KAAK4wE,gBAC5D5wE,KAAKgxE,gBAAkBhxE,KAAKkQ,sBAAsBC,eAAeu/D,EAAAuB,gBACjEjxE,KAAKkQ,sBAAsBG,WAAWhR,EAAA6xE,gBAAiBlxE,KAAKgxE,iBAC5DhxE,KAAKmqB,gBAAkBnqB,KAAKkQ,sBAAsBC,eAAe0/D,EAAAsB,gBACjEnxE,KAAKkQ,sBAAsBG,WAAWhR,EAAA2tB,gBAAiBhtB,KAAKmqB,iBAI5DnqB,KAAK+Q,cAAgB/Q,KAAK0B,UAAU,IAAImM,EAAAujE,aAAapxE,KAAK8R,eAAgB9R,KAAKgxE,gBAAiBhxE,KAAKmK,YAAanK,KAAK8W,YAAa9W,KAAKoK,eAAgBpK,KAAKmqB,gBAAiBnqB,KAAKob,kBAAmBpb,KAAK4wE,iBAC5M5wE,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK+Q,cAAcpO,WAAY3C,KAAKmwE,cAGtEnwE,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAK8R,eAAe7P,SAAUjC,KAAKowE,YACrEpwE,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAKmK,YAAY+3B,OAAQliC,KAAKkwE,UAChElwE,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAKmK,YAAY83B,SAAUjiC,KAAKiwE,YAClEjwE,KAAK0B,UAAU1B,KAAKmK,YAAYknE,wBAAwB,IAAMrxE,KAAK6c,gBAAe,KAClF7c,KAAK0B,UAAU1B,KAAKmK,YAAY64D,YAAY,IAAOhjE,KAAKsxE,aAAaC,oBACrEvxE,KAAK0B,UAAU1B,KAAKoK,eAAeumB,uBAAuB,CAAC,cAAe,IAAM3wB,KAAKwxE,kCACrFxxE,KAAK0B,UAAU1B,KAAK8R,eAAevP,SAAS,KAC1CvC,KAAKgb,UAAU/J,KAAK,CAAEhM,SAAUjF,KAAK8R,eAAe3N,OAAOK,QAC3DxE,KAAK+Q,cAAc0gE,eAAezxE,KAAK8R,eAAe3N,OAAO6tB,UAAWhyB,KAAK8R,eAAe3N,OAAOutE,iBAGrG1xE,KAAKsxE,aAAetxE,KAAK0B,UAAU,IAAIkuE,EAAA+B,YAAY,CAAC10D,EAAM20D,IAAkB5xE,KAAK+Q,cAAc8gE,MAAM50D,EAAM20D,KAC3G5xE,KAAK0B,UAAUsM,EAAA4D,WAAWC,QAAQ7R,KAAKsxE,aAAanvC,cAAeniC,KAAKqwE,gBAC1E,CAEO,KAAAnsC,CAAMjnB,EAA2BqN,GACtCtqB,KAAKsxE,aAAaptC,MAAMjnB,EAAMqN,EAChC,CAWO,SAAAwnD,CAAU70D,EAA2B80D,GACtC/xE,KAAK8W,YAAY2mD,UAAYp+D,EAAA2yE,aAAaC,OAASnC,IACrD9vE,KAAK8W,YAAY/O,KAAK,qDACtB+nE,GAA2B,GAE7B9vE,KAAKsxE,aAAaQ,UAAU70D,EAAM80D,EACpC,CAEO,KAAAvxD,CAAMvD,EAAc8mB,GAAwB,GACjD/jC,KAAKmK,YAAYK,iBAAiByS,EAAM8mB,EAC1C,CAEO,MAAA5qB,CAAOtE,EAAWV,GACnBrM,MAAM+M,IAAM/M,MAAMqM,KAItBU,EAAIF,KAAKkZ,IAAIhZ,EAAC,GACdV,EAAIQ,KAAKkZ,IAAI1Z,EAAC,GAIdnU,KAAKsxE,aAAaY,YAElBlyE,KAAK8R,eAAeqH,OAAOtE,EAAGV,GAChC,CAOO,MAAAg+D,CAAOC,EAA2BlmD,GAAqB,GAC5DlsB,KAAK8R,eAAeqgE,OAAOC,EAAWlmD,EACxC,CASO,WAAApmB,CAAY2W,EAAc/B,GAC/B1a,KAAK8R,eAAehM,YAAY2W,EAAM/B,EACxC,CAEO,WAAAgC,CAAYC,GACjB3c,KAAK8F,YAAY6W,GAAa3c,KAAKe,KAAO,GAC5C,CAEO,WAAA6b,GACL5c,KAAK8F,aAAa9F,KAAK8R,eAAe3N,OAAOK,MAC/C,CAEO,cAAAqY,CAAeC,GACpB9c,KAAK8F,YAAY9F,KAAK8R,eAAe3N,OAAOqQ,MAAQxU,KAAK8R,eAAe3N,OAAOK,MACjF,CAEO,YAAAuY,CAAaxY,GAClB,MAAMyY,EAAezY,EAAOvE,KAAK8R,eAAe3N,OAAOK,MAClC,IAAjBwY,GACFhd,KAAK8F,YAAYkX,EAErB,CAGO,kBAAAq1D,CAAmBl4C,EAAyB7P,GACjD,OAAOtqB,KAAK+Q,cAAcshE,mBAAmBl4C,EAAI7P,EACnD,CAGO,kBAAAgoD,CAAmBn4C,EAAyB7P,GACjD,OAAOtqB,KAAK+Q,cAAcuhE,mBAAmBn4C,EAAI7P,EACnD,CAGO,kBAAAioD,CAAmBp4C,EAAyB7P,GACjD,OAAOtqB,KAAK+Q,cAAcwhE,mBAAmBp4C,EAAI7P,EACnD,CAGO,kBAAAkoD,CAAmBpgE,EAAekY,GACvC,OAAOtqB,KAAK+Q,cAAcyhE,mBAAmBpgE,EAAOkY,EACtD,CAGO,kBAAAmoD,CAAmBt4C,EAAyB7P,GACjD,OAAOtqB,KAAK+Q,cAAc0hE,mBAAmBt4C,EAAI7P,EACnD,CAEU,MAAAta,GACRhQ,KAAKwxE,+BACP,CAEO,KAAAlgE,GACLtR,KAAK+Q,cAAcO,QACnBtR,KAAK8R,eAAeR,QACpBtR,KAAKgxE,gBAAgB1/D,QACrBtR,KAAKmK,YAAYmH,QACjBtR,KAAKob,kBAAkB9J,OACzB,CAGQ,6BAAAkgE,GACN,IAAI/mE,GAAQ,EACZ,MAAMioE,EAAa1yE,KAAKoK,eAAeE,WAAWooE,WAC9CA,QAAqC9tE,IAAvB8tE,EAAWC,cAAoD/tE,IAA3B8tE,EAAWE,cAC/DnoE,KAAkC,WAAvBioE,EAAWC,SAAwBD,EAAWE,YAAc,QAErEnoE,EACFzK,KAAK6yE,mCAEL7yE,KAAKgwE,2BAA2B3jE,OAEpC,CAEU,gCAAAwmE,GACR,IAAK7yE,KAAKgwE,2BAA2BvlE,MAAO,CAC1C,MAAMqoE,EAA6B,GACnCA,EAAY7uE,KAAKjE,KAAK2C,WAAWgtE,EAAAoD,8BAA8BlxE,KAAK,KAAM7B,KAAK8R,kBAC/EghE,EAAY7uE,KAAKjE,KAAKuyE,mBAAmB,CAAES,MAAO,KAAO,MACvD,EAAArD,EAAAoD,+BAA8B/yE,KAAK8R,iBAC5B,KAET9R,KAAKgwE,2BAA2BvlE,OAAQ,EAAArL,EAAAqE,cAAa,KACnD,IAAK,MAAMgqC,KAAKqlC,EACdrlC,EAAEp0B,WAGR,CACF,+GCzSF,MAAAja,EAAAF,EAAA,MAyEA,IAAiB0S,YAnEjB,iBAAAlS,GACUM,KAAA8+D,WAAqD,GACrD9+D,KAAAizE,WAAY,CA+DtB,CA5DE,SAAW1kE,GACT,OAAIvO,KAAKkzE,SAGTlzE,KAAKkzE,OAAS,CAACpe,EAAyBqe,EAAgBL,KACtD,GAAI9yE,KAAKizE,UACP,OAAO,EAAA7zE,EAAAqE,cAAa,QAGtB,MAAMw9D,EAAQ,CAAEnN,GAAIgB,EAAUqe,YAC9BnzE,KAAK8+D,WAAW76D,KAAKg9D,GAErB,MAAMjiD,GAAS,EAAA5f,EAAAqE,cAAa,KAC1B,MAAM2vE,EAAMpzE,KAAK8+D,WAAW3D,QAAQ8F,IACvB,IAATmS,GACFpzE,KAAK8+D,WAAWh3C,OAAOsrD,EAAK,KAYhC,OARIN,IACEvH,MAAM8H,QAAQP,GAChBA,EAAY7uE,KAAK+a,GAEjB8zD,EAAYnyE,IAAIqe,IAIbA,IAzBAhf,KAAKkzE,MA4BhB,CAEO,IAAAjiE,CAAK1C,GACV,IAAIvO,KAAKizE,UAGT,OAAQjzE,KAAK8+D,WAAWv9D,QACtB,KAAK,EAAG,OACR,KAAK,EAAG,CACN,MAAMuyD,GAAEA,EAAEqf,SAAEA,GAAanzE,KAAK8+D,WAAW,GAEzC,YADAhL,EAAGwf,KAAKH,EAAU5kE,EAEpB,CACA,QAAS,CAEP,MAAMglE,EAAYvzE,KAAK8+D,WAAWv3D,QAClC,IAAK,MAAMusD,GAAEA,EAAEqf,SAAEA,KAAcI,EAC7Bzf,EAAGwf,KAAKH,EAAU5kE,EAEtB,EAEJ,CAEO,OAAA8K,GACDrZ,KAAKizE,YAGTjzE,KAAKizE,WAAY,EACjBjzE,KAAK8+D,WAAWv9D,OAAS,EAC3B,GAGF,SAAiBqQ,GACCA,EAAAC,QAAhB,SAA2B6xC,EAAiBL,GAC1C,OAAOK,EAAKviD,GAAKkiD,EAAGpyC,KAAK9P,GAC3B,EAEgByQ,EAAAuV,IAAhB,SAA0B5Y,EAAkB4Y,GAC1C,MAAO,CAAC2tC,EAAyBqe,EAAgBL,IACxCvkE,EAAMzP,GAAKg2D,EAASwe,KAAKH,EAAUhsD,EAAIroB,SAAK8F,EAAWkuE,EAElE,EAIgBlhE,EAAAmJ,IAAhB,YAA0BuhD,GACxB,MAAO,CAACxH,EAAyBqe,EAAgBL,KAC/C,MAAM/T,EAAQ,IAAI3/D,EAAAy8C,gBAClB,IAAK,MAAMttC,KAAS+tD,EAClByC,EAAMp+D,IAAI4N,EAAMpN,GAAK2zD,EAASwe,KAAKH,EAAUhyE,KAS/C,OAPI2xE,IACEvH,MAAM8H,QAAQP,GAChBA,EAAY7uE,KAAK86D,GAEjB+T,EAAYnyE,IAAIo+D,IAGbA,EAEX,EAIgBntD,EAAAqf,gBAAhB,SAAmC1iB,EAAkBkP,EAAqC+1D,GAExF,OADA/1D,EAAQ+1D,GACDjlE,EAAMpN,GAAKsc,EAAQtc,GAC5B,CACD,CApCD,CAAiByQ,IAAUnT,EAAAmT,WAAVA,EAAU,+iBCxE3B,MAAA6hE,EAAAv0E,EAAA,MACAw0E,EAAAx0E,EAAA,MACAE,EAAAF,EAAA,MACAy0E,EAAAz0E,EAAA,KACAwO,EAAAxO,EAAA,MAEAylC,EAAAzlC,EAAA,MACA+qB,EAAA/qB,EAAA,MACAmsC,EAAAnsC,EAAA,MACAG,EAAAH,EAAA,MACAuwE,EAAAvwE,EAAA,MACA00E,EAAA10E,EAAA,MACA20E,EAAA30E,EAAA,MACA40E,EAAA50E,EAAA,MACAyO,EAAAzO,EAAA,MACA8O,EAAA9O,EAAA,MACA60E,EAAA70E,EAAA,MAKM80E,EAAoC,CAAE,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,GAsBzF,SAASC,EAAoBxlB,EAAWna,GACtC,GAAIma,EAAI,GACN,OAAOna,EAAK4/B,cAAe,EAE7B,OAAQzlB,GACN,KAAK,EAAG,QAASna,EAAK6/B,WACtB,KAAK,EAAG,QAAS7/B,EAAK8/B,YACtB,KAAK,EAAG,QAAS9/B,EAAK+/B,eACtB,KAAK,EAAG,QAAS//B,EAAKggC,iBACtB,KAAK,EAAG,QAAShgC,EAAKigC,SACtB,KAAK,EAAG,QAASjgC,EAAKkgC,SACtB,KAAK,EAAG,QAASlgC,EAAKmgC,WACtB,KAAK,EAAG,QAASngC,EAAKogC,gBACtB,KAAK,EAAG,QAASpgC,EAAKqgC,YACtB,KAAK,GAAI,QAASrgC,EAAKsgC,cACvB,KAAK,GAAI,QAAStgC,EAAKugC,YACvB,KAAK,GAAI,QAASvgC,EAAKwgC,eACvB,KAAK,GAAI,QAASxgC,EAAKygC,iBACvB,KAAK,GAAI,QAASzgC,EAAK0gC,oBACvB,KAAK,GAAI,QAAS1gC,EAAK2gC,kBACvB,KAAK,GAAI,QAAS3gC,EAAK4gC,gBACvB,KAAK,GAAI,QAAS5gC,EAAK6gC,mBACvB,KAAK,GAAI,QAAS7gC,EAAK8gC,aACvB,KAAK,GAAI,QAAS9gC,EAAK+gC,YACvB,KAAK,GAAI,QAAS/gC,EAAKghC,UACvB,KAAK,GAAI,QAAShhC,EAAKihC,SACvB,KAAK,GAAI,QAASjhC,EAAK4/B,YAEzB,OAAO,CACT,CAEA,IAAYnzD,GAAZ,SAAYA,GACVA,EAAAA,EAAA,6CACAA,EAAAA,EAAA,8CACD,CAHD,CAAYA,IAAwBtiB,EAAAsiB,yBAAxBA,EAAwB,KAMpC,IAAIy0D,EAAQ,EASZ,MAAApE,UAAkChyE,EAAAK,WAWzB,WAAAg2E,GAAgC,OAAOz1E,KAAK01E,YAAc,CA2CjE,WAAAh2E,CACmBoS,EACAk/D,EACA5hD,EACAtY,EACAoT,EACAC,EACAqxC,EACAma,EACAtzC,EAAiC,IAAIqxC,EAAAkC,sBAEtD71E,QAViBC,KAAA8R,eAAAA,EACA9R,KAAAgxE,gBAAAA,EACAhxE,KAAAovB,aAAAA,EACApvB,KAAA8W,YAAAA,EACA9W,KAAAkqB,gBAAAA,EACAlqB,KAAAmqB,gBAAAA,EACAnqB,KAAAw7D,mBAAAA,EACAx7D,KAAA21E,gBAAAA,EACA31E,KAAAqiC,QAAAA,EA9DXriC,KAAA61E,aAA4B,IAAIC,YAAY,MAC5C91E,KAAA+1E,eAAgC,IAAIpC,EAAAqC,cACpCh2E,KAAAi2E,aAA4B,IAAItC,EAAAuC,YAChCl2E,KAAAm2E,aAAe,GACfn2E,KAAAo2E,UAAY,GAEVp2E,KAAAq2E,kBAA8B,GAC9Br2E,KAAAs2E,eAA2B,GAE7Bt2E,KAAA01E,aAA+BhoE,EAAAmT,kBAAkB04B,QAEjDv5C,KAAAu2E,uBAAyC7oE,EAAAmT,kBAAkB04B,QAIlDv5C,KAAAw2E,eAAiBx2E,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAAgR,cAAgBhR,KAAKw2E,eAAejoE,MACnCvO,KAAAy2E,sBAAwBz2E,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC5CtP,KAAAkR,qBAAuBlR,KAAKy2E,sBAAsBloE,MACjDvO,KAAA02E,gBAAkB12E,KAAK0B,UAAU,IAAIsM,EAAAsB,SACtCtP,KAAAqR,eAAiBrR,KAAK02E,gBAAgBnoE,MACrCvO,KAAA22E,oBAAsB32E,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC1CtP,KAAAmR,mBAAqBnR,KAAK22E,oBAAoBpoE,MAC7CvO,KAAA42E,wBAA0B52E,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC9CtP,KAAA62E,uBAAyB72E,KAAK42E,wBAAwBroE,MACrDvO,KAAA82E,+BAAiC92E,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrDtP,KAAAuR,8BAAgCvR,KAAK82E,+BAA+BvoE,MAEnEvO,KAAA+2E,YAAc/2E,KAAK0B,UAAU,IAAIsM,EAAAsB,SAClCtP,KAAAwC,WAAaxC,KAAK+2E,YAAYxoE,MAC7BvO,KAAAg3E,WAAah3E,KAAK0B,UAAU,IAAIsM,EAAAsB,SACjCtP,KAAA4C,UAAY5C,KAAKg3E,WAAWzoE,MAC3BvO,KAAAqP,cAAgBrP,KAAK0B,UAAU,IAAIsM,EAAAsB,SACpCtP,KAAAuP,aAAevP,KAAKqP,cAAcd,MACjCvO,KAAAmwE,YAAcnwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAClCtP,KAAA2C,WAAa3C,KAAKmwE,YAAY5hE,MAC7BvO,KAAAgb,UAAYhb,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAuC,SAAWvC,KAAKgb,UAAUzM,MACzBvO,KAAA2P,eAAiB3P,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAA4P,cAAgB5P,KAAK2P,eAAepB,MACnCvO,KAAAi3E,SAAWj3E,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC/BtP,KAAA0R,QAAU1R,KAAKi3E,SAAS1oE,MACvBvO,KAAAk3E,2BAA6Bl3E,KAAK0B,UAAU,IAAIsM,EAAAsB,SACjDtP,KAAA0Y,0BAA4B1Y,KAAKk3E,2BAA2B3oE,MAEpEvO,KAAAm3E,YAA2B,CACjCC,QAAQ,EACRC,aAAc,EACdC,aAAc,EACdC,cAAe,EACftyE,SAAU,GAq7FJjF,KAAAw3E,eAAiB,cAt6FvBx3E,KAAK0B,UAAU1B,KAAKqiC,SACpBriC,KAAKy3E,iBAAmB,IAAIC,EAAgB13E,KAAK8R,gBAGjD9R,KAAK23E,cAAgB33E,KAAK8R,eAAe3N,OACzCnE,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiBtwB,GAAKnB,KAAK23E,cAAgBx2E,EAAEwkE,eAKxF3lE,KAAKqiC,QAAQu1C,sBAAsB,CAACxlE,EAAOylE,KACzC73E,KAAK8W,YAAYC,MAAM,qBAAsB,CAAEk6C,WAAYjxD,KAAKqiC,QAAQy1C,cAAc1lE,GAAQylE,OAAQA,EAAOE,cAE/G/3E,KAAKqiC,QAAQ21C,sBAAsB5lE,IACjCpS,KAAK8W,YAAYC,MAAM,qBAAsB,CAAEk6C,WAAYjxD,KAAKqiC,QAAQy1C,cAAc1lE,OAExFpS,KAAKqiC,QAAQ41C,0BAA0Bj9C,IACrCh7B,KAAK8W,YAAYC,MAAM,yBAA0B,CAAEikB,WAErDh7B,KAAKqiC,QAAQ61C,sBAAsB,CAACjnB,EAAY4L,EAAQ5/C,KACtDjd,KAAK8W,YAAYC,MAAM,qBAAsB,CAAEk6C,aAAY4L,SAAQ5/C,WAErEjd,KAAKqiC,QAAQ81C,sBAAsB,CAAC/lE,EAAOyqD,EAAQub,KAClC,SAAXvb,IACFub,EAAUA,EAAQL,WAEpB/3E,KAAK8W,YAAYC,MAAM,qBAAsB,CAAEk6C,WAAYjxD,KAAKqiC,QAAQy1C,cAAc1lE,GAAQyqD,SAAQub,cAExGp4E,KAAKqiC,QAAQg2C,sBAAsB,CAACjmE,EAAOyqD,EAAQub,KACjDp4E,KAAK8W,YAAYC,MAAM,qBAAsB,CAAEk6C,WAAYjxD,KAAKqiC,QAAQy1C,cAAc1lE,GAAQyqD,SAAQub,cAMxGp4E,KAAKqiC,QAAQi2C,gBAAgB,CAACr7D,EAAM5a,EAAOC,IAAQtC,KAAKu4E,MAAMt7D,EAAM5a,EAAOC,IAK3EtC,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKw4E,YAAYX,IAC3E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAKq9C,WAAWw6B,IAC9F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK04E,SAASb,IACxE73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAK24E,YAAYd,IAC/F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK44E,WAAWf,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK64E,cAAchB,IAC7E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK84E,eAAejB,IAC9E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK+4E,eAAelB,IAC9E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKg5E,oBAAoBnB,IACnF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKi5E,mBAAmBpB,IAClF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKk5E,eAAerB,IAC9E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKm5E,iBAAiBtB,IAChF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKo5E,eAAevB,GAAQ,IACtF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAKo5E,eAAevB,GAAQ,IACnG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKs5E,YAAYzB,GAAQ,IACnF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAKs5E,YAAYzB,GAAQ,IAChG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKu5E,YAAY1B,IAC3E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKw5E,YAAY3B,IAC3E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKy5E,YAAY5B,IAC3E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK05E,SAAS7B,IACxE73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK25E,WAAW9B,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK45E,WAAW/B,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK65E,kBAAkBhC,IACjF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK25E,WAAW9B,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK85E,gBAAgBjC,IAC/E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK+5E,kBAAkBlC,IACjF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKg6E,yBAAyBnC,IACxF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKi6E,4BAA4BpC,IAC3F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAKk6E,8BAA8BrC,IAC1G73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKm6E,gBAAgBtC,IAC/E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKo6E,kBAAkBvC,IACjF73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKq6E,WAAWxC,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKs6E,SAASzC,IACxE73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKu6E,QAAQ1C,IACvE73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAKw6E,eAAe3C,IAC3F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKy6E,UAAU5C,IACzE73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK06E,iBAAiB7C,IAC7F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK26E,eAAe9C,IAC9E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAK46E,aAAa/C,IAC5E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK66E,oBAAoBhD,IAChG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAK86E,UAAUjD,IAC7F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK+6E,cAAclD,IAC1F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAKg7E,eAAenD,IAClG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKi7E,gBAAgBpD,IAC/E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKk7E,WAAWrD,IAC1E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKm7E,cAActD,IAC7E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAES,MAAO,KAAO6E,GAAU73E,KAAKo7E,cAAcvD,IAC7E73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAMzF,MAAO,KAAO6E,GAAU73E,KAAKq7E,cAAcxD,IAClG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAMzF,MAAO,KAAO6E,GAAU73E,KAAKs7E,cAAczD,IAClG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAKu7E,gBAAgB1D,IACnG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAEkG,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAKw7E,YAAY3D,GAAQ,IACvG73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKZ,cAAe,IAAKzF,MAAO,KAAO6E,GAAU73E,KAAKw7E,YAAY3D,GAAQ,IAGpH73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAKy7E,iBAAiB5D,IAC7F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK07E,mBAAmB7D,IAC/F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK27E,kBAAkB9D,IAC9F73E,KAAKqiC,QAAQkwC,mBAAmB,CAAE8G,OAAQ,IAAKrG,MAAO,KAAO6E,GAAU73E,KAAK47E,iBAAiB/D,IAK7F73E,KAAKqiC,QAAQw5C,kBAAiB,IAAS,IAAM77E,KAAK87E,QAClD97E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAK+7E,YACjD/7E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAK+7E,YACjD/7E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAK+7E,YACjD/7E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAKg8E,kBACjDh8E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAKi8E,aACjDj8E,KAAKqiC,QAAQw5C,kBAAiB,KAAQ,IAAM77E,KAAKk8E,OACjDl8E,KAAKqiC,QAAQw5C,kBAAiB,IAAQ,IAAM77E,KAAKm8E,YACjDn8E,KAAKqiC,QAAQw5C,kBAAiB,IAAQ,IAAM77E,KAAKo8E,WAGjDp8E,KAAKqiC,QAAQw5C,kBAAiB,IAAS,IAAM77E,KAAKqS,SAClDrS,KAAKqiC,QAAQw5C,kBAAiB,IAAS,IAAM77E,KAAKusB,YAClDvsB,KAAKqiC,QAAQw5C,kBAAiB,IAAS,IAAM77E,KAAKq8E,UAMlDr8E,KAAKqiC,QAAQmwC,mBAAmB,EAAG,IAAIoB,EAAA0I,WAAWr/D,IAAUjd,KAAKu8E,SAASt/D,GAAOjd,KAAKw8E,YAAYv/D,IAAc,KAEhHjd,KAAKqiC,QAAQmwC,mBAAmB,EAAG,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAKw8E,YAAYv/D,KAE3Ejd,KAAKqiC,QAAQmwC,mBAAmB,EAAG,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAKu8E,SAASt/D,KAGxEjd,KAAKqiC,QAAQmwC,mBAAmB,EAAG,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAKy8E,wBAAwBx/D,KAKvFjd,KAAKqiC,QAAQmwC,mBAAmB,EAAG,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK08E,aAAaz/D,KAE5Ejd,KAAKqiC,QAAQmwC,mBAAmB,GAAI,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK28E,mBAAmB1/D,KAEnFjd,KAAKqiC,QAAQmwC,mBAAmB,GAAI,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK48E,mBAAmB3/D,KAEnFjd,KAAKqiC,QAAQmwC,mBAAmB,GAAI,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK68E,uBAAuB5/D,KAavFjd,KAAKqiC,QAAQmwC,mBAAmB,IAAK,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK88E,oBAAoB7/D,KAIrFjd,KAAKqiC,QAAQmwC,mBAAmB,IAAK,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAK+8E,eAAe9/D,KAEhFjd,KAAKqiC,QAAQmwC,mBAAmB,IAAK,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAKg9E,eAAe//D,KAEhFjd,KAAKqiC,QAAQmwC,mBAAmB,IAAK,IAAIoB,EAAA0I,WAAWr/D,GAAQjd,KAAKi9E,mBAAmBhgE,KAYpFjd,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKk7E,cAC3Dl7E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKo7E,iBAC3Dp7E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKqS,SAC3DrS,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKusB,YAC3DvsB,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKq8E,UAC3Dr8E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKk9E,gBAC3Dl9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKm9E,yBAC3Dn9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKo9E,qBAC3Dp9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKq9E,aAC3Dr9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKs9E,UAAU,IACrEt9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKs9E,UAAU,IACrEt9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKs9E,UAAU,IACrEt9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKs9E,UAAU,IACrEt9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEW,MAAO,KAAO,IAAMhzE,KAAKs9E,UAAU,IACrEt9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAO,KAAO,IAAMhzE,KAAKu9E,wBAC/Ev9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAO,KAAO,IAAMhzE,KAAKu9E,wBAC/E,IAAK,MAAMC,KAAQ/J,EAAAgK,SACjBz9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IACpGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAOwK,GAAQ,IAAMx9E,KAAK09E,cAAc,IAAMF,IAEtGx9E,KAAKqiC,QAAQgwC,mBAAmB,CAAEoG,cAAe,IAAKzF,MAAO,KAAO,IAAMhzE,KAAK29E,0BAK/E39E,KAAKqiC,QAAQu7C,gBAAiB77D,IAC5B/hB,KAAK8W,YAAYpQ,MAAM,kBAAmBqb,GACnCA,IAMT/hB,KAAKqiC,QAAQiwC,mBAAmB,CAAEmG,cAAe,IAAKzF,MAAO,KAAO,IAAIa,EAAAgK,WAAW,CAAC5gE,EAAM46D,IAAW73E,KAAK89E,oBAAoB7gE,EAAM46D,IACtI,CAKQ,cAAAkG,CAAe1G,EAAsBC,EAAsBC,EAAuBtyE,GACxFjF,KAAKm3E,YAAYC,QAAS,EAC1Bp3E,KAAKm3E,YAAYE,aAAeA,EAChCr3E,KAAKm3E,YAAYG,aAAeA,EAChCt3E,KAAKm3E,YAAYI,cAAgBA,EACjCv3E,KAAKm3E,YAAYlyE,SAAWA,CAC9B,CAEQ,sBAAA+4E,CAAuBC,GAE7B,GAAIj+E,KAAK8W,YAAY2mD,UAAYp+D,EAAA2yE,aAAaC,KAAM,CAClD,IAAIiM,EACJ,MAAMC,EAAc,IAAI7T,QAAe,CAAC8T,EAAMC,KAC5CH,EAAczvD,WAAW,IAAM4vD,EAAI,iBAAgB,OAErD/T,QAAQgU,KAAK,CAACL,EAAGE,IACdI,KAAK,UACgB35E,IAAhBs5E,GACF/vD,aAAa+vD,IAEdM,IAID,QAHoB55E,IAAhBs5E,GACF/vD,aAAa+vD,GAEH,kBAARM,EACF,MAAMA,EAER/3E,QAAQsB,KAAK,oDAEnB,CACF,CAEQ,iBAAA02E,GACN,OAAOz+E,KAAK01E,aAAa1qD,SAASC,KACpC,CAeO,KAAA4mD,CAAM50D,EAA2B20D,GACtC,IAAI5yD,EACAq4D,EAAer3E,KAAK23E,cAAc9iE,EAClCyiE,EAAet3E,KAAK23E,cAAcxjE,EAClC9R,EAAQ,EACZ,MAAMq8E,EAAY1+E,KAAKm3E,YAAYC,OAEnC,GAAIsH,EAAW,CAEb,GAAI1/D,EAAShf,KAAKqiC,QAAQwvC,MAAM7xE,KAAK61E,aAAc71E,KAAKm3E,YAAYI,cAAe3F,GAEjF,OADA5xE,KAAKg+E,uBAAuBh/D,GACrBA,EAETq4D,EAAer3E,KAAKm3E,YAAYE,aAChCC,EAAet3E,KAAKm3E,YAAYG,aAChCt3E,KAAKm3E,YAAYC,QAAS,EACtBn6D,EAAK1b,OAAM,SACbc,EAAQrC,KAAKm3E,YAAYlyE,SAAQ,OAErC,CA2BA,GAxBIjF,KAAK8W,YAAY2mD,UAAYp+D,EAAA2yE,aAAa2M,OAC5C3+E,KAAK8W,YAAYC,MAAM,iBAAgC,iBAATkG,EAAoB,KAAKA,KAAU,KAAKsuD,MAAMqT,UAAUz3D,IAAImsD,KAAKr2D,EAAM9b,GAAKif,OAAOC,aAAalf,IAAIqwB,KAAK,SAErJxxB,KAAK8W,YAAY2mD,WAAap+D,EAAA2yE,aAAa6M,OAC7C7+E,KAAK8W,YAAYgoE,MAAM,uBAAwC,iBAAT7hE,EAClDA,EAAK8hE,MAAM,IAAI53D,IAAIhmB,GAAKA,EAAEse,WAAW,IACrCxC,GAKFjd,KAAK61E,aAAat0E,OAAS0b,EAAK1b,QAC9BvB,KAAK61E,aAAat0E,OAAM,SAC1BvB,KAAK61E,aAAe,IAAIC,YAAYnhE,KAAKC,IAAIqI,EAAK1b,OAAM,UAMvDm9E,GACH1+E,KAAKy3E,iBAAiBuH,aAIpB/hE,EAAK1b,OAAM,OACb,IAAK,IAAIzC,EAAIuD,EAAOvD,EAAIme,EAAK1b,OAAQzC,GAAC,OAAsC,CAC1E,MAAMwD,EAAMxD,EAAC,OAAsCme,EAAK1b,OAASzC,EAAC,OAAsCme,EAAK1b,OACvGuvD,EAAuB,iBAAT7zC,EAChBjd,KAAK+1E,eAAekJ,OAAOhiE,EAAK+c,UAAUl7B,EAAGwD,GAAMtC,KAAK61E,cACxD71E,KAAKi2E,aAAagJ,OAAOhiE,EAAKiiE,SAASpgF,EAAGwD,GAAMtC,KAAK61E,cACzD,GAAI72D,EAAShf,KAAKqiC,QAAQwvC,MAAM7xE,KAAK61E,aAAc/kB,GAGjD,OAFA9wD,KAAK+9E,eAAe1G,EAAcC,EAAcxmB,EAAKhyD,GACrDkB,KAAKg+E,uBAAuBh/D,GACrBA,CAEX,MAEA,IAAK0/D,EAAW,CACd,MAAM5tB,EAAuB,iBAAT7zC,EAChBjd,KAAK+1E,eAAekJ,OAAOhiE,EAAMjd,KAAK61E,cACtC71E,KAAKi2E,aAAagJ,OAAOhiE,EAAMjd,KAAK61E,cACxC,GAAI72D,EAAShf,KAAKqiC,QAAQwvC,MAAM7xE,KAAK61E,aAAc/kB,GAGjD,OAFA9wD,KAAK+9E,eAAe1G,EAAcC,EAAcxmB,EAAK,GACrD9wD,KAAKg+E,uBAAuBh/D,GACrBA,CAEX,CAGEhf,KAAK23E,cAAc9iE,IAAMwiE,GAAgBr3E,KAAK23E,cAAcxjE,IAAMmjE,GACpEt3E,KAAKqP,cAAc4B,OAKrB,MAAMkuE,EAAcn/E,KAAKy3E,iBAAiBn1E,KAAOtC,KAAK8R,eAAe3N,OAAOqQ,MAAQxU,KAAK8R,eAAe3N,OAAOK,OACzG46E,EAAgBp/E,KAAKy3E,iBAAiBp1E,OAASrC,KAAK8R,eAAe3N,OAAOqQ,MAAQxU,KAAK8R,eAAe3N,OAAOK,OAC/G46E,EAAgBp/E,KAAK8R,eAAe/Q,MACtCf,KAAKy2E,sBAAsBxlE,KAAK,CAC9B5O,MAAOsS,KAAKC,IAAIwqE,EAAep/E,KAAK8R,eAAe/Q,KAAO,GAC1DuB,IAAKqS,KAAKC,IAAIuqE,EAAan/E,KAAK8R,eAAe/Q,KAAO,IAG5D,CAEO,KAAAw3E,CAAMt7D,EAAmB5a,EAAeC,GAC7C,IAAI04B,EACAqkD,EACJ,MAAMC,EAAUt/E,KAAKgxE,gBAAgBsO,QAC/B7jE,EAAmBzb,KAAKkqB,gBAAgB5f,WAAWmR,iBACnDxT,EAAOjI,KAAK8R,eAAe7J,KAC3B47B,EAAiB7jC,KAAKovB,aAAa/kB,gBAAgBy5B,WACnDX,EAAanjC,KAAKovB,aAAauT,MAAMQ,WACrCo8C,EAAUv/E,KAAK01E,aACrB,IAAI8J,EAAYx/E,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GAI3F,IAAKqrE,EACH,OAGFx/E,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,GAG/CnU,KAAK23E,cAAc9iE,GAAKvS,EAAMD,EAAQ,GAAsD,IAAjDm9E,EAAUzqE,SAAS/U,KAAK23E,cAAc9iE,EAAI,IACvF2qE,EAAUE,qBAAqB1/E,KAAK23E,cAAc9iE,EAAI,EAAG,EAAG,EAAG0qE,GAGjE,IAAII,EAAqB3/E,KAAKqiC,QAAQs9C,mBACtC,IAAK,IAAI90E,EAAMxI,EAAOwI,EAAMvI,IAAOuI,EAAK,CAKtC,GAJAmwB,EAAO/d,EAAKpS,GAIC,MAATmwB,EACF,SAMF,GAAIA,EAAO,KAAOskD,EAAS,CACzB,MAAMM,EAAKN,EAAQl/D,OAAOC,aAAa2a,IACnC4kD,IACF5kD,EAAO4kD,EAAGngE,WAAW,GAEzB,CAEA,MAAMogE,EAAc7/E,KAAK21E,gBAAgBmK,eAAe9kD,EAAM2kD,GAC9DN,EAAU5P,EAAAoB,eAAekP,aAAaF,GACtC,MAAMG,EAAavQ,EAAAoB,eAAeoP,kBAAkBJ,GAC9Cz9B,EAAW49B,EAAavQ,EAAAoB,eAAekP,aAAaJ,GAAsB,EAChFA,EAAqBE,EAEjBpkE,GACFzb,KAAK+2E,YAAY9lE,MAAK,EAAA0iE,EAAAuM,qBAAoBllD,IAE5C,MAAMpP,EAAS5rB,KAAKy+E,oBAQpB,GAPI7yD,GACF5rB,KAAKmqB,gBAAgBg2D,cAAcv0D,EAAQ5rB,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GAMvFnU,KAAK23E,cAAc9iE,EAAIwqE,EAAUj9B,EAAWn6C,EAG9C,GAAI47B,EAAgB,CAClB,MAAMu8C,EAASZ,EACf,IAAIa,EAASrgF,KAAK23E,cAAc9iE,EAAIutC,EAgBpC,GAfApiD,KAAK23E,cAAc9iE,EAAIutC,EACvBpiD,KAAK23E,cAAcxjE,IACfnU,KAAK23E,cAAcxjE,IAAMnU,KAAK23E,cAAcjG,aAAe,GAC7D1xE,KAAK23E,cAAcxjE,IACnBnU,KAAK8R,eAAeqgE,OAAOnyE,KAAKsgF,kBAAkB,KAE9CtgF,KAAK23E,cAAcxjE,GAAKnU,KAAK8R,eAAe/Q,OAC9Cf,KAAK23E,cAAcxjE,EAAInU,KAAK8R,eAAe/Q,KAAO,GAIpDf,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GAAI+X,WAAY,GAG7FszD,EAAYx/E,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,IAClFqrE,EACH,OASF,IAPIp9B,EAAW,GAAKo9B,aAAqB9xE,EAAA6yE,YAGvCf,EAAUgB,cAAcJ,EACtBC,EAAQ,EAAGj+B,GAAU,GAGlBi+B,EAASp4E,GACdm4E,EAAOV,qBAAqBW,IAAU,EAAG,EAAGd,EAEhD,MAEE,GADAv/E,KAAK23E,cAAc9iE,EAAI5M,EAAO,EACd,IAAZo3E,EAGF,SASN,GAAIW,GAAchgF,KAAK23E,cAAc9iE,EAAG,CACtC,MAAMhO,EAAS24E,EAAUzqE,SAAS/U,KAAK23E,cAAc9iE,EAAI,GAAK,EAAI,EAIlE2qE,EAAUiB,mBAAmBzgF,KAAK23E,cAAc9iE,EAAIhO,EAClDm0B,EAAMqkD,GACR,IAAK,IAAIj7B,EAAQi7B,EAAUj9B,IAAYgC,GAAS,GAC9Co7B,EAAUE,qBAAqB1/E,KAAK23E,cAAc9iE,IAAK,EAAG,EAAG0qE,GAE/D,QACF,CAoBA,GAjBIp8C,IAEFq8C,EAAUkB,YAAY1gF,KAAK23E,cAAc9iE,EAAGwqE,EAAUj9B,EAAUpiD,KAAK23E,cAAcgJ,YAAYpB,IAI1D,IAAjCC,EAAUzqE,SAAS9M,EAAO,IAC5Bu3E,EAAUE,qBAAqBz3E,EAAO,EAAG08B,EAAAi8C,eAAgBj8C,EAAAk8C,gBAAiBtB,IAK9EC,EAAUE,qBAAqB1/E,KAAK23E,cAAc9iE,IAAKmmB,EAAMqkD,EAASE,GAKlEF,EAAU,EACZ,OAASA,GAEPG,EAAUE,qBAAqB1/E,KAAK23E,cAAc9iE,IAAK,EAAG,EAAG0qE,EAGnE,CAEAv/E,KAAKqiC,QAAQs9C,mBAAqBA,EAG9B3/E,KAAK23E,cAAc9iE,EAAI5M,GAAQ3F,EAAMD,EAAQ,GAAkD,IAA7Cm9E,EAAUzqE,SAAS/U,KAAK23E,cAAc9iE,KAAa2qE,EAAU30D,WAAW7qB,KAAK23E,cAAc9iE,IAC/I2qE,EAAUE,qBAAqB1/E,KAAK23E,cAAc9iE,EAAG,EAAG,EAAG0qE,GAG7Dv/E,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,EACrD,CAKO,kBAAAo+D,CAAmBp4C,EAAyB7P,GACjD,MAAiB,MAAb6P,EAAG64C,OAAkB74C,EAAGk/C,QAAWl/C,EAAGs+C,cASnCz4E,KAAKqiC,QAAQkwC,mBAAmBp4C,EAAI7P,GAPlCtqB,KAAKqiC,QAAQkwC,mBAAmBp4C,EAAI09C,IACpC5D,EAAoB4D,EAAOA,OAAO,GAAI73E,KAAKkqB,gBAAgB5f,WAAW6wE,gBAGpE7wD,EAASutD,GAItB,CAKO,kBAAAvF,CAAmBn4C,EAAyB7P,GACjD,OAAOtqB,KAAKqiC,QAAQiwC,mBAAmBn4C,EAAI,IAAI05C,EAAAgK,WAAWvzD,GAC5D,CAKO,kBAAA+nD,CAAmBl4C,EAAyB7P,GACjD,OAAOtqB,KAAKqiC,QAAQgwC,mBAAmBl4C,EAAI7P,EAC7C,CAKO,kBAAAkoD,CAAmBpgE,EAAekY,GACvC,OAAOtqB,KAAKqiC,QAAQmwC,mBAAmBpgE,EAAO,IAAIwhE,EAAA0I,WAAWhyD,GAC/D,CAKO,kBAAAmoD,CAAmBt4C,EAAyB7P,GACjD,OAAOtqB,KAAKqiC,QAAQowC,mBAAmBt4C,EAAI,IAAI25C,EAAAgN,WAAWx2D,GAC5D,CAUO,IAAAwxD,GAEL,OADA97E,KAAKw2E,eAAevlE,QACb,CACT,CAYO,QAAA8qE,GA0BL,OAzBA/7E,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,GAC/CnU,KAAKkqB,gBAAgB5f,WAAWy2E,aAClC/gF,KAAK23E,cAAc9iE,EAAI,GAEzB7U,KAAK23E,cAAcxjE,IACfnU,KAAK23E,cAAcxjE,IAAMnU,KAAK23E,cAAcjG,aAAe,GAC7D1xE,KAAK23E,cAAcxjE,IACnBnU,KAAK8R,eAAeqgE,OAAOnyE,KAAKsgF,mBACvBtgF,KAAK23E,cAAcxjE,GAAKnU,KAAK8R,eAAe/Q,KACrDf,KAAK23E,cAAcxjE,EAAInU,KAAK8R,eAAe/Q,KAAO,EAOlDf,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GAAI+X,WAAY,EAGzFlsB,KAAK23E,cAAc9iE,GAAK7U,KAAK8R,eAAe7J,MAC9CjI,KAAK23E,cAAc9iE,IAErB7U,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,GAEnDnU,KAAKmwE,YAAYl/D,QACV,CACT,CAQO,cAAA+qE,GAEL,OADAh8E,KAAK23E,cAAc9iE,EAAI,GAChB,CACT,CAaO,SAAAonE,GAEL,IAAKj8E,KAAKovB,aAAa/kB,gBAAgBk5B,kBAKrC,OAJAvjC,KAAKghF,kBACDhhF,KAAK23E,cAAc9iE,EAAI,GACzB7U,KAAK23E,cAAc9iE,KAEd,EAQT,GAFA7U,KAAKghF,gBAAgBhhF,KAAK8R,eAAe7J,MAErCjI,KAAK23E,cAAc9iE,EAAI,EACzB7U,KAAK23E,cAAc9iE,SAUnB,GAA6B,IAAzB7U,KAAK23E,cAAc9iE,GAClB7U,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,WAC1ChyB,KAAK23E,cAAcxjE,GAAKnU,KAAK23E,cAAcjG,cAC3C1xE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,IAAI+X,UAAW,CAC7FlsB,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GAAI+X,WAAY,EAC3FlsB,KAAK23E,cAAcxjE,IACnBnU,KAAK23E,cAAc9iE,EAAI7U,KAAK8R,eAAe7J,KAAO,EAMlD,MAAM1D,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GACpF5P,EAAK2gE,SAASllE,KAAK23E,cAAc9iE,KAAOtQ,EAAKsmB,WAAW7qB,KAAK23E,cAAc9iE,IAC7E7U,KAAK23E,cAAc9iE,GAKvB,CAGF,OADA7U,KAAKghF,mBACE,CACT,CAQO,GAAA9E,GACL,GAAIl8E,KAAK23E,cAAc9iE,GAAK7U,KAAK8R,eAAe7J,KAC9C,OAAO,EAET,MAAMg5E,EAAYjhF,KAAK23E,cAAc9iE,EAKrC,OAJA7U,KAAK23E,cAAc9iE,EAAI7U,KAAK23E,cAAcuJ,WACtClhF,KAAKkqB,gBAAgB5f,WAAWmR,kBAClCzb,KAAKg3E,WAAW/lE,KAAKjR,KAAK23E,cAAc9iE,EAAIosE,IAEvC,CACT,CASO,QAAA9E,GAEL,OADAn8E,KAAKgxE,gBAAgBsM,UAAU,IACxB,CACT,CASO,OAAAlB,GAEL,OADAp8E,KAAKgxE,gBAAgBsM,UAAU,IACxB,CACT,CAKQ,eAAA0D,CAAgBG,EAAiBnhF,KAAK8R,eAAe7J,KAAO,GAClEjI,KAAK23E,cAAc9iE,EAAIF,KAAKC,IAAIusE,EAAQxsE,KAAKkZ,IAAI,EAAG7tB,KAAK23E,cAAc9iE,IACvE7U,KAAK23E,cAAcxjE,EAAInU,KAAKovB,aAAa/kB,gBAAgBg5B,OACrD1uB,KAAKC,IAAI5U,KAAK23E,cAAcjG,aAAc/8D,KAAKkZ,IAAI7tB,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcxjE,IACpGQ,KAAKC,IAAI5U,KAAK8R,eAAe/Q,KAAO,EAAG4T,KAAKkZ,IAAI,EAAG7tB,KAAK23E,cAAcxjE,IAC1EnU,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,EACrD,CAKQ,UAAAitE,CAAWvsE,EAAWV,GAC5BnU,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,GAC/CnU,KAAKovB,aAAa/kB,gBAAgBg5B,QACpCrjC,KAAK23E,cAAc9iE,EAAIA,EACvB7U,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UAAY7d,IAEtDnU,KAAK23E,cAAc9iE,EAAIA,EACvB7U,KAAK23E,cAAcxjE,EAAIA,GAEzBnU,KAAKghF,kBACLhhF,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,EACrD,CAKQ,WAAAktE,CAAYxsE,EAAWV,GAG7BnU,KAAKghF,kBACLhhF,KAAKohF,WAAWphF,KAAK23E,cAAc9iE,EAAIA,EAAG7U,KAAK23E,cAAcxjE,EAAIA,EACnE,CASO,QAAAukE,CAASb,GAEd,MAAMyJ,EAAYthF,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UAM5D,OALIsvD,GAAa,EACfthF,KAAKqhF,YAAY,GAAI1sE,KAAKC,IAAI0sE,EAAWzJ,EAAOA,OAAO,IAAM,IAE7D73E,KAAKqhF,YAAY,IAAKxJ,EAAOA,OAAO,IAAM,KAErC,CACT,CASO,UAAAe,CAAWf,GAEhB,MAAM0J,EAAevhF,KAAK23E,cAAcjG,aAAe1xE,KAAK23E,cAAcxjE,EAM1E,OALIotE,GAAgB,EAClBvhF,KAAKqhF,YAAY,EAAG1sE,KAAKC,IAAI2sE,EAAc1J,EAAOA,OAAO,IAAM,IAE/D73E,KAAKqhF,YAAY,EAAGxJ,EAAOA,OAAO,IAAM,IAEnC,CACT,CAQO,aAAAgB,CAAchB,GAEnB,OADA73E,KAAKqhF,YAAYxJ,EAAOA,OAAO,IAAM,EAAG,IACjC,CACT,CAQO,cAAAiB,CAAejB,GAEpB,OADA73E,KAAKqhF,cAAcxJ,EAAOA,OAAO,IAAM,GAAI,IACpC,CACT,CAUO,cAAAkB,CAAelB,GAGpB,OAFA73E,KAAK44E,WAAWf,GAChB73E,KAAK23E,cAAc9iE,EAAI,GAChB,CACT,CAUO,mBAAAmkE,CAAoBnB,GAGzB,OAFA73E,KAAK04E,SAASb,GACd73E,KAAK23E,cAAc9iE,EAAI,GAChB,CACT,CAQO,kBAAAokE,CAAmBpB,GAExB,OADA73E,KAAKohF,YAAYvJ,EAAOA,OAAO,IAAM,GAAK,EAAG73E,KAAK23E,cAAcxjE,IACzD,CACT,CAWO,cAAA+kE,CAAerB,GAOpB,OANA73E,KAAKohF,WAEFvJ,EAAOt2E,QAAU,GAAMs2E,EAAOA,OAAO,IAAM,GAAK,EAAI,GAEpDA,EAAOA,OAAO,IAAM,GAAK,IAErB,CACT,CASO,eAAAiC,CAAgBjC,GAErB,OADA73E,KAAKohF,YAAYvJ,EAAOA,OAAO,IAAM,GAAK,EAAG73E,KAAK23E,cAAcxjE,IACzD,CACT,CAQO,iBAAA4lE,CAAkBlC,GAEvB,OADA73E,KAAKqhF,YAAYxJ,EAAOA,OAAO,IAAM,EAAG,IACjC,CACT,CAQO,eAAAsC,CAAgBtC,GAErB,OADA73E,KAAKohF,WAAWphF,KAAK23E,cAAc9iE,GAAIgjE,EAAOA,OAAO,IAAM,GAAK,IACzD,CACT,CASO,iBAAAuC,CAAkBvC,GAEvB,OADA73E,KAAKqhF,YAAY,EAAGxJ,EAAOA,OAAO,IAAM,IACjC,CACT,CAUO,UAAAwC,CAAWxC,GAEhB,OADA73E,KAAKk5E,eAAerB,IACb,CACT,CAaO,QAAAyC,CAASzC,GACd,MAAM2J,EAAQ3J,EAAOA,OAAO,GAM5B,OALc,IAAV2J,SACKxhF,KAAK23E,cAAc8J,KAAKzhF,KAAK23E,cAAc9iE,GAC/B,IAAV2sE,IACTxhF,KAAK23E,cAAc8J,KAAO,KAErB,CACT,CAQO,gBAAAtI,CAAiBtB,GACtB,GAAI73E,KAAK23E,cAAc9iE,GAAK7U,KAAK8R,eAAe7J,KAC9C,OAAO,EAET,IAAIu5E,EAAQ3J,EAAOA,OAAO,IAAM,EAChC,KAAO2J,KACLxhF,KAAK23E,cAAc9iE,EAAI7U,KAAK23E,cAAcuJ,WAE5C,OAAO,CACT,CAOO,iBAAArH,CAAkBhC,GACvB,GAAI73E,KAAK23E,cAAc9iE,GAAK7U,KAAK8R,eAAe7J,KAC9C,OAAO,EAET,IAAIu5E,EAAQ3J,EAAOA,OAAO,IAAM,EAEhC,KAAO2J,KACLxhF,KAAK23E,cAAc9iE,EAAI7U,KAAK23E,cAAc+J,WAE5C,OAAO,CACT,CAOO,eAAAnG,CAAgB1D,GACrB,MAAMoG,EAAIpG,EAAOA,OAAO,GAGxB,OAFU,IAANoG,IAASj+E,KAAK01E,aAAa1pE,IAAE,WACvB,IAANiyE,GAAiB,IAANA,IAASj+E,KAAK01E,aAAa1pE,KAAM,YACzC,CACT,CAYQ,kBAAA21E,CAAmBxtE,EAAW9R,EAAeC,EAAas/E,GAAqB,EAAOC,GAA0B,GACtH,MAAMt9E,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GAChE5P,IAGLA,EAAKu9E,aACHz/E,EACAC,EACAtC,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,kBACpCuB,GAEED,IACFr9E,EAAK2nB,WAAY,GAErB,CAOQ,gBAAA61D,CAAiB5tE,EAAW0tE,GAA0B,GAC5D,MAAMt9E,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GACjE5P,IACFA,EAAKulC,KAAK9pC,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,kBAAmBuB,GACjE7hF,KAAK8R,eAAe3N,OAAO69E,aAAahiF,KAAK23E,cAAcnjE,MAAQL,GACnE5P,EAAK2nB,WAAY,EAErB,CA0BO,cAAAktD,CAAevB,EAAiBgK,GAA0B,GAE/D,IAAI75D,EACJ,OAFAhoB,KAAKghF,gBAAgBhhF,KAAK8R,eAAe7J,MAEjC4vE,EAAOA,OAAO,IACpB,KAAK,EAIH,IAHA7vD,EAAIhoB,KAAK23E,cAAcxjE,EACvBnU,KAAKy3E,iBAAiBgI,UAAUz3D,GAChChoB,KAAK2hF,mBAAmB35D,IAAKhoB,KAAK23E,cAAc9iE,EAAG7U,KAAK8R,eAAe7J,KAA+B,IAAzBjI,KAAK23E,cAAc9iE,EAASgtE,GAClG75D,EAAIhoB,KAAK8R,eAAe/Q,KAAMinB,IACnChoB,KAAK+hF,iBAAiB/5D,EAAG65D,GAE3B7hF,KAAKy3E,iBAAiBgI,UAAUz3D,GAChC,MACF,KAAK,EAKH,GAJAA,EAAIhoB,KAAK23E,cAAcxjE,EACvBnU,KAAKy3E,iBAAiBgI,UAAUz3D,GAEhChoB,KAAK2hF,mBAAmB35D,EAAG,EAAGhoB,KAAK23E,cAAc9iE,EAAI,GAAG,EAAMgtE,GAC1D7hF,KAAK23E,cAAc9iE,EAAI,GAAK7U,KAAK8R,eAAe7J,KAAM,CAExD,MAAMskB,EAAWvsB,KAAK23E,cAActzE,MAAMP,IAAIkkB,EAAI,GAC9CuE,IACFA,EAASL,WAAY,EAEzB,CACA,KAAOlE,KACLhoB,KAAK+hF,iBAAiB/5D,EAAG65D,GAE3B7hF,KAAKy3E,iBAAiBgI,UAAU,GAChC,MACF,KAAK,EACH,GAAIz/E,KAAKkqB,gBAAgB5f,WAAW23E,uBAAwB,CAG1D,IAFAj6D,EAAIhoB,KAAK8R,eAAe/Q,KACxBf,KAAKy3E,iBAAiBhG,eAAe,EAAGzpD,EAAI,GACrCA,KAAK,CACV,MAAMiE,EAAcjsB,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQwT,GAC5E,GAAIiE,GAAaxB,mBACf,KAEJ,CACA,KAAOzC,GAAK,EAAGA,IACbhoB,KAAK8R,eAAeqgE,OAAOnyE,KAAKsgF,iBAEpC,KACK,CAGH,IAFAt4D,EAAIhoB,KAAK8R,eAAe/Q,KACxBf,KAAKy3E,iBAAiBgI,UAAUz3D,EAAI,GAC7BA,KACLhoB,KAAK+hF,iBAAiB/5D,EAAG65D,GAE3B7hF,KAAKy3E,iBAAiBgI,UAAU,EAClC,CACA,MACF,KAAK,EAEH,MAAMyC,EAAiBliF,KAAK23E,cAActzE,MAAM9C,OAASvB,KAAK8R,eAAe/Q,KACzEmhF,EAAiB,IACnBliF,KAAK23E,cAActzE,MAAM+nE,UAAU8V,GACnCliF,KAAK23E,cAAcnjE,MAAQG,KAAKkZ,IAAI7tB,KAAK23E,cAAcnjE,MAAQ0tE,EAAgB,GAC/EliF,KAAK23E,cAAcnzE,MAAQmQ,KAAKkZ,IAAI7tB,KAAK23E,cAAcnzE,MAAQ09E,EAAgB,GAE/EliF,KAAKgb,UAAU/J,KAAK,IAI1B,OAAO,CACT,CAwBO,WAAAqoE,CAAYzB,EAAiBgK,GAA0B,GAE5D,OADA7hF,KAAKghF,gBAAgBhhF,KAAK8R,eAAe7J,MACjC4vE,EAAOA,OAAO,IACpB,KAAK,EACH73E,KAAK2hF,mBAAmB3hF,KAAK23E,cAAcxjE,EAAGnU,KAAK23E,cAAc9iE,EAAG7U,KAAK8R,eAAe7J,KAA+B,IAAzBjI,KAAK23E,cAAc9iE,EAASgtE,GAC1H,MACF,KAAK,EACH7hF,KAAK2hF,mBAAmB3hF,KAAK23E,cAAcxjE,EAAG,EAAGnU,KAAK23E,cAAc9iE,EAAI,GAAG,EAAOgtE,GAClF,MACF,KAAK,EACH7hF,KAAK2hF,mBAAmB3hF,KAAK23E,cAAcxjE,EAAG,EAAGnU,KAAK8R,eAAe7J,MAAM,EAAM45E,GAIrF,OADA7hF,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,IAC5C,CACT,CAWO,WAAAolE,CAAY1B,GACjB73E,KAAKghF,kBACL,IAAIQ,EAAQ3J,EAAOA,OAAO,IAAM,EAEhC,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAGT,MAAMpqB,EAAc5H,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAE5DguE,EAAyBniF,KAAK8R,eAAe/Q,KAAO,EAAIf,KAAK23E,cAAcjG,aAC3E0Q,EAAuBpiF,KAAK8R,eAAe/Q,KAAO,EAAIf,KAAK23E,cAAcnjE,MAAQ2tE,EAAyB,EAChH,KAAOX,KAGLxhF,KAAK23E,cAActzE,MAAMyjB,OAAOs6D,EAAuB,EAAG,GAC1DpiF,KAAK23E,cAActzE,MAAMyjB,OAAOlgB,EAAK,EAAG5H,KAAK23E,cAAc/2D,aAAa5gB,KAAKsgF,mBAK/E,OAFAtgF,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAcxjE,EAAGnU,KAAK23E,cAAcjG,cAC9E1xE,KAAK23E,cAAc9iE,EAAI,GAChB,CACT,CAWO,WAAA2kE,CAAY3B,GACjB73E,KAAKghF,kBACL,IAAIQ,EAAQ3J,EAAOA,OAAO,IAAM,EAEhC,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAGT,MAAMpqB,EAAc5H,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAElE,IAAI6T,EAGJ,IAFAA,EAAIhoB,KAAK8R,eAAe/Q,KAAO,EAAIf,KAAK23E,cAAcjG,aACtD1pD,EAAIhoB,KAAK8R,eAAe/Q,KAAO,EAAIf,KAAK23E,cAAcnjE,MAAQwT,EACvDw5D,KAGLxhF,KAAK23E,cAActzE,MAAMyjB,OAAOlgB,EAAK,GACrC5H,KAAK23E,cAActzE,MAAMyjB,OAAOE,EAAG,EAAGhoB,KAAK23E,cAAc/2D,aAAa5gB,KAAKsgF,mBAK7E,OAFAtgF,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAcxjE,EAAGnU,KAAK23E,cAAcjG,cAC9E1xE,KAAK23E,cAAc9iE,EAAI,GAChB,CACT,CAcO,WAAA2jE,CAAYX,GACjB73E,KAAKghF,kBACL,MAAMz8E,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GASxF,OARI5P,IACFA,EAAKm8E,YACH1gF,KAAK23E,cAAc9iE,EACnBgjE,EAAOA,OAAO,IAAM,EACpB73E,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAEtCtgF,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,KAE9C,CACT,CAcO,WAAAslE,CAAY5B,GACjB73E,KAAKghF,kBACL,MAAMz8E,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GASxF,OARI5P,IACFA,EAAK89E,YACHriF,KAAK23E,cAAc9iE,EACnBgjE,EAAOA,OAAO,IAAM,EACpB73E,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAEtCtgF,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,KAE9C,CACT,CAUO,QAAAulE,CAAS7B,GACd,IAAI2J,EAAQ3J,EAAOA,OAAO,IAAM,EAEhC,KAAO2J,KACLxhF,KAAK23E,cAActzE,MAAMyjB,OAAO9nB,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAc3lD,UAAW,GACzFhyB,KAAK23E,cAActzE,MAAMyjB,OAAO9nB,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcjG,aAAc,EAAG1xE,KAAK23E,cAAc/2D,aAAa5gB,KAAKsgF,mBAGtI,OADAtgF,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAOO,UAAAiI,CAAW9B,GAChB,IAAI2J,EAAQ3J,EAAOA,OAAO,IAAM,EAEhC,KAAO2J,KACLxhF,KAAK23E,cAActzE,MAAMyjB,OAAO9nB,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcjG,aAAc,GAC5F1xE,KAAK23E,cAActzE,MAAMyjB,OAAO9nB,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAc3lD,UAAW,EAAGhyB,KAAK23E,cAAc/2D,aAAalT,EAAAmT,oBAG9H,OADA7gB,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAoBO,UAAAr0B,CAAWw6B,GAChB,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAET,MAAMwvD,EAAQ3J,EAAOA,OAAO,IAAM,EAClC,IAAK,IAAI1jE,EAAInU,KAAK23E,cAAc3lD,UAAW7d,GAAKnU,KAAK23E,cAAcjG,eAAgBv9D,EAAG,CACpF,MAAM5P,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GACrE5P,EAAK89E,YAAY,EAAGb,EAAOxhF,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAC/D/7E,EAAK2nB,WAAY,CACnB,CAEA,OADAlsB,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAqBO,WAAAiH,CAAYd,GACjB,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAET,MAAMwvD,EAAQ3J,EAAOA,OAAO,IAAM,EAClC,IAAK,IAAI1jE,EAAInU,KAAK23E,cAAc3lD,UAAW7d,GAAKnU,KAAK23E,cAAcjG,eAAgBv9D,EAAG,CACpF,MAAM5P,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GACrE5P,EAAKm8E,YAAY,EAAGc,EAAOxhF,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAC/D/7E,EAAK2nB,WAAY,CACnB,CAEA,OADAlsB,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAWO,aAAA2J,CAAcxD,GACnB,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAET,MAAMwvD,EAAQ3J,EAAOA,OAAO,IAAM,EAClC,IAAK,IAAI1jE,EAAInU,KAAK23E,cAAc3lD,UAAW7d,GAAKnU,KAAK23E,cAAcjG,eAAgBv9D,EAAG,CACpF,MAAM5P,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GACrE5P,EAAKm8E,YAAY1gF,KAAK23E,cAAc9iE,EAAG2sE,EAAOxhF,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAClF/7E,EAAK2nB,WAAY,CACnB,CAEA,OADAlsB,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAWO,aAAA4J,CAAczD,GACnB,GAAI73E,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAcjG,cAAgB1xE,KAAK23E,cAAcxjE,EAAInU,KAAK23E,cAAc3lD,UACtG,OAAO,EAET,MAAMwvD,EAAQ3J,EAAOA,OAAO,IAAM,EAClC,IAAK,IAAI1jE,EAAInU,KAAK23E,cAAc3lD,UAAW7d,GAAKnU,KAAK23E,cAAcjG,eAAgBv9D,EAAG,CACpF,MAAM5P,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQL,GACrE5P,EAAK89E,YAAYriF,KAAK23E,cAAc9iE,EAAG2sE,EAAOxhF,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAClF/7E,EAAK2nB,WAAY,CACnB,CAEA,OADAlsB,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,eAC/E,CACT,CAUO,UAAAkI,CAAW/B,GAChB73E,KAAKghF,kBACL,MAAMz8E,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GASxF,OARI5P,IACFA,EAAKu9E,aACH9hF,KAAK23E,cAAc9iE,EACnB7U,KAAK23E,cAAc9iE,GAAKgjE,EAAOA,OAAO,IAAM,GAC5C73E,KAAK23E,cAAcgJ,YAAY3gF,KAAKsgF,mBAEtCtgF,KAAKy3E,iBAAiBgI,UAAUz/E,KAAK23E,cAAcxjE,KAE9C,CACT,CA4BO,wBAAA6lE,CAAyBnC,GAC9B,MAAMyK,EAAYtiF,KAAKqiC,QAAQs9C,mBAC/B,IAAK2C,EACH,OAAO,EAGT,MAAM/gF,EAASs2E,EAAOA,OAAO,IAAM,EAC7BwH,EAAU5P,EAAAoB,eAAekP,aAAauC,GACtCztE,EAAI7U,KAAK23E,cAAc9iE,EAAIwqE,EAE3Bx1E,EADY7J,KAAK23E,cAActzE,MAAMP,IAAI9D,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,GACtEmkD,UAAUzjD,GAC3BoI,EAAO,IAAI64D,YAAYjsE,EAAKtI,OAASA,GAC3C,IAAIghF,EAAQ,EACZ,IAAK,IAAIC,EAAQ,EAAGA,EAAQ34E,EAAKtI,QAAS,CACxC,MAAMq+E,EAAK/1E,EAAK44E,YAAYD,IAAU,EACtCvlE,EAAKslE,KAAW3C,EAChB4C,GAAS5C,EAAK,MAAS,EAAI,CAC7B,CACA,IAAI8C,EAAUH,EACd,IAAK,IAAIzjF,EAAI,EAAGA,EAAIyC,IAAUzC,EAC5Bme,EAAK0lE,WAAWD,EAAS,EAAGH,GAC5BG,GAAWH,EAGb,OADAviF,KAAKu4E,MAAMt7D,EAAM,EAAGylE,IACb,CACT,CA2BO,2BAAAzI,CAA4BpC,GACjC,OAAIA,EAAOA,OAAO,GAAK,IAGnB73E,KAAK4iF,IAAI,UAAY5iF,KAAK4iF,IAAI,iBAAmB5iF,KAAK4iF,IAAI,UAC5D5iF,KAAKovB,aAAa5kB,iBAAiB,WAC1BxK,KAAK4iF,IAAI,UAClB5iF,KAAKovB,aAAa5kB,iBAAiB,WAL5B,CAQX,CA0BO,6BAAA0vE,CAA8BrC,GACnC,OAAIA,EAAOA,OAAO,GAAK,IAMnB73E,KAAK4iF,IAAI,SACX5iF,KAAKovB,aAAa5kB,iBAAiB,eAC1BxK,KAAK4iF,IAAI,gBAClB5iF,KAAKovB,aAAa5kB,iBAAiB,eAC1BxK,KAAK4iF,IAAI,SAGlB5iF,KAAKovB,aAAa5kB,iBAAiBqtE,EAAOA,OAAO,GAAK,KAC7C73E,KAAK4iF,IAAI,WAClB5iF,KAAKovB,aAAa5kB,iBAAiB,oBAd5B,CAiBX,CAUO,aAAAuwE,CAAclD,GACnB,OAAIA,EAAOA,OAAO,GAAK,GAGvB73E,KAAKovB,aAAa5kB,iBAAiB,gBAAwBupE,EAAA8O,sBAFlD,CAIX,CAMQ,GAAAD,CAAIE,GACV,OAAQ9iF,KAAKkqB,gBAAgB5f,WAAWy4E,SAAW,IAAI3lD,WAAW0lD,EACpE,CAmBO,OAAAvI,CAAQ1C,GACb,IAAK,IAAI/4E,EAAI,EAAGA,EAAI+4E,EAAOt2E,OAAQzC,IACjC,OAAQ+4E,EAAOA,OAAO/4E,IACpB,KAAK,EACHkB,KAAKovB,aAAauT,MAAMQ,YAAa,EACrC,MACF,KAAK,GACHnjC,KAAKkqB,gBAAgBhhB,QAAQ63E,YAAa,EAIhD,OAAO,CACT,CAoHO,cAAAvG,CAAe3C,GACpB,IAAK,IAAI/4E,EAAI,EAAGA,EAAI+4E,EAAOt2E,OAAQzC,IACjC,OAAQ+4E,EAAOA,OAAO/4E,IACpB,KAAK,EACHkB,KAAKovB,aAAa/kB,gBAAgB24B,uBAAwB,EAC1D,MACF,KAAK,EACHhjC,KAAKgxE,gBAAgBgS,YAAY,EAAGvP,EAAAwP,iBACpCjjF,KAAKgxE,gBAAgBgS,YAAY,EAAGvP,EAAAwP,iBACpCjjF,KAAKgxE,gBAAgBgS,YAAY,EAAGvP,EAAAwP,iBACpCjjF,KAAKgxE,gBAAgBgS,YAAY,EAAGvP,EAAAwP,iBAEpC,MACF,KAAK,EAMCjjF,KAAKkqB,gBAAgB5f,WAAW6wE,cAAcjH,cAChDl0E,KAAK8R,eAAeqH,OAAO,IAAKnZ,KAAK8R,eAAe/Q,MACpDf,KAAK02E,gBAAgBzlE,QAEvB,MACF,KAAK,EACHjR,KAAKovB,aAAa/kB,gBAAgBg5B,QAAS,EAC3CrjC,KAAKohF,WAAW,EAAG,GACnB,MACF,KAAK,EACHphF,KAAKovB,aAAa/kB,gBAAgBy5B,YAAa,EAC/C,MACF,KAAK,GACC9jC,KAAKkqB,gBAAgB5f,WAAW44E,QAAQC,sBAC1CnjF,KAAKkqB,gBAAgBhhB,QAAQ+gC,aAAc,GAE7C,MACF,KAAK,GACHjqC,KAAKovB,aAAa/kB,gBAAgBk5B,mBAAoB,EACtD,MACF,KAAK,GACHvjC,KAAK8W,YAAYC,MAAM,6CACvB/W,KAAKovB,aAAa/kB,gBAAgB64B,mBAAoB,EACtDljC,KAAK42E,wBAAwB3lE,OAC7B,MACF,KAAK,EAEHjR,KAAKw7D,mBAAmB14B,eAAiB,MACzC,MACF,KAAK,IAEH9iC,KAAKw7D,mBAAmB14B,eAAiB,QACzC,MACF,KAAK,KACH9iC,KAAKw7D,mBAAmB14B,eAAiB,OACzC,MACF,KAAK,KAGH9iC,KAAKw7D,mBAAmB14B,eAAiB,MACzC,MACF,KAAK,KAGH9iC,KAAKovB,aAAa/kB,gBAAgBwJ,WAAY,EAC9C7T,KAAK22E,oBAAoB1lE,OACzB,MACF,KAAK,KACHjR,KAAK8W,YAAYC,MAAM,yCACvB,MACF,KAAK,KACH/W,KAAKw7D,mBAAmB4nB,eAAiB,MACzC,MACF,KAAK,KACHpjF,KAAK8W,YAAYC,MAAM,yCACvB,MACF,KAAK,KACH/W,KAAKw7D,mBAAmB4nB,eAAiB,aACzC,MACF,KAAK,GACHpjF,KAAKovB,aAAasU,gBAAiB,EACnC,MACF,KAAK,KACH1jC,KAAKk7E,aACL,MACF,KAAK,KACHl7E,KAAKk7E,aAEP,KAAK,GACL,KAAK,KAEH,GAAIl7E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cAAe,CAC/D,MAAM94C,EAAQ/hB,KAAKovB,aAAayrC,cAChC94C,EAAMshE,UAAYthE,EAAM+4C,MACxB/4C,EAAM+4C,MAAQ/4C,EAAMuhE,QACtB,CACAtjF,KAAK8R,eAAe0B,QAAQ+vE,kBAAkBvjF,KAAKsgF,kBACnDtgF,KAAKovB,aAAa5S,qBAAsB,EACxCxc,KAAKy2E,sBAAsBxlE,UAAKrM,GAChC5E,KAAK42E,wBAAwB3lE,OAC7B,MACF,KAAK,KACHjR,KAAKovB,aAAa/kB,gBAAgBL,oBAAqB,EACvD,MACF,KAAK,KACHhK,KAAKovB,aAAa/kB,gBAAgBioB,oBAAqB,EACvD,MACF,KAAK,MACCtyB,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcwoB,kBAAoB,KACpExjF,KAAKovB,aAAa/kB,gBAAgBuO,oBAAqB,GAEzD,MACF,KAAK,KACC5Y,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcp3B,iBAChD5jC,KAAKovB,aAAa/kB,gBAAgBu5B,gBAAiB,GAK3D,OAAO,CACT,CAuBO,SAAA62C,CAAU5C,GACf,IAAK,IAAI/4E,EAAI,EAAGA,EAAI+4E,EAAOt2E,OAAQzC,IACjC,OAAQ+4E,EAAOA,OAAO/4E,IACpB,KAAK,EACHkB,KAAKovB,aAAauT,MAAMQ,YAAa,EACrC,MACF,KAAK,GACHnjC,KAAKkqB,gBAAgBhhB,QAAQ63E,YAAa,EAIhD,OAAO,CACT,CAgHO,gBAAArG,CAAiB7C,GACtB,IAAK,IAAI/4E,EAAI,EAAGA,EAAI+4E,EAAOt2E,OAAQzC,IACjC,OAAQ+4E,EAAOA,OAAO/4E,IACpB,KAAK,EACHkB,KAAKovB,aAAa/kB,gBAAgB24B,uBAAwB,EAC1D,MACF,KAAK,EAMChjC,KAAKkqB,gBAAgB5f,WAAW6wE,cAAcjH,cAChDl0E,KAAK8R,eAAeqH,OAAO,GAAInZ,KAAK8R,eAAe/Q,MACnDf,KAAK02E,gBAAgBzlE,QAEvB,MACF,KAAK,EACHjR,KAAKovB,aAAa/kB,gBAAgBg5B,QAAS,EAC3CrjC,KAAKohF,WAAW,EAAG,GACnB,MACF,KAAK,EACHphF,KAAKovB,aAAa/kB,gBAAgBy5B,YAAa,EAC/C,MACF,KAAK,GACC9jC,KAAKkqB,gBAAgB5f,WAAW44E,QAAQC,sBAC1CnjF,KAAKkqB,gBAAgBhhB,QAAQ+gC,aAAc,GAE7C,MACF,KAAK,GACHjqC,KAAKovB,aAAa/kB,gBAAgBk5B,mBAAoB,EACtD,MACF,KAAK,GACHvjC,KAAK8W,YAAYC,MAAM,oCACvB/W,KAAKovB,aAAa/kB,gBAAgB64B,mBAAoB,EACtDljC,KAAK42E,wBAAwB3lE,OAC7B,MACF,KAAK,EACL,KAAK,IACL,KAAK,KACL,KAAK,KACHjR,KAAKw7D,mBAAmB14B,eAAiB,OACzC,MACF,KAAK,KACH9iC,KAAKovB,aAAa/kB,gBAAgBwJ,WAAY,EAC9C,MACF,KAAK,KACH7T,KAAK8W,YAAYC,MAAM,yCACvB,MACF,KAAK,KAML,KAAK,KACH/W,KAAKw7D,mBAAmB4nB,eAAiB,UACzC,MALF,KAAK,KACHpjF,KAAK8W,YAAYC,MAAM,yCACvB,MAIF,KAAK,GACH/W,KAAKovB,aAAasU,gBAAiB,EACnC,MACF,KAAK,KACH1jC,KAAKo7E,gBACL,MACF,KAAK,KAEL,KAAK,GACL,KAAK,KAEH,GAAIp7E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cAAe,CAC/D,MAAM94C,EAAQ/hB,KAAKovB,aAAayrC,cAChC94C,EAAMuhE,SAAWvhE,EAAM+4C,MACvB/4C,EAAM+4C,MAAQ/4C,EAAMshE,SACtB,CAEArjF,KAAK8R,eAAe0B,QAAQiwE,uBACH,OAArB5L,EAAOA,OAAO/4E,IAChBkB,KAAKo7E,gBAEPp7E,KAAKovB,aAAa5S,qBAAsB,EACxCxc,KAAKy2E,sBAAsBxlE,UAAKrM,GAChC5E,KAAK42E,wBAAwB3lE,OAC7B,MACF,KAAK,KACHjR,KAAKovB,aAAa/kB,gBAAgBL,oBAAqB,EACvD,MACF,KAAK,KACHhK,KAAKovB,aAAa/kB,gBAAgBioB,oBAAqB,EACvDtyB,KAAKy2E,sBAAsBxlE,UAAKrM,GAChC,MACF,KAAK,MACC5E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcwoB,kBAAoB,KACpExjF,KAAKovB,aAAa/kB,gBAAgBuO,oBAAqB,GAEzD,MACF,KAAK,KACC5Y,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcp3B,iBAChD5jC,KAAKovB,aAAa/kB,gBAAgBu5B,gBAAiB,GAK3D,OAAO,CACT,CAmCO,WAAA43C,CAAY3D,EAAiBnlE,GAWlC,MAAMgxE,EAAK1jF,KAAKovB,aAAa/kB,iBACrBy4B,eAAgB6gD,EAAeP,eAAgBQ,GAAkB5jF,KAAKw7D,mBACxEqoB,EAAK7jF,KAAKovB,cACV5b,QAAEA,EAAOvL,KAAEA,GAASjI,KAAK8R,gBACzB2B,OAAEA,EAAM2f,IAAEA,GAAQ5f,EAClB8gC,EAAOt0C,KAAKkqB,gBAAgB5f,WAE5Bw5E,EAAI,CAAClhD,EAAW7Z,KACpB86D,EAAGr5E,iBAAiB,KAAakI,EAAO,GAAK,MAAMkwB,KAAK7Z,QACjD,GAEHg7D,EAAOt5E,GAAsBA,EAAO,EAAQ,EAE5CwzE,EAAIpG,EAAOA,OAAO,GAExB,OAAInlE,EACkBoxE,EAAE7F,EAAZ,IAANA,EAAmB,EACb,IAANA,EAAqB8F,EAAIF,EAAGlhD,MAAMQ,YAC5B,KAAN86C,EAAoB,EACd,KAANA,EAAsB8F,EAAIzvC,EAAKysC,YACzB,GAGF,IAAN9C,EAAgB6F,EAAE7F,EAAG8F,EAAIL,EAAG1gD,wBACtB,IAANi7C,EAAgB6F,EAAE7F,EAAG3pC,EAAK6mC,cAAcjH,YAAwB,KAATjsE,EAAa,EAAoB,MAATA,EAAc,EAAQ,EAAoB,GACnH,IAANg2E,EAAgB6F,EAAE7F,EAAG8F,EAAIL,EAAGrgD,SACtB,IAAN46C,EAAgB6F,EAAE7F,EAAG8F,EAAIL,EAAG5/C,aACtB,IAANm6C,EAAgB6F,EAAE7F,EAAC,GACb,IAANA,EAAgB6F,EAAE7F,EAAG8F,EAAsB,QAAlBJ,IACnB,KAAN1F,EAAiB6F,EAAE7F,EAAG8F,EAAIzvC,EAAKrK,cACzB,KAANg0C,EAAiB6F,EAAE7F,EAAG8F,GAAKF,EAAGngD,iBACxB,KAANu6C,EAAiB6F,EAAE7F,EAAG8F,EAAIL,EAAGngD,oBACvB,KAAN06C,EAAiB6F,EAAE7F,EAAG8F,EAAIL,EAAGxgD,oBACvB,KAAN+6C,EAAiB6F,EAAE7F,EAAC,GACd,MAANA,EAAmB6F,EAAE7F,EAAG8F,EAAsB,UAAlBJ,IACtB,OAAN1F,EAAmB6F,EAAE7F,EAAG8F,EAAsB,SAAlBJ,IACtB,OAAN1F,EAAmB6F,EAAE7F,EAAG8F,EAAsB,QAAlBJ,IACtB,OAAN1F,EAAmB6F,EAAE7F,EAAG8F,EAAIL,EAAG7vE,YACzB,OAANoqE,EAAmB6F,EAAE7F,EAAC,GAChB,OAANA,EAAmB6F,EAAE7F,EAAG8F,EAAsB,QAAlBH,IACtB,OAAN3F,EAAmB6F,EAAE7F,EAAC,GAChB,OAANA,EAAmB6F,EAAE7F,EAAG8F,EAAsB,eAAlBH,IACtB,OAAN3F,EAAmB6F,EAAE7F,EAAC,GAChB,KAANA,GAAkB,OAANA,GAAoB,OAANA,EAAmB6F,EAAE7F,EAAG8F,EAAItwE,IAAW2f,IAC3D,OAAN6qD,EAAmB6F,EAAE7F,EAAG8F,EAAIL,EAAG15E,qBACzB,OAANi0E,EAAmB6F,EAAE7F,EAAG8F,EAAIL,EAAGpxD,qBACzB,OAAN2rD,GAAmBj+E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcp3B,eAAiBkgD,EAAE7F,EAAG8F,EAAIL,EAAG9/C,iBAC3FkgD,EAAE7F,EAAC,EACZ,CAKQ,gBAAA+F,CAAiBzxE,EAAe0xE,EAAcC,EAAYC,EAAYC,GAS5E,OARa,IAATH,GACF1xE,GAAK,SACLA,IAAS,SACTA,GAAS84B,EAAAoD,cAAc41C,aAAa,CAACH,EAAIC,EAAIC,KAC3B,IAATH,IACT1xE,IAAS,SACTA,GAAS,SAA2B,IAAL2xE,GAE1B3xE,CACT,CAMQ,aAAA+xE,CAAczM,EAAiBhtE,EAAa05E,GAKlD,MAAMC,EAAO,CAAC,EAAG,GAAI,EAAG,EAAG,EAAG,GAG9B,IAAIC,EAAS,EAGTC,EAAU,EAEd,EAAG,CAED,GADAF,EAAKE,EAAUD,GAAU5M,EAAOA,OAAOhtE,EAAM65E,GACzC7M,EAAO8M,aAAa95E,EAAM65E,GAAU,CACtC,MAAME,EAAY/M,EAAOgN,aAAah6E,EAAM65E,GAC5C,IAAI5lF,EAAI,EACR,GACkB,IAAZ0lF,EAAK,KACPC,EAAS,GAEXD,EAAKE,EAAU5lF,EAAI,EAAI2lF,GAAUG,EAAU9lF,WAClCA,EAAI8lF,EAAUrjF,QAAUzC,EAAI4lF,EAAU,EAAID,EAASD,EAAKjjF,QACnE,KACF,CAEA,GAAiB,IAAZijF,EAAK,IAAYE,EAAUD,GAAU,GACxB,IAAZD,EAAK,IAAYE,EAAUD,GAAU,EACzC,MAGED,EAAK,KACPC,EAAS,EAEb,SAAWC,EAAU75E,EAAMgtE,EAAOt2E,QAAUmjF,EAAUD,EAASD,EAAKjjF,QAGpE,IAAK,IAAIzC,EAAI,EAAGA,EAAI0lF,EAAKjjF,SAAUzC,GAChB,IAAb0lF,EAAK1lF,KACP0lF,EAAK1lF,GAAK,GAKd,OAAQ0lF,EAAK,IACX,KAAK,GACHD,EAAKt4E,GAAKjM,KAAKgkF,iBAAiBO,EAAKt4E,GAAIu4E,EAAK,GAAIA,EAAK,GAAIA,EAAK,GAAIA,EAAK,IACzE,MACF,KAAK,GACHD,EAAKv4E,GAAKhM,KAAKgkF,iBAAiBO,EAAKv4E,GAAIw4E,EAAK,GAAIA,EAAK,GAAIA,EAAK,GAAIA,EAAK,IACzE,MACF,KAAK,GACHD,EAAKv5D,SAAWu5D,EAAKv5D,SAASuuB,QAC9BgrC,EAAKv5D,SAAS85D,eAAiB9kF,KAAKgkF,iBAAiBO,EAAKv5D,SAAS85D,eAAgBN,EAAK,GAAIA,EAAK,GAAIA,EAAK,GAAIA,EAAK,IAGvH,OAAOE,CACT,CAWQ,iBAAAK,CAAkBj8E,EAAey7E,GAGvCA,EAAKv5D,SAAWu5D,EAAKv5D,SAASuuB,WAGxBzwC,GAASA,EAAQ,KACrBA,EAAQ,GAEVy7E,EAAKv5D,SAASqjB,eAAiBvlC,EAC/By7E,EAAKt4E,IAAE,UAGO,IAAVnD,IACFy7E,EAAKt4E,KAAM,WAIbs4E,EAAKS,gBACP,CAEQ,YAAAC,CAAaV,GACnBA,EAAKt4E,GAAKyB,EAAAmT,kBAAkB5U,GAC5Bs4E,EAAKv4E,GAAK0B,EAAAmT,kBAAkB7U,GAC5Bu4E,EAAKv5D,SAAWu5D,EAAKv5D,SAASuuB,QAG9BgrC,EAAKv5D,SAASqjB,eAAc,EAC5Bk2C,EAAKv5D,SAAS85D,iBAAkB,SAChCP,EAAKS,gBACP,CAqFO,cAAArK,CAAe9C,GAEpB,GAAsB,IAAlBA,EAAOt2E,QAAqC,IAArBs2E,EAAOA,OAAO,GAEvC,OADA73E,KAAKilF,aAAajlF,KAAK01E,eAChB,EAGT,MAAMwP,EAAIrN,EAAOt2E,OACjB,IAAI08E,EACJ,MAAMsG,EAAOvkF,KAAK01E,aAElB,IAAK,IAAI52E,EAAI,EAAGA,EAAIomF,EAAGpmF,IACrBm/E,EAAIpG,EAAOA,OAAO/4E,GACdm/E,GAAK,IAAMA,GAAK,IAElBsG,EAAKt4E,KAAM,SACXs4E,EAAKt4E,IAAM,SAAqBgyE,EAAI,IAC3BA,GAAK,IAAMA,GAAK,IAEzBsG,EAAKv4E,KAAM,SACXu4E,EAAKv4E,IAAM,SAAqBiyE,EAAI,IAC3BA,GAAK,IAAMA,GAAK,IAEzBsG,EAAKt4E,KAAM,SACXs4E,EAAKt4E,IAAM,SAAqBgyE,EAAI,IAC3BA,GAAK,KAAOA,GAAK,KAE1BsG,EAAKv4E,KAAM,SACXu4E,EAAKv4E,IAAM,SAAqBiyE,EAAI,KACrB,IAANA,EAETj+E,KAAKilF,aAAaV,GACH,IAANtG,EAETsG,EAAKt4E,IAAE,UACQ,IAANgyE,EAETsG,EAAKv4E,IAAE,SACQ,IAANiyE,GAETsG,EAAKt4E,IAAE,UACPjM,KAAK+kF,kBAAkBlN,EAAO8M,aAAa7lF,GAAK+4E,EAAOgN,aAAa/lF,GAAI,GAAI,EAAwBylF,IACrF,IAANtG,EAETsG,EAAKt4E,IAAE,UACQ,IAANgyE,EAGTsG,EAAKt4E,IAAE,SACQ,IAANgyE,EAETsG,EAAKt4E,IAAE,WACQ,IAANgyE,EAETsG,EAAKt4E,IAAE,WACQ,IAANgyE,EAETsG,EAAKv4E,IAAE,UACQ,KAANiyE,EAETj+E,KAAK+kF,kBAAiB,EAAwBR,GAC/B,KAANtG,GAETsG,EAAKt4E,KAAM,UACXs4E,EAAKv4E,KAAM,WACI,KAANiyE,EAETsG,EAAKv4E,KAAM,SACI,KAANiyE,GAETsG,EAAKt4E,KAAM,UACXjM,KAAK+kF,kBAAiB,EAAsBR,IAC7B,KAANtG,EAETsG,EAAKt4E,KAAM,UACI,KAANgyE,EAETsG,EAAKt4E,KAAM,SACI,KAANgyE,EAETsG,EAAKt4E,KAAM,WACI,KAANgyE,EAETsG,EAAKt4E,IAAM,WACI,KAANgyE,GAETsG,EAAKt4E,KAAM,SACXs4E,EAAKt4E,IAA0B,SAApByB,EAAAmT,kBAAkB5U,IACd,KAANgyE,GAETsG,EAAKv4E,KAAM,SACXu4E,EAAKv4E,IAA0B,SAApB0B,EAAAmT,kBAAkB7U,IACd,KAANiyE,GAAkB,KAANA,GAAkB,KAANA,EAEjCn/E,GAAKkB,KAAKskF,cAAczM,EAAQ/4E,EAAGylF,GACpB,KAANtG,EAETsG,EAAKv4E,IAAE,WACQ,KAANiyE,EAETsG,EAAKv4E,KAAM,WACI,MAANiyE,IAAcj+E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcmqB,0BAA4B,GAEjGZ,EAAKt4E,KAAM,UACI,MAANgyE,IAAcj+E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcmqB,0BAA4B,GAEjGZ,EAAKv4E,KAAM,UACI,KAANiyE,GACTsG,EAAKv5D,SAAWu5D,EAAKv5D,SAASuuB,QAC9BgrC,EAAKv5D,SAAS85D,gBAAkB,EAChCP,EAAKS,kBAELhlF,KAAK8W,YAAYC,MAAM,6BAA8BknE,GAGzD,OAAO,CACT,CA2BO,YAAArD,CAAa/C,GAClB,OAAQA,EAAOA,OAAO,IACpB,KAAK,EAEH73E,KAAKovB,aAAa5kB,iBAAiB,QACnC,MACF,KAAK,EAEH,MAAM2J,EAAInU,KAAK23E,cAAcxjE,EAAI,EAC3BU,EAAI7U,KAAK23E,cAAc9iE,EAAI,EACjC7U,KAAKovB,aAAa5kB,iBAAiB,KAAa2J,KAAKU,MAGzD,OAAO,CACT,CAGO,mBAAAgmE,CAAoBhD,GAGzB,OAAQA,EAAOA,OAAO,IACpB,KAAK,EAEH,MAAM1jE,EAAInU,KAAK23E,cAAcxjE,EAAI,EAC3BU,EAAI7U,KAAK23E,cAAc9iE,EAAI,EACjC7U,KAAKovB,aAAa5kB,iBAAiB,MAAc2J,KAAKU,MACtD,MACF,KAAK,GAIL,KAAK,GAIL,KAAK,GAIL,KAAK,GAGH,MACF,KAAK,KAEC7U,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcwoB,kBAAoB,IACpExjF,KAAKk3E,2BAA2BjmE,OAItC,OAAO,CACT,CAsBO,SAAA6pE,CAAUjD,GAkBf,OAjBA73E,KAAKovB,aAAasU,gBAAiB,EACnC1jC,KAAK42E,wBAAwB3lE,OAC7BjR,KAAK23E,cAAc3lD,UAAY,EAC/BhyB,KAAK23E,cAAcjG,aAAe1xE,KAAK8R,eAAe/Q,KAAO,EAC7Df,KAAK01E,aAAehoE,EAAAmT,kBAAkB04B,QACtCv5C,KAAKovB,aAAa9d,QAClBtR,KAAKgxE,gBAAgB1/D,QAGrBtR,KAAK23E,cAAcyN,OAAS,EAC5BplF,KAAK23E,cAAc0N,OAASrlF,KAAK23E,cAAcnjE,MAC/CxU,KAAK23E,cAAc2N,iBAAiBr5E,GAAKjM,KAAK01E,aAAazpE,GAC3DjM,KAAK23E,cAAc2N,iBAAiBt5E,GAAKhM,KAAK01E,aAAa1pE,GAC3DhM,KAAK23E,cAAc4N,aAAevlF,KAAKgxE,gBAAgBsO,QAGvDt/E,KAAKovB,aAAa/kB,gBAAgBg5B,QAAS,GACpC,CACT,CAsBO,cAAA23C,CAAenD,GACpB,MAAM2J,EAA0B,IAAlB3J,EAAOt2E,OAAe,EAAIs2E,EAAOA,OAAO,GACtD,GAAc,IAAV2J,EACFxhF,KAAKovB,aAAa/kB,gBAAgB6/B,iBAActlC,EAChD5E,KAAKovB,aAAa/kB,gBAAgB4/B,iBAAcrlC,MAC3C,CACL,OAAQ48E,GACN,KAAK,EACL,KAAK,EACHxhF,KAAKovB,aAAa/kB,gBAAgB6/B,YAAc,QAChD,MACF,KAAK,EACL,KAAK,EACHlqC,KAAKovB,aAAa/kB,gBAAgB6/B,YAAc,YAChD,MACF,KAAK,EACL,KAAK,EACHlqC,KAAKovB,aAAa/kB,gBAAgB6/B,YAAc,MAGpD,MAAMs7C,EAAahE,EAAQ,GAAM,EACjCxhF,KAAKovB,aAAa/kB,gBAAgB4/B,YAAcu7C,CAClD,CACA,OAAO,CACT,CASO,eAAAvK,CAAgBpD,GACrB,MAAM7sE,EAAM6sE,EAAOA,OAAO,IAAM,EAChC,IAAIv8B,EAWJ,OATIu8B,EAAOt2E,OAAS,IAAM+5C,EAASu8B,EAAOA,OAAO,IAAM73E,KAAK8R,eAAe/Q,MAAmB,IAAXu6C,KACjFA,EAASt7C,KAAK8R,eAAe/Q,MAG3Bu6C,EAAStwC,IACXhL,KAAK23E,cAAc3lD,UAAYhnB,EAAM,EACrChL,KAAK23E,cAAcjG,aAAep2B,EAAS,EAC3Ct7C,KAAKohF,WAAW,EAAG,KAEd,CACT,CAgCO,aAAAjG,CAActD,GACnB,IAAK5D,EAAoB4D,EAAOA,OAAO,GAAI73E,KAAKkqB,gBAAgB5f,WAAW6wE,eACzE,OAAO,EAET,MAAMsK,EAAU5N,EAAOt2E,OAAS,EAAKs2E,EAAOA,OAAO,GAAK,EACxD,OAAQA,EAAOA,OAAO,IACpB,KAAK,GACY,IAAX4N,GACFzlF,KAAK82E,+BAA+B7lE,KAAK8P,EAAyBC,qBAEpE,MACF,KAAK,GACHhhB,KAAK82E,+BAA+B7lE,KAAK8P,EAAyBK,sBAClE,MACF,KAAK,GACCphB,KAAK8R,gBACP9R,KAAKovB,aAAa5kB,iBAAiB,OAAexK,KAAK8R,eAAe/Q,QAAQf,KAAK8R,eAAe7J,SAEpG,MACF,KAAK,GACY,IAAXw9E,GAA2B,IAAXA,IAClBzlF,KAAKq2E,kBAAkBpyE,KAAKjE,KAAKm2E,cAC7Bn2E,KAAKq2E,kBAAkB90E,OAAM,IAC/BvB,KAAKq2E,kBAAkB1yE,SAGZ,IAAX8hF,GAA2B,IAAXA,IAClBzlF,KAAKs2E,eAAeryE,KAAKjE,KAAKo2E,WAC1Bp2E,KAAKs2E,eAAe/0E,OAAM,IAC5BvB,KAAKs2E,eAAe3yE,SAGxB,MACF,KAAK,GACY,IAAX8hF,GAA2B,IAAXA,GACdzlF,KAAKq2E,kBAAkB90E,QACzBvB,KAAKu8E,SAASv8E,KAAKq2E,kBAAkB5wE,OAG1B,IAAXggF,GAA2B,IAAXA,GACdzlF,KAAKs2E,eAAe/0E,QACtBvB,KAAKw8E,YAAYx8E,KAAKs2E,eAAe7wE,OAK7C,OAAO,CACT,CAWO,UAAAy1E,CAAWrD,GAUhB,OATA73E,KAAK23E,cAAcyN,OAASplF,KAAK23E,cAAc9iE,EAC/C7U,KAAK23E,cAAc0N,OAASrlF,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAC1EnU,KAAK23E,cAAc2N,iBAAiBr5E,GAAKjM,KAAK01E,aAAazpE,GAC3DjM,KAAK23E,cAAc2N,iBAAiBt5E,GAAKhM,KAAK01E,aAAa1pE,GAC3DhM,KAAK23E,cAAc4N,aAAevlF,KAAKgxE,gBAAgBsO,QACvDt/E,KAAK23E,cAAc+N,cAAgB1lF,KAAKgxE,gBAAgB2U,SAASp+E,QACjEvH,KAAK23E,cAAciO,YAAc5lF,KAAKgxE,gBAAgB6U,OACtD7lF,KAAK23E,cAAcmO,gBAAkB9lF,KAAKovB,aAAa/kB,gBAAgBg5B,OACvErjC,KAAK23E,cAAcoO,oBAAsB/lF,KAAKovB,aAAa/kB,gBAAgBy5B,YACpE,CACT,CAWO,aAAAs3C,CAAcvD,GACnB73E,KAAK23E,cAAc9iE,EAAI7U,KAAK23E,cAAcyN,QAAU,EACpDplF,KAAK23E,cAAcxjE,EAAIQ,KAAKkZ,IAAI7tB,KAAK23E,cAAc0N,OAASrlF,KAAK23E,cAAcnjE,MAAO,GACtFxU,KAAK01E,aAAazpE,GAAKjM,KAAK23E,cAAc2N,iBAAiBr5E,GAC3DjM,KAAK01E,aAAa1pE,GAAKhM,KAAK23E,cAAc2N,iBAAiBt5E,GAC3D,IAAK,IAAIlN,EAAI,EAAGA,EAAIkB,KAAK23E,cAAc+N,cAAcnkF,OAAQzC,IAC3DkB,KAAKgxE,gBAAgBgS,YAAYlkF,EAAGkB,KAAK23E,cAAc+N,cAAc5mF,IAMvE,OAJAkB,KAAKgxE,gBAAgBsM,UAAUt9E,KAAK23E,cAAciO,aAClD5lF,KAAKovB,aAAa/kB,gBAAgBg5B,OAASrjC,KAAK23E,cAAcmO,gBAC9D9lF,KAAKovB,aAAa/kB,gBAAgBy5B,WAAa9jC,KAAK23E,cAAcoO,oBAClE/lF,KAAKghF,mBACE,CACT,CAaO,QAAAzE,CAASt/D,GAGd,OAFAjd,KAAKm2E,aAAel5D,EACpBjd,KAAK2P,eAAesB,KAAKgM,IAClB,CACT,CAMO,WAAAu/D,CAAYv/D,GAEjB,OADAjd,KAAKo2E,UAAYn5D,GACV,CACT,CAWO,uBAAAw/D,CAAwBx/D,GAC7B,MAAM1O,EAAqB,GACrBy3E,EAAQ/oE,EAAK8hE,MAAM,KACzB,KAAOiH,EAAMzkF,OAAS,GAAG,CACvB,MAAM6xE,EAAM4S,EAAMriF,QACZsiF,EAAOD,EAAMriF,QACnB,GAAI,QAAQuiF,KAAK9S,GAAM,CACrB,MAAM/gE,EAAQxK,SAASurE,EAAK,IAC5B,GAAI+S,EAAkB9zE,GACpB,GAAa,MAAT4zE,EACF13E,EAAMtK,KAAK,CAAEuN,KAAI,EAA2Ba,cACvC,CACL,MAAME,GAAQ,EAAA5E,EAAA86D,YAAWwd,GACrB1zE,GACFhE,EAAMtK,KAAK,CAAEuN,KAAI,EAAwBa,QAAOE,SAEpD,CAEJ,CACF,CAIA,OAHIhE,EAAMhN,QACRvB,KAAKi3E,SAAShmE,KAAK1C,IAEd,CACT,CAmBO,YAAAmuE,CAAaz/D,GAElB,MAAMm2D,EAAMn2D,EAAKk+C,QAAQ,KACzB,IAAa,IAATiY,EAEF,OAAO,EAET,MAAMj5C,EAAKld,EAAK1V,MAAM,EAAG6rE,GAAKphC,OACxB7mB,EAAMlO,EAAK1V,MAAM6rE,EAAM,GAC7B,OAAIjoD,EACKnrB,KAAKomF,iBAAiBjsD,EAAIhP,IAE/BgP,EAAG6X,QAGAhyC,KAAKqmF,kBACd,CAEQ,gBAAAD,CAAiBvO,EAAgB1sD,GAEnCnrB,KAAKy+E,qBACPz+E,KAAKqmF,mBAEP,MAAMC,EAAezO,EAAOkH,MAAM,KAClC,IAAI5kD,EACJ,MAAMosD,EAAeD,EAAaE,UAAUrlF,GAAKA,EAAEi8B,WAAW,QAO9D,OANsB,IAAlBmpD,IACFpsD,EAAKmsD,EAAaC,GAAch/E,MAAM,SAAM3C,GAE9C5E,KAAK01E,aAAa1qD,SAAWhrB,KAAK01E,aAAa1qD,SAASuuB,QACxDv5C,KAAK01E,aAAa1qD,SAASC,MAAQjrB,KAAKmqB,gBAAgBs8D,aAAa,CAAEtsD,KAAIhP,QAC3EnrB,KAAK01E,aAAasP,kBACX,CACT,CAEQ,gBAAAqB,GAIN,OAHArmF,KAAK01E,aAAa1qD,SAAWhrB,KAAK01E,aAAa1qD,SAASuuB,QACxDv5C,KAAK01E,aAAa1qD,SAASC,MAAQ,EACnCjrB,KAAK01E,aAAasP,kBACX,CACT,CAUQ,wBAAA0B,CAAyBzpE,EAAcpW,GAC7C,MAAMm/E,EAAQ/oE,EAAK8hE,MAAM,KACzB,IAAK,IAAIjgF,EAAI,EAAGA,EAAIknF,EAAMzkF,UACpBsF,GAAU7G,KAAKw3E,eAAej2E,UADAzC,IAAK+H,EAEvC,GAAiB,MAAbm/E,EAAMlnF,GACRkB,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,EAA2Ba,MAAOrS,KAAKw3E,eAAe3wE,UAC3E,CACL,MAAM0L,GAAQ,EAAA5E,EAAA86D,YAAWud,EAAMlnF,IAC3ByT,GACFvS,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,EAAwBa,MAAOrS,KAAKw3E,eAAe3wE,GAAS0L,UAE1F,CAEF,OAAO,CACT,CAwBO,kBAAAoqE,CAAmB1/D,GACxB,OAAOjd,KAAK0mF,yBAAyBzpE,EAAM,EAC7C,CAOO,kBAAA2/D,CAAmB3/D,GACxB,OAAOjd,KAAK0mF,yBAAyBzpE,EAAM,EAC7C,CAOO,sBAAA4/D,CAAuB5/D,GAC5B,OAAOjd,KAAK0mF,yBAAyBzpE,EAAM,EAC7C,CAUO,mBAAA6/D,CAAoB7/D,GACzB,IAAKA,EAEH,OADAjd,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,MACnB,EAET,MAAMjD,EAAqB,GACrBy3E,EAAQ/oE,EAAK8hE,MAAM,KACzB,IAAK,IAAIjgF,EAAI,EAAGA,EAAIknF,EAAMzkF,SAAUzC,EAClC,GAAI,QAAQonF,KAAKF,EAAMlnF,IAAK,CAC1B,MAAMuT,EAAQxK,SAASm+E,EAAMlnF,GAAI,IAC7BqnF,EAAkB9zE,IACpB9D,EAAMtK,KAAK,CAAEuN,KAAI,EAA4Ba,SAEjD,CAKF,OAHI9D,EAAMhN,QACRvB,KAAKi3E,SAAShmE,KAAK1C,IAEd,CACT,CAOO,cAAAwuE,CAAe9/D,GAEpB,OADAjd,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,EAA4Ba,MAAK,QACpD,CACT,CAOO,cAAA2qE,CAAe//D,GAEpB,OADAjd,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,EAA4Ba,MAAK,QACpD,CACT,CAOO,kBAAA4qE,CAAmBhgE,GAExB,OADAjd,KAAKi3E,SAAShmE,KAAK,CAAC,CAAEO,KAAI,EAA4Ba,MAAK,QACpD,CACT,CAWO,QAAAka,GAGL,OAFAvsB,KAAK23E,cAAc9iE,EAAI,EACvB7U,KAAKqS,SACE,CACT,CAOO,qBAAA8qE,GAIL,OAHAn9E,KAAK8W,YAAYC,MAAM,6CACvB/W,KAAKovB,aAAa/kB,gBAAgB64B,mBAAoB,EACtDljC,KAAK42E,wBAAwB3lE,QACtB,CACT,CAOO,iBAAAmsE,GAIL,OAHAp9E,KAAK8W,YAAYC,MAAM,oCACvB/W,KAAKovB,aAAa/kB,gBAAgB64B,mBAAoB,EACtDljC,KAAK42E,wBAAwB3lE,QACtB,CACT,CAQO,oBAAAssE,GAGL,OAFAv9E,KAAKgxE,gBAAgBsM,UAAU,GAC/Bt9E,KAAKgxE,gBAAgBgS,YAAY,EAAGvP,EAAAwP,kBAC7B,CACT,CAkBO,aAAAvF,CAAciJ,GACnB,OAA8B,IAA1BA,EAAeplF,QACjBvB,KAAKu9E,wBACE,IAEiB,MAAtBoJ,EAAe,IAGnB3mF,KAAKgxE,gBAAgBgS,YAAYhP,EAAO2S,EAAe,IAAKlT,EAAAgK,SAASkJ,EAAe,KAAOlT,EAAAwP,kBAFlF,EAIX,CAWO,KAAA5wE,GAUL,OATArS,KAAKghF,kBACLhhF,KAAK23E,cAAcxjE,IACfnU,KAAK23E,cAAcxjE,IAAMnU,KAAK23E,cAAcjG,aAAe,GAC7D1xE,KAAK23E,cAAcxjE,IACnBnU,KAAK8R,eAAeqgE,OAAOnyE,KAAKsgF,mBACvBtgF,KAAK23E,cAAcxjE,GAAKnU,KAAK8R,eAAe/Q,OACrDf,KAAK23E,cAAcxjE,EAAInU,KAAK8R,eAAe/Q,KAAO,GAEpDf,KAAKghF,mBACE,CACT,CAYO,MAAA3E,GAEL,OADAr8E,KAAK23E,cAAc8J,KAAKzhF,KAAK23E,cAAc9iE,IAAK,GACzC,CACT,CAWO,YAAAqoE,GAEL,GADAl9E,KAAKghF,kBACDhhF,KAAK23E,cAAcxjE,IAAMnU,KAAK23E,cAAc3lD,UAAW,CAIzD,MAAM40D,EAAqB5mF,KAAK23E,cAAcjG,aAAe1xE,KAAK23E,cAAc3lD,UAChFhyB,KAAK23E,cAActzE,MAAMgoE,cAAcrsE,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAAGyyE,EAAoB,GAC5G5mF,KAAK23E,cAActzE,MAAMS,IAAI9E,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAAGnU,KAAK23E,cAAc/2D,aAAa5gB,KAAKsgF,mBACnHtgF,KAAKy3E,iBAAiBhG,eAAezxE,KAAK23E,cAAc3lD,UAAWhyB,KAAK23E,cAAcjG,aACxF,MACE1xE,KAAK23E,cAAcxjE,IACnBnU,KAAKghF,kBAEP,OAAO,CACT,CASO,SAAA3D,GAGL,OAFAr9E,KAAKqiC,QAAQ/wB,QACbtR,KAAK02E,gBAAgBzlE,QACd,CACT,CAEO,KAAAK,GACLtR,KAAK01E,aAAehoE,EAAAmT,kBAAkB04B,QACtCv5C,KAAKu2E,uBAAyB7oE,EAAAmT,kBAAkB04B,OAClD,CAKQ,cAAA+mC,GAGN,OAFAtgF,KAAKu2E,uBAAuBvqE,KAAM,SAClChM,KAAKu2E,uBAAuBvqE,IAA6B,SAAvBhM,KAAK01E,aAAa1pE,GAC7ChM,KAAKu2E,sBACd,CAYO,SAAA+G,CAAUuJ,GAEf,OADA7mF,KAAKgxE,gBAAgBsM,UAAUuJ,IACxB,CACT,CAUO,sBAAAlJ,GAEL,MAAMj1E,EAAO,IAAIuhB,EAAAI,SACjB3hB,EAAKguD,QAAU,GAAC,GAA0B,IAAIj3C,WAAW,GACzD/W,EAAKuD,GAAKjM,KAAK01E,aAAazpE,GAC5BvD,EAAKsD,GAAKhM,KAAK01E,aAAa1pE,GAG5BhM,KAAKohF,WAAW,EAAG,GACnB,IAAK,IAAI0F,EAAU,EAAGA,EAAU9mF,KAAK8R,eAAe/Q,OAAQ+lF,EAAS,CACnE,MAAMl/E,EAAM5H,KAAK23E,cAAcnjE,MAAQxU,KAAK23E,cAAcxjE,EAAI2yE,EACxDviF,EAAOvE,KAAK23E,cAActzE,MAAMP,IAAI8D,GACtCrD,IACFA,EAAKulC,KAAKphC,GACVnE,EAAK2nB,WAAY,EAErB,CAGA,OAFAlsB,KAAKy3E,iBAAiBsP,eACtB/mF,KAAKohF,WAAW,EAAG,IACZ,CACT,CA6BO,mBAAAtD,CAAoB7gE,EAAc46D,GACvC,MAMMtzD,EAAIvkB,KAAK8R,eAAe3N,OACxBmwC,EAAOt0C,KAAKkqB,gBAAgB5f,WAGlC,MAVU,CAACsiE,IACT5sE,KAAKovB,aAAa5kB,iBAAiB,IAAYoiE,SACxC,GAQiBkX,CAAb,OAAT7mE,EAAwB,OAAOjd,KAAK01E,aAAasR,cAAgB,EAAI,MAC5D,OAAT/pE,EAAwB,aACf,MAATA,EAAuB,OAAOsH,EAAEyN,UAAY,KAAKzN,EAAEmtD,aAAe,KAEzD,MAATz0D,EAAuB,SACd,OAATA,EAAwB,OAPc,CAAEgqE,MAAS,EAAGv+D,UAAa,EAAGw+D,IAAO,GAOrC5yC,EAAKpK,cAAgBoK,EAAKrK,YAAc,EAAI,OAC7E,OACX,CAEO,cAAAwnC,CAAe9nD,EAAYE,GAChC7pB,KAAKy3E,iBAAiBhG,eAAe9nD,EAAIE,EAC3C,CAWO,gBAAA4xD,CAAiB5D,GACtB,IAAK73E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cACjD,OAAO,EAET,MAAMC,EAAQ+c,EAAOA,OAAO,IAAM,EAC5BoM,EAAOpM,EAAOt2E,OAAS,GAAKs2E,EAAOA,OAAO,IAAW,EACrD91D,EAAQ/hB,KAAKovB,aAAayrC,cAEhC,OAAQopB,GACN,KAAK,EACHliE,EAAM+4C,MAAQA,EACd,MACF,KAAK,EACH/4C,EAAM+4C,OAASA,EACf,MACF,KAAK,EACH/4C,EAAM+4C,QAAUA,EAGpB,OAAO,CACT,CASO,kBAAA4gB,CAAmB7D,GACxB,IAAK73E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cACjD,OAAO,EAET,MAAMC,EAAQ96D,KAAKovB,aAAayrC,cAAcC,MAE9C,OADA96D,KAAKovB,aAAa5kB,iBAAiB,MAAcswD,OAC1C,CACT,CAQO,iBAAA6gB,CAAkB9D,GACvB,IAAK73E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cACjD,OAAO,EAET,MAAMC,EAAQ+c,EAAOA,OAAO,IAAM,EAC5B91D,EAAQ/hB,KAAKovB,aAAayrC,cAE1BssB,EADQnnF,KAAK8R,eAAe3N,SAAWnE,KAAK8R,eAAe0B,QAAQ4f,IACnDrR,EAAMqlE,SAAWrlE,EAAMslE,UAU7C,OAPIF,EAAM5lF,QAAU,IAClB4lF,EAAMxjF,QAIRwjF,EAAMljF,KAAK8d,EAAM+4C,OACjB/4C,EAAM+4C,MAAQA,GACP,CACT,CAQO,gBAAA8gB,CAAiB/D,GACtB,IAAK73E,KAAKkqB,gBAAgB5f,WAAW0wD,cAAcH,cACjD,OAAO,EAET,MAAM36B,EAAQvrB,KAAKkZ,IAAI,EAAGgqD,EAAOA,OAAO,IAAM,GACxC91D,EAAQ/hB,KAAKovB,aAAayrC,cAE1BssB,EADQnnF,KAAK8R,eAAe3N,SAAWnE,KAAK8R,eAAe0B,QAAQ4f,IACnDrR,EAAMqlE,SAAWrlE,EAAMslE,UAG7C,IAAK,IAAIvoF,EAAI,EAAGA,EAAIohC,GAASinD,EAAM5lF,OAAS,EAAGzC,IAC7CijB,EAAM+4C,MAAQqsB,EAAM1hF,MAMtB,OAHqB,IAAjB0hF,EAAM5lF,QAAgB2+B,EAAQ,IAChCne,EAAM+4C,MAAQ,IAET,CACT,mBAeF,IAAM4c,EAAN,MAIE,WAAAh4E,CACmCoS,uBAAAA,EAEjC9R,KAAKg/E,YACP,CAEO,UAAAA,GACLh/E,KAAKqC,MAAQrC,KAAK8R,eAAe3N,OAAOgQ,EACxCnU,KAAKsC,IAAMtC,KAAK8R,eAAe3N,OAAOgQ,CACxC,CAEO,SAAAsrE,CAAUtrE,GACXA,EAAInU,KAAKqC,MACXrC,KAAKqC,MAAQ8R,EACJA,EAAInU,KAAKsC,MAClBtC,KAAKsC,IAAM6R,EAEf,CAEO,cAAAs9D,CAAe9nD,EAAYE,GAC5BF,EAAKE,IACP2rD,EAAQ7rD,EACRA,EAAKE,EACLA,EAAK2rD,GAEH7rD,EAAK3pB,KAAKqC,QACZrC,KAAKqC,MAAQsnB,GAEXE,EAAK7pB,KAAKsC,MACZtC,KAAKsC,IAAMunB,EAEf,CAEO,YAAAk9D,GACL/mF,KAAKyxE,eAAe,EAAGzxE,KAAK8R,eAAe/Q,KAAO,EACpD,GAGF,SAAAolF,EAAkC17E,GAChC,OAAO,GAAKA,GAASA,EAAQ,GAC/B,CA5CMitE,EAAenuE,EAAA,CAKhBC,EAAA,EAAAnK,EAAAyqB,iBALC4tD,cCrjHN,SAAAj0E,EAA6BqwD,GAC3B,MAAO,CAAEz6C,QAASy6C,EACpB,CAKA,SAAAz6C,EAA+CiuE,GAC7C,IAAKA,EACH,OAAOA,EAET,GAAI/b,MAAM8H,QAAQiU,GAAM,CACtB,IAAK,MAAM75C,KAAK65C,EACd75C,EAAEp0B,UAEJ,MAAO,EACT,CAEA,OADAiuE,EAAIjuE,UACGiuE,CACT,8JAEA,YAAsCxU,GACpC,OAAOrvE,EAAa,IAAM4V,EAAQy5D,GACpC,EAEA,MAAAj3B,EAAA,WAAAn8C,GACmBM,KAAAunF,aAAe,IAAI//D,IAC5BxnB,KAAA0qE,aAAc,CAgCxB,CA9BE,cAAWtzC,GACT,OAAOp3B,KAAK0qE,WACd,CAEO,GAAA/pE,CAA2B6mF,GAMhC,OALIxnF,KAAK0qE,YACP8c,EAAEnuE,UAEFrZ,KAAKunF,aAAa5mF,IAAI6mF,GAEjBA,CACT,CAEO,OAAAnuE,GACL,IAAIrZ,KAAK0qE,YAAT,CAGA1qE,KAAK0qE,aAAc,EACnB,IAAK,MAAMj9B,KAAKztC,KAAKunF,aACnB95C,EAAEp0B,UAEJrZ,KAAKunF,aAAal7E,OALlB,CAMF,CAEO,KAAAA,GACL,IAAK,MAAMohC,KAAKztC,KAAKunF,aACnB95C,EAAEp0B,UAEJrZ,KAAKunF,aAAal7E,OACpB,sBAGF,MAAA5M,EAAA,WAAAC,GAGqBM,KAAAm3B,OAAS,IAAI0kB,CASlC,CAPS,OAAAxiC,GACLrZ,KAAKm3B,OAAO9d,SACd,CAEU,SAAA3X,CAAiC8lF,GACzC,OAAOxnF,KAAKm3B,OAAOx2B,IAAI6mF,EACzB,iBAVuB/nF,EAAAixD,KAAoB9nD,OAAO+lB,OAAO,CAAE,OAAAtV,GAAY,wBAazE,iBAAA3Z,GAEUM,KAAA0qE,aAAc,CAuBxB,CArBE,SAAWjgE,GACT,OAAOzK,KAAK0qE,iBAAc9lE,EAAY5E,KAAKynF,MAC7C,CAEA,SAAWh9E,CAAMA,GACXzK,KAAK0qE,aAAejgE,IAAUzK,KAAKynF,SAGvCznF,KAAKynF,QAAQpuE,UACbrZ,KAAKynF,OAASh9E,EAChB,CAEO,KAAA4B,GACLrM,KAAKyK,WAAQ7F,CACf,CAEO,OAAAyU,GACLrZ,KAAK0qE,aAAc,EACnB1qE,KAAKynF,QAAQpuE,UACbrZ,KAAKynF,YAAS7iF,CAChB,+FC1GF,MAAAiH,EAAA,WAAAnM,GACUM,KAAA0nF,MAA8F,EAgBxG,CAdS,GAAA5iF,CAAImiE,EAAewe,EAAiBh7E,GACpCzK,KAAK0nF,MAAMzgB,KACdjnE,KAAK0nF,MAAMzgB,GAAS,IAEtBjnE,KAAK0nF,MAAMzgB,GAA2Bwe,GAAUh7E,CAClD,CAEO,GAAA3G,CAAImjE,EAAewe,GACxB,OAAOzlF,KAAK0nF,MAAMzgB,GAA4BjnE,KAAK0nF,MAAMzgB,GAA2Bwe,QAAU7gF,CAChG,CAEO,KAAAyH,GACLrM,KAAK0nF,MAAQ,EACf,6BAGF,iBAAAhoF,GACUM,KAAA0nF,MAAwE,IAAI77E,CAgBtF,CAdS,GAAA/G,CAAImiE,EAAewe,EAAiBkC,EAAeC,EAAiBn9E,GACpEzK,KAAK0nF,MAAM5jF,IAAImjE,EAAOwe,IACzBzlF,KAAK0nF,MAAM5iF,IAAImiE,EAAOwe,EAAQ,IAAI55E,GAEpC7L,KAAK0nF,MAAM5jF,IAAImjE,EAAOwe,GAAS3gF,IAAI6iF,EAAOC,EAAQn9E,EACpD,CAEO,GAAA3G,CAAImjE,EAAewe,EAAiBkC,EAAeC,GACxD,OAAO5nF,KAAK0nF,MAAM5jF,IAAImjE,EAAOwe,IAAS3hF,IAAI6jF,EAAOC,EACnD,CAEO,KAAAv7E,GACLrM,KAAK0nF,MAAMr7E,OACb,0LCRF,SAA8Bw7E,GAC5B,OAAO,CACT,qBACA,WACE,IAAKppF,EAAAqiD,SACH,OAAO,EAET,MAAMgnC,EAAe3nC,EAAUC,MAAM,kBACrC,OAAqB,OAAjB0nC,GAAyBA,EAAavmF,OAAS,EAC1C,EAEFsG,SAASigF,EAAa,GAAI,GACnC,EAzBarpF,EAAAspF,SAA6B,oBAAZC,WAA2B,UAAYA,UAAyC,oBAAd9nC,YAA6BA,UAAUC,UAAU/iB,WAAW,aAC5J,MAAM+iB,EAAa1hD,EAAM,OAAI,OAASyhD,UAAUC,UAC1ChM,EAAY11C,EAAM,OAAI,OAASyhD,UAAU/L,SAElC11C,EAAAkX,UAAYwqC,EAAU10B,SAAS,WAC/BhtB,EAAAuhD,SAAWG,EAAU10B,SAAS,UAC9BhtB,EAAAwpF,aAAe9nC,EAAU10B,SAAS,QAClChtB,EAAAqiD,SAAW,iCAAiC98C,KAAKm8C,GAuBjD1hD,EAAAkgB,MAAQ,CAAC,YAAa,WAAY,SAAU,UAAU8M,SAAS0oB,GAC/D11C,EAAAqhB,UAAY,CAAC,UAAW,QAAS,QAAS,SAAS2L,SAAS0oB,GAC5D11C,EAAAsX,QAAUo+B,EAASgnB,QAAQ,UAAY,EAEvC18D,EAAAuZ,WAAa,WAAWhU,KAAKm8C,qFChD1C,MAAAif,EAAAlgE,EAAA,MAIA,IAAIJ,EAAI,eAQR,MAWE,WAAAY,CACmBwoF,EACjBC,GADiBnoF,KAAAkoF,QAAAA,EAXXloF,KAAAsrE,OAAc,GAELtrE,KAAAooF,gBAAuB,GAEhCpoF,KAAAqoF,qBAAsB,EAEbroF,KAAAsoF,gBAA4B,GAErCtoF,KAAAuoF,oBAAqB,EAM3BvoF,KAAKwoF,mBAAqB,IAAIppB,EAAAqpB,cAAcN,GAC5CnoF,KAAK0oF,kBAAoB,IAAItpB,EAAAqpB,cAAcN,EAC7C,CAEO,KAAA97E,GACLrM,KAAKsrE,OAAO/pE,OAAS,EACrBvB,KAAKooF,gBAAgB7mF,OAAS,EAC9BvB,KAAKwoF,mBAAmBn8E,QACxBrM,KAAKqoF,qBAAsB,EAC3BroF,KAAKsoF,gBAAgB/mF,OAAS,EAC9BvB,KAAK0oF,kBAAkBr8E,QACvBrM,KAAKuoF,oBAAqB,CAC5B,CAEO,MAAAI,CAAOl+E,GACZzK,KAAK4oF,uBAC+B,IAAhC5oF,KAAKooF,gBAAgB7mF,QACvBvB,KAAKwoF,mBAAmBK,QAAQ,IAAM7oF,KAAK8oF,kBAE7C9oF,KAAKooF,gBAAgBnkF,KAAKwG,EAC5B,CAEQ,cAAAq+E,GACN,MAAMC,EAAoB/oF,KAAKooF,gBAAgB5lE,KAAK,CAAC3jB,EAAG0lB,IAAMvkB,KAAKkoF,QAAQrpF,GAAKmB,KAAKkoF,QAAQ3jE,IAC7F,IAAIykE,EAAyB,EACzBC,EAAa,EAEjB,MAAMrd,EAAW,IAAIL,MAAMvrE,KAAKsrE,OAAO/pE,OAASvB,KAAKooF,gBAAgB7mF,QAErE,IAAK,IAAI2nF,EAAgB,EAAGA,EAAgBtd,EAASrqE,OAAQ2nF,IACvDD,GAAcjpF,KAAKsrE,OAAO/pE,QAAUvB,KAAKkoF,QAAQa,EAAkBC,KAA4BhpF,KAAKkoF,QAAQloF,KAAKsrE,OAAO2d,KAC1Hrd,EAASsd,GAAiBH,EAAkBC,GAC5CA,KAEApd,EAASsd,GAAiBlpF,KAAKsrE,OAAO2d,KAI1CjpF,KAAKsrE,OAASM,EACd5rE,KAAKooF,gBAAgB7mF,OAAS,CAChC,CAEQ,qBAAA4nF,IACDnpF,KAAKqoF,qBAAuBroF,KAAKooF,gBAAgB7mF,OAAS,GAC7DvB,KAAKwoF,mBAAmBpnB,OAE5B,CAEO,OAAO32D,GAEZ,GADAzK,KAAKmpF,wBACsB,IAAvBnpF,KAAKsrE,OAAO/pE,OACd,OAAO,EAET,MAAM0B,EAAMjD,KAAKkoF,QAAQz9E,GACzB,YAAY7F,IAAR3B,MAGAjD,KAAKopF,aAAa3+E,EAAOxH,IAUO,IAAhCjD,KAAKsoF,gBAAgB/mF,SAGzBvB,KAAK4oF,uBACE5oF,KAAKopF,aAAa3+E,EAAOxH,IAClC,CAEQ,YAAAmmF,CAAa3+E,EAAUxH,GAE7B,GADAnE,EAAIkB,KAAKqpF,QAAQpmF,IACN,IAAPnE,EACF,OAAO,EAET,GAAIkB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,EACnC,OAAO,EAET,GACE,GAAIjD,KAAKsrE,OAAOxsE,KAAO2L,EAKrB,OAJoC,IAAhCzK,KAAKsoF,gBAAgB/mF,QACvBvB,KAAK0oF,kBAAkBG,QAAQ,IAAM7oF,KAAKspF,iBAE5CtpF,KAAKsoF,gBAAgBrkF,KAAKnF,IACnB,UAEAA,EAAIkB,KAAKsrE,OAAO/pE,QAAUvB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,GACtE,OAAO,CACT,CAEQ,aAAAqmF,GACNtpF,KAAKuoF,oBAAqB,EAC1B,MAAMgB,EAAuBvpF,KAAKsoF,gBAAgB9lE,KAAK,CAAC3jB,EAAG0lB,IAAM1lB,EAAI0lB,GACrE,IAAIilE,EAA4B,EAChC,MAAM5d,EAAW,IAAIL,MAAMvrE,KAAKsrE,OAAO/pE,OAASgoF,EAAqBhoF,QACrE,IAAI2nF,EAAgB,EACpB,IAAK,IAAIpqF,EAAI,EAAGA,EAAIkB,KAAKsrE,OAAO/pE,OAAQzC,IAClCyqF,EAAqBC,KAA+B1qF,EACtD0qF,IAEA5d,EAASsd,KAAmBlpF,KAAKsrE,OAAOxsE,GAG5CkB,KAAKsrE,OAASM,EACd5rE,KAAKsoF,gBAAgB/mF,OAAS,EAC9BvB,KAAKuoF,oBAAqB,CAC5B,CAEQ,oBAAAK,IACD5oF,KAAKuoF,oBAAsBvoF,KAAKsoF,gBAAgB/mF,OAAS,GAC5DvB,KAAK0oF,kBAAkBtnB,OAE3B,CAEO,eAACqoB,CAAexmF,GAGrB,GAFAjD,KAAKmpF,wBACLnpF,KAAK4oF,uBACsB,IAAvB5oF,KAAKsrE,OAAO/pE,SAGhBzC,EAAIkB,KAAKqpF,QAAQpmF,KACbnE,EAAI,GAAKA,GAAKkB,KAAKsrE,OAAO/pE,SAG1BvB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,GAGrC,SACQjD,KAAKsrE,OAAOxsE,WACTA,EAAIkB,KAAKsrE,OAAO/pE,QAAUvB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,EACxE,CAEO,YAAAymF,CAAazmF,EAAaqnB,GAG/B,GAFAtqB,KAAKmpF,wBACLnpF,KAAK4oF,uBACsB,IAAvB5oF,KAAKsrE,OAAO/pE,SAGhBzC,EAAIkB,KAAKqpF,QAAQpmF,KACbnE,EAAI,GAAKA,GAAKkB,KAAKsrE,OAAO/pE,SAG1BvB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,GAGrC,GACEqnB,EAAStqB,KAAKsrE,OAAOxsE,YACZA,EAAIkB,KAAKsrE,OAAO/pE,QAAUvB,KAAKkoF,QAAQloF,KAAKsrE,OAAOxsE,MAAQmE,EACxE,CAEO,MAAAshC,GAIL,OAHAvkC,KAAKmpF,wBACLnpF,KAAK4oF,uBAEE,IAAI5oF,KAAKsrE,QAAQ/mC,QAC1B,CAEQ,OAAA8kD,CAAQpmF,GACd,IAAI2R,EAAM,EACNiZ,EAAM7tB,KAAKsrE,OAAO/pE,OAAS,EAC/B,KAAOssB,GAAOjZ,GAAK,CACjB,IAAI+0E,EAAO/0E,EAAMiZ,GAAQ,EACzB,MAAM+7D,EAAS5pF,KAAKkoF,QAAQloF,KAAKsrE,OAAOqe,IACxC,GAAIC,EAAS3mF,EACX4qB,EAAM87D,EAAM,MACP,MAAIC,EAAS3mF,GAEb,CAEL,KAAO0mF,EAAM,GAAK3pF,KAAKkoF,QAAQloF,KAAKsrE,OAAOqe,EAAM,MAAQ1mF,GACvD0mF,IAEF,OAAOA,CACT,CAPE/0E,EAAM+0E,EAAM,CAOd,CACF,CAGA,OAAO/0E,CACT,6GC9MF,MAAAi1E,EAAA,WAAAnqF,GACUM,KAAA8pF,QAAoB,GACpB9pF,KAAAyrE,QAAU,CAmBpB,CAjBE,UAAWlqE,GACT,OAAOvB,KAAKyrE,OACd,CAEO,KAAAn6D,GACLtR,KAAK8pF,QAAQvoF,OAAS,EACtBvB,KAAKyrE,QAAU,CACjB,CAEO,MAAAse,CAAOC,GACZhqF,KAAK8pF,QAAQ7lF,KAAK+lF,GAClBhqF,KAAKyrE,SAAWue,EAAMzoF,MACxB,CAEO,QAAA+C,GACL,OAAOtE,KAAK8pF,QAAQt4D,KAAK,GAC3B,2CAMF,MAGE,WAAA9xB,CAA6BuqF,GAAAjqF,KAAAiqF,OAAAA,EAFZjqF,KAAAkqF,SAAW,IAAIL,CAEe,CAE/C,UAAWtoF,GACT,OAAOvB,KAAKkqF,SAAS3oF,MACvB,CAEA,SAAW4oF,GACT,OAAOnqF,KAAKiqF,MACd,CAEO,KAAA34E,GACLtR,KAAKkqF,SAAS54E,OAChB,CAKO,MAAAy4E,CAAOC,GAEZ,OADAhqF,KAAKkqF,SAASH,OAAOC,GACjBhqF,KAAKkqF,SAAS3oF,OAASvB,KAAKiqF,SAC9BjqF,KAAKkqF,SAAS54E,SACP,EAGX,CAEO,QAAAhN,GACL,OAAOtE,KAAKkqF,SAAS5lF,UACvB,8HCjCF,MAAe8lF,EAMb,WAAA1qF,CAAYyoF,GALJnoF,KAAAqqF,OAAmC,GAEnCrqF,KAAAsqF,GAAK,EAIXtqF,KAAK8W,YAAcqxE,CACrB,CAKO,OAAAU,CAAQ0B,GACbvqF,KAAKqqF,OAAOpmF,KAAKsmF,GACjBvqF,KAAK2hE,QACP,CAEO,KAAAP,GACL,KAAOphE,KAAKsqF,GAAKtqF,KAAKqqF,OAAO9oF,QACtBvB,KAAKqqF,OAAOrqF,KAAKsqF,OACpBtqF,KAAKsqF,KAGTtqF,KAAKqM,OACP,CAEO,KAAAA,GACDrM,KAAKwqF,gBACPxqF,KAAKyqF,gBAAgBzqF,KAAKwqF,eAC1BxqF,KAAKwqF,mBAAgB5lF,GAEvB5E,KAAKsqF,GAAK,EACVtqF,KAAKqqF,OAAO9oF,OAAS,CACvB,CAEQ,MAAAogE,GACD3hE,KAAKwqF,gBACRxqF,KAAKwqF,cAAgBxqF,KAAK0qF,iBAAiB1qF,KAAK2qF,SAAS9oF,KAAK7B,OAElE,CAEQ,QAAA2qF,CAASC,GAEf,IAAIC,EADJ7qF,KAAKwqF,mBAAgB5lF,EAErB,IAEIkmF,EAFAC,EAAc,EACdC,EAAwBJ,EAASK,gBAErC,KAAOjrF,KAAKsqF,GAAKtqF,KAAKqqF,OAAO9oF,QAAQ,CAanC,GAZAspF,EAAex8D,YAAYC,MACtBtuB,KAAKqqF,OAAOrqF,KAAKsqF,OACpBtqF,KAAKsqF,KAKPO,EAAel2E,KAAKkZ,IAAI,EAAGQ,YAAYC,MAAQu8D,GAC/CE,EAAcp2E,KAAKkZ,IAAIg9D,EAAcE,GAGrCD,EAAoBF,EAASK,gBACX,IAAdF,EAAoBD,EAOtB,OAJIE,EAAwBH,GAAgB,IAC1C7qF,KAAK8W,YAAY/O,KAAK,4CAA4C4M,KAAK0qB,IAAI1qB,KAAK6d,MAAMw4D,EAAwBH,cAEhH7qF,KAAK2hE,SAGPqpB,EAAwBF,CAC1B,CACA9qF,KAAKqM,OACP,EAQF,MAAA6+E,UAAuCd,EAC3B,gBAAAM,CAAiBpgE,GACzB,OAAOmE,WAAW,IAAMnE,EAAStqB,KAAKmrF,gBAAgB,KACxD,CAEU,eAAAV,CAAgBx5B,GACxB9iC,aAAa8iC,EACf,CAEQ,eAAAk6B,CAAgBj4C,GACtB,MAAM5wC,EAAM+rB,YAAYC,MAAQ4kB,EAChC,MAAO,CACL+3C,cAAe,IAAMt2E,KAAKkZ,IAAI,EAAGvrB,EAAM+rB,YAAYC,OAEvD,wBAsBW7vB,EAAAgqF,cAAiB,wBAAyB1pF,WAnBvD,cAAoCqrF,EACxB,gBAAAM,CAAiBpgE,GACzB,OAAO8gE,oBAAoB9gE,EAC7B,CAEU,eAAAmgE,CAAgBx5B,GACxBo6B,mBAAmBp6B,EACrB,GAY2Fi6B,sBAM7F,MAGE,WAAAxrF,CAAYyoF,GACVnoF,KAAKsrF,OAAS,IAAI7sF,EAAAgqF,cAAcN,EAClC,CAEO,GAAArjF,CAAIylF,GACTvqF,KAAKsrF,OAAOj/E,QACZrM,KAAKsrF,OAAOzC,QAAQ0B,EACtB,CAEO,KAAAnpB,GACLphE,KAAKsrF,OAAOlqB,OACd,CAEO,OAAA/nD,GACLrZ,KAAKsrF,OAAOj/E,OACd,sFCrKW5N,EAAAokF,cAAgB,+GCA7B,SAA8C5jD,GAW5C,MAAM16B,EAAO06B,EAAc96B,OAAOE,MAAMP,IAAIm7B,EAAc96B,OAAOqQ,MAAQyqB,EAAc96B,OAAOgQ,EAAI,GAC5Fo3E,EAAWhnF,GAAMT,IAAIm7B,EAAch3B,KAAO,GAE1CskB,EAAW0S,EAAc96B,OAAOE,MAAMP,IAAIm7B,EAAc96B,OAAOqQ,MAAQyqB,EAAc96B,OAAOgQ,GAC9FoY,GAAYg/D,IACdh/D,EAASL,UAAaq/D,EAAS5mD,EAAA6mD,wBAA0B7mD,EAAAi8C,gBAAkB2K,EAAS5mD,EAAA6mD,wBAA0B7mD,EAAA8mD,qBAElH,EArBA,MAAA9mD,EAAAzlC,EAAA,yGCIA,MAAAuvC,EAAA,WAAA/uC,GAsBSM,KAAAiM,GAAK,EACLjM,KAAAgM,GAAK,EACLhM,KAAAgrB,SAA2B,IAAI0gE,CAmGxC,CA1HS,iBAAOl5E,CAAW/H,GACvB,MAAO,CACLA,IAAK,GAA4B,IACjCA,IAAK,EAA8B,IAC3B,IAARA,EAEJ,CAEO,mBAAO45E,CAAa55E,GACzB,OAAmB,IAAXA,EAAM,KAAS,IAAuC,IAAXA,EAAM,KAAS,EAAwC,IAAXA,EAAM,EACvG,CAEO,KAAA8uC,GACL,MAAMoyC,EAAS,IAAIl9C,EAInB,OAHAk9C,EAAO1/E,GAAKjM,KAAKiM,GACjB0/E,EAAO3/E,GAAKhM,KAAKgM,GACjB2/E,EAAO3gE,SAAWhrB,KAAKgrB,SAASuuB,QACzBoyC,CACT,CAQO,SAAAv8C,GAA4B,OAAc,SAAPpvC,KAAKiM,EAAsB,CAC9D,MAAA8hC,GAA4B,OAAc,UAAP/tC,KAAKiM,EAAmB,CAC3D,WAAA4hC,GACL,OAAI7tC,KAAK+qB,oBAAkD,IAA5B/qB,KAAKgrB,SAASqjB,eACpC,EAEK,UAAPruC,KAAKiM,EACd,CACO,OAAAqhC,GAA4B,OAAc,UAAPttC,KAAKiM,EAAoB,CAC5D,WAAAkiC,GAA4B,OAAc,WAAPnuC,KAAKiM,EAAwB,CAChE,QAAA+hC,GAA4B,OAAc,SAAPhuC,KAAKgM,EAAqB,CAC7D,KAAAoiC,GAA4B,OAAc,UAAPpuC,KAAKgM,EAAkB,CAC1D,eAAA4iC,GAA4B,OAAc,WAAP5uC,KAAKiM,EAA4B,CACpE,WAAA+6E,GAA4B,OAAc,UAAPhnF,KAAKgM,EAAwB,CAChE,UAAA8hC,GAA4B,OAAc,WAAP9tC,KAAKgM,EAAuB,CAG/D,cAAAgjC,GAA2B,OAAc,SAAPhvC,KAAKiM,EAAyB,CAChE,cAAAkjC,GAA2B,OAAc,SAAPnvC,KAAKgM,EAAyB,CAChE,OAAA4/E,GAA2B,QAAqC,UAA7B5rF,KAAKiM,GAAgD,CACxF,OAAA4/E,GAA2B,QAAqC,UAA7B7rF,KAAKgM,GAAgD,CACxF,WAAA8/E,GAA2B,OAAqC,WAAtB,SAAP9rF,KAAKiM,KAAgF,WAAtB,SAAPjM,KAAKiM,GAAiD,CACjJ,WAAA8/E,GAA2B,OAAqC,WAAtB,SAAP/rF,KAAKgM,KAAgF,WAAtB,SAAPhM,KAAKgM,GAAiD,CACjJ,WAAAggF,GAA2B,QAAe,SAAPhsF,KAAKiM,GAAgC,CACxE,WAAAggF,GAA2B,QAAe,SAAPjsF,KAAKgM,GAAgC,CACxE,kBAAAkgF,GAAgC,OAAmB,IAAZlsF,KAAKiM,IAAwB,IAAZjM,KAAKgM,EAAU,CAGvE,UAAA8iC,GACL,OAAe,SAAP9uC,KAAKiM,IACX,cACA,cAA0B,OAAc,IAAPjM,KAAKiM,GACtC,cAA0B,OAAc,SAAPjM,KAAKiM,GACtC,QAA0B,OAAQ,EAEtC,CACO,UAAAgjC,GACL,OAAe,SAAPjvC,KAAKgM,IACX,cACA,cAA0B,OAAc,IAAPhM,KAAKgM,GACtC,cAA0B,OAAc,SAAPhM,KAAKgM,GACtC,QAA0B,OAAQ,EAEtC,CAGO,gBAAA+e,GACL,OAAc,UAAP/qB,KAAKgM,EACd,CACO,cAAAg5E,GACDhlF,KAAKgrB,SAASmhE,UAChBnsF,KAAKgM,KAAM,UAEXhM,KAAKgM,IAAE,SAEX,CACO,iBAAA0iC,GACL,GAAY,UAAP1uC,KAAKgM,KAA+BhM,KAAKgrB,SAAS85D,eACrD,OAAoC,SAA5B9kF,KAAKgrB,SAAS85D,gBACpB,cACA,cAA0B,OAAmC,IAA5B9kF,KAAKgrB,SAAS85D,eAC/C,cAA0B,OAAmC,SAA5B9kF,KAAKgrB,SAAS85D,eAC/C,QAA0B,OAAO9kF,KAAK8uC,aAG1C,OAAO9uC,KAAK8uC,YACd,CACO,qBAAAs9C,GACL,OAAe,UAAPpsF,KAAKgM,KAA+BhM,KAAKgrB,SAAS85D,eAC1B,SAA5B9kF,KAAKgrB,SAAS85D,eACd9kF,KAAKgvC,gBACX,CACO,mBAAAT,GACL,OAAe,UAAPvuC,KAAKgM,KAA+BhM,KAAKgrB,SAAS85D,iBACH,UAAlD9kF,KAAKgrB,SAAS85D,gBACf9kF,KAAK4rF,SACX,CACO,uBAAAS,GACL,OAAe,UAAPrsF,KAAKgM,KAA+BhM,KAAKgrB,SAAS85D,eACH,WAAtB,SAA5B9kF,KAAKgrB,SAAS85D,iBACyC,WAAtB,SAA5B9kF,KAAKgrB,SAAS85D,gBACpB9kF,KAAK8rF,aACX,CACO,uBAAAx9C,GACL,OAAe,UAAPtuC,KAAKgM,KAA+BhM,KAAKgrB,SAAS85D,iBACzB,SAA5B9kF,KAAKgrB,SAAS85D,gBACf9kF,KAAKgsF,aACX,CACO,iBAAAM,GACL,OAAc,UAAPtsF,KAAKiM,GACA,UAAPjM,KAAKgM,GAA4BhM,KAAKgrB,SAASqjB,eAAgB,EACjE,CACL,CACO,yBAAAk+C,GACL,OAAOvsF,KAAKgrB,SAASwhE,sBACvB,oBAQF,MAAAd,EAEE,OAAWx9C,GACT,OAAIluC,KAAKysF,QAEQ,UAAZzsF,KAAK0sF,KACL1sF,KAAKquC,gBAAkB,GAGrBruC,KAAK0sF,IACd,CACA,OAAWx+C,CAAIzjC,GAAiBzK,KAAK0sF,KAAOjiF,CAAO,CAEnD,kBAAW4jC,GAET,OAAIruC,KAAKysF,OACP,GAEe,UAATzsF,KAAK0sF,OAAoC,EACnD,CACA,kBAAWr+C,CAAe5jC,GACxBzK,KAAK0sF,OAAQ,UACb1sF,KAAK0sF,MAASjiF,GAAS,GAAG,SAC5B,CAEA,kBAAWq6E,GACT,OAAmB,SAAZ9kF,KAAK0sF,IACd,CACA,kBAAW5H,CAAer6E,GACxBzK,KAAK0sF,OAAQ,SACb1sF,KAAK0sF,MAAgB,SAARjiF,CACf,CAGA,SAAWwgB,GACT,OAAOjrB,KAAKysF,MACd,CACA,SAAWxhE,CAAMxgB,GACfzK,KAAKysF,OAAShiF,CAChB,CAEA,0BAAW+hF,GACT,MAAMG,GAAgB,WAAT3sF,KAAK0sF,OAAmC,GACrD,OAAIC,EAAM,EACK,WAANA,EAEFA,CACT,CACA,0BAAWH,CAAuB/hF,GAChCzK,KAAK0sF,MAAQ,UACb1sF,KAAK0sF,MAASjiF,GAAS,GAAG,UAC5B,CAEA,WAAA/K,CACEwuC,EAAc,EACdjjB,EAAgB,GAtDVjrB,KAAA0sF,KAAe,EAgCf1sF,KAAAysF,OAAiB,EAwBvBzsF,KAAK0sF,KAAOx+C,EACZluC,KAAKysF,OAASxhE,CAChB,CAEO,KAAAsuB,GACL,OAAO,IAAImyC,EAAc1rF,KAAK0sF,KAAM1sF,KAAKysF,OAC3C,CAMO,OAAAN,GACL,OAA0B,IAAnBnsF,KAAKquC,gBAA0D,IAAhBruC,KAAKysF,MAC7D,oHC7MF,MAAAG,EAAA1tF,EAAA,MACAE,EAAAF,EAAA,MACAkgE,EAAAlgE,EAAA,MAGAmsC,EAAAnsC,EAAA,MACAwO,EAAAxO,EAAA,MACA2tF,EAAA3tF,EAAA,MACA4tF,EAAA5tF,EAAA,KACA+qB,EAAA/qB,EAAA,MACAylC,EAAAzlC,EAAA,MACA6tF,EAAA7tF,EAAA,MACAu0E,EAAAv0E,EAAA,MAGaT,EAAAuuF,gBAAkB,WAS/B,MAAAC,UAA4B7tF,EAAAK,WA2B1B,WAAAC,CACUwtF,EACAhjE,EACApY,EACSgF,GAEjB/W,QALQC,KAAAktF,eAAAA,EACAltF,KAAAkqB,gBAAAA,EACAlqB,KAAA8R,eAAAA,EACS9R,KAAA8W,YAAAA,EA7BZ9W,KAAAwE,MAAgB,EAChBxE,KAAAwU,MAAgB,EAChBxU,KAAAmU,EAAY,EACZnU,KAAA6U,EAAY,EAGZ7U,KAAAyhF,KAAkD,GAClDzhF,KAAAqlF,OAAiB,EACjBrlF,KAAAolF,OAAiB,EACjBplF,KAAAslF,iBAAmB53E,EAAAmT,kBAAkB04B,QACrCv5C,KAAAulF,aAAqC9R,EAAAwP,gBACrCjjF,KAAA0lF,cAA0C,GAC1C1lF,KAAA4lF,YAAsB,EACtB5lF,KAAA8lF,iBAA2B,EAC3B9lF,KAAA+lF,qBAA+B,EAC/B/lF,KAAA8d,QAAoB,GACnB9d,KAAAmtF,UAAuBljE,EAAAI,SAAS+iE,aAAa,CAAC,EAAGzoD,EAAA0oD,eAAgB1oD,EAAAk8C,gBAAiBl8C,EAAAi8C,iBAClF5gF,KAAAstF,gBAA6BrjE,EAAAI,SAAS+iE,aAAa,CAAC,EAAGzoD,EAAAiJ,qBAAsBjJ,EAAA4oD,sBAAuB5oD,EAAA8mD,uBAGpGzrF,KAAAwtF,aAAuB,EAEvBxtF,KAAAytF,uBAAyB,EAU/BztF,KAAK0tF,MAAQ1tF,KAAK8R,eAAe7J,KACjCjI,KAAK2tF,MAAQ3tF,KAAK8R,eAAe/Q,KACjCf,KAAKqE,MAAQ,IAAIuoF,EAAA7hB,aAA0B/qE,KAAK4tF,wBAAwB5tF,KAAK2tF,QAC7E3tF,KAAKgyB,UAAY,EACjBhyB,KAAK0xE,aAAe1xE,KAAK2tF,MAAQ,EACjC3tF,KAAK6tF,gBACL7tF,KAAK8tF,oBAAsB,IAAI1uB,EAAAqpB,cAAczoF,KAAK8W,aAClD9W,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAK8tF,oBAAoBzhF,UAC3DrM,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAK2gB,oBACvC3gB,KAAK+tF,aAAe/tF,KAAK0B,UAAU,IAAImrF,EAAAmB,sBACzC,CAEO,WAAArN,CAAY4D,GAUjB,OATIA,GACFvkF,KAAKmtF,UAAUlhF,GAAKs4E,EAAKt4E,GACzBjM,KAAKmtF,UAAUnhF,GAAKu4E,EAAKv4E,GACzBhM,KAAKmtF,UAAUniE,SAAWu5D,EAAKv5D,WAE/BhrB,KAAKmtF,UAAUlhF,GAAK,EACpBjM,KAAKmtF,UAAUnhF,GAAK,EACpBhM,KAAKmtF,UAAUniE,SAAW,IAAIqgB,EAAAqgD,eAEzB1rF,KAAKmtF,SACd,CAEO,iBAAAc,CAAkB1J,GAUvB,OATIA,GACFvkF,KAAKstF,gBAAgBrhF,GAAKs4E,EAAKt4E,GAC/BjM,KAAKstF,gBAAgBthF,GAAKu4E,EAAKv4E,GAC/BhM,KAAKstF,gBAAgBtiE,SAAWu5D,EAAKv5D,WAErChrB,KAAKstF,gBAAgBrhF,GAAK,EAC1BjM,KAAKstF,gBAAgBthF,GAAK,EAC1BhM,KAAKstF,gBAAgBtiE,SAAW,IAAIqgB,EAAAqgD,eAE/B1rF,KAAKstF,eACd,CAEO,YAAA1sE,CAAa2jE,EAAsBr4D,GACxC,OAAO,IAAIxe,EAAA6yE,WAAWvgF,KAAK+tF,aAAc/tF,KAAK8R,eAAe7J,KAAMjI,KAAK2gF,YAAY4D,GAAOr4D,EAC7F,CAEA,iBAAWoU,GACT,OAAOtgC,KAAKktF,gBAAkBltF,KAAKqE,MAAMqnE,UAAY1rE,KAAK2tF,KAC5D,CAEA,sBAAWt5E,GACT,MACM65E,EADYluF,KAAKwU,MAAQxU,KAAKmU,EACNnU,KAAKwE,MACnC,OAAQ0pF,GAAa,GAAKA,EAAYluF,KAAK2tF,KAC7C,CAOQ,uBAAAC,CAAwB7sF,GAC9B,IAAKf,KAAKktF,eACR,OAAOnsF,EAGT,MAAMotF,EAAsBptF,EAAOf,KAAKkqB,gBAAgB5f,WAAW8jF,WAEnE,OAAOD,EAAsB1vF,EAAAuuF,gBAAkBvuF,EAAAuuF,gBAAkBmB,CACnE,CAKO,gBAAAE,CAAiBC,GACtB,GAA0B,IAAtBtuF,KAAKqE,MAAM9C,OAAc,CAC3B+sF,IAAa5gF,EAAAmT,kBACb,IAAI/hB,EAAIkB,KAAK2tF,MACb,KAAO7uF,KACLkB,KAAKqE,MAAMJ,KAAKjE,KAAK4gB,aAAa0tE,GAEtC,CACF,CAKO,KAAAjiF,GACLrM,KAAK+tF,aAAa1hF,QAClBrM,KAAKwE,MAAQ,EACbxE,KAAKwU,MAAQ,EACbxU,KAAKmU,EAAI,EACTnU,KAAK6U,EAAI,EACT7U,KAAKqE,MAAQ,IAAIuoF,EAAA7hB,aAA0B/qE,KAAK4tF,wBAAwB5tF,KAAK2tF,QAC7E3tF,KAAKgyB,UAAY,EACjBhyB,KAAK0xE,aAAe1xE,KAAK2tF,MAAQ,EACjC3tF,KAAK6tF,eACP,CAOO,MAAA10E,CAAOo1E,EAAiBC,GAE7B,MAAMC,EAAWzuF,KAAK2gF,YAAYjzE,EAAAmT,mBAClC7gB,KAAK+tF,aAAa1hF,QAGlB,IAAIqiF,EAAmB,EAIvB,MAAM/iB,EAAe3rE,KAAK4tF,wBAAwBY,GAWlD,GAVI7iB,EAAe3rE,KAAKqE,MAAMqnE,YAC5B1rE,KAAKqE,MAAMqnE,UAAYC,GASrB3rE,KAAKqE,MAAM9C,OAAS,EAAG,CAEzB,GAAIvB,KAAK0tF,MAAQa,EACf,IAAK,IAAIzvF,EAAI,EAAGA,EAAIkB,KAAKqE,MAAM9C,OAAQzC,IAErC4vF,IAAqB1uF,KAAKqE,MAAMP,IAAIhF,GAAIqa,OAAOo1E,EAASE,GAK5D,IAAIE,EAAS,EACb,GAAI3uF,KAAK2tF,MAAQa,EACf,IAAK,IAAIr6E,EAAInU,KAAK2tF,MAAOx5E,EAAIq6E,EAASr6E,IAChCnU,KAAKqE,MAAM9C,OAASitF,EAAUxuF,KAAKwU,aACsB5P,IAAvD5E,KAAKkqB,gBAAgB5f,WAAWooE,WAAWC,cAAoF/tE,IAA3D5E,KAAKkqB,gBAAgB5f,WAAWooE,WAAWE,YAGjH5yE,KAAKqE,MAAMJ,KAAK,IAAIyJ,EAAA6yE,WAAWvgF,KAAK+tF,aAAcQ,EAASE,GAAU,IAEjEzuF,KAAKwU,MAAQ,GAAKxU,KAAKqE,MAAM9C,QAAUvB,KAAKwU,MAAQxU,KAAKmU,EAAIw6E,EAAS,GAGxE3uF,KAAKwU,QACLm6E,IACI3uF,KAAKwE,MAAQ,GAEfxE,KAAKwE,SAKPxE,KAAKqE,MAAMJ,KAAK,IAAIyJ,EAAA6yE,WAAWvgF,KAAK+tF,aAAcQ,EAASE,GAAU,UAM7E,IAAK,IAAIt6E,EAAInU,KAAK2tF,MAAOx5E,EAAIq6E,EAASr6E,IAChCnU,KAAKqE,MAAM9C,OAASitF,EAAUxuF,KAAKwU,QACjCxU,KAAKqE,MAAM9C,OAASvB,KAAKwU,MAAQxU,KAAKmU,EAAI,EAE5CnU,KAAKqE,MAAMoB,OAGXzF,KAAKwU,QACLxU,KAAKwE,UAQb,GAAImnE,EAAe3rE,KAAKqE,MAAMqnE,UAAW,CAEvC,MAAMkjB,EAAe5uF,KAAKqE,MAAM9C,OAASoqE,EACrCijB,EAAe,IACjB5uF,KAAKqE,MAAM+nE,UAAUwiB,GACrB5uF,KAAKwU,MAAQG,KAAKkZ,IAAI7tB,KAAKwU,MAAQo6E,EAAc,GACjD5uF,KAAKwE,MAAQmQ,KAAKkZ,IAAI7tB,KAAKwE,MAAQoqF,EAAc,GACjD5uF,KAAKqlF,OAAS1wE,KAAKkZ,IAAI7tB,KAAKqlF,OAASuJ,EAAc,IAErD5uF,KAAKqE,MAAMqnE,UAAYC,CACzB,CAGA3rE,KAAK6U,EAAIF,KAAKC,IAAI5U,KAAK6U,EAAG05E,EAAU,GACpCvuF,KAAKmU,EAAIQ,KAAKC,IAAI5U,KAAKmU,EAAGq6E,EAAU,GAChCG,IACF3uF,KAAKmU,GAAKw6E,GAEZ3uF,KAAKolF,OAASzwE,KAAKC,IAAI5U,KAAKolF,OAAQmJ,EAAU,GAE9CvuF,KAAKgyB,UAAY,CACnB,CAIA,GAFAhyB,KAAK0xE,aAAe8c,EAAU,EAE1BxuF,KAAK6uF,mBACP7uF,KAAK8uF,QAAQP,EAASC,GAGlBxuF,KAAK0tF,MAAQa,GACf,IAAK,IAAIzvF,EAAI,EAAGA,EAAIkB,KAAKqE,MAAM9C,OAAQzC,IAErC4vF,IAAqB1uF,KAAKqE,MAAMP,IAAIhF,GAAIqa,OAAOo1E,EAASE,GAU9D,GALAzuF,KAAK0tF,MAAQa,EACbvuF,KAAK2tF,MAAQa,EAITxuF,KAAKqE,MAAM9C,OAAS,EAAG,CACzB,MAAMqpC,EAAOj2B,KAAKkZ,IAAI,EAAG7tB,KAAKqE,MAAM9C,OAASvB,KAAKwU,MAAQ,GAC1DxU,KAAKmU,EAAIQ,KAAKC,IAAI5U,KAAKmU,EAAGy2B,EAC5B,CAEA5qC,KAAK8tF,oBAAoBzhF,QAErBqiF,EAAmB,GAAM1uF,KAAKqE,MAAM9C,SACtCvB,KAAKytF,uBAAyB,EAC9BztF,KAAK8tF,oBAAoBjF,QAAQ,IAAM7oF,KAAK+uF,yBAEhD,CAEQ,qBAAAA,GACN,IAAIC,GAAY,EACZhvF,KAAKytF,wBAA0BztF,KAAKqE,MAAM9C,SAG5CvB,KAAKytF,uBAAyB,EAC9BuB,GAAY,GAEd,IAAIC,EAAU,EACd,KAAOjvF,KAAKytF,uBAAyBztF,KAAKqE,MAAM9C,QAG9C,GAFA0tF,GAAWjvF,KAAKqE,MAAMP,IAAI9D,KAAKytF,0BAA2ByB,gBAEtDD,EAAU,IACZ,OAAO,EAMX,OAAOD,CACT,CAEA,oBAAYH,GACV,MAAMnc,EAAa1yE,KAAKkqB,gBAAgB5f,WAAWooE,WACnD,OAAIA,GAAcA,EAAWE,YACpB5yE,KAAKktF,gBAAyC,WAAvBxa,EAAWC,SAAwBD,EAAWE,aAAe,MAEtF5yE,KAAKktF,cACd,CAEQ,OAAA4B,CAAQP,EAAiBC,GAC3BxuF,KAAK0tF,QAAUa,IAKfA,EAAUvuF,KAAK0tF,MACjB1tF,KAAKmvF,cAAcZ,EAASC,GAE5BxuF,KAAKovF,eAAeb,EAASC,GAEjC,CAEQ,aAAAW,CAAcZ,EAAiBC,GACrC,MAAMa,EAAmBrvF,KAAKkqB,gBAAgB5f,WAAW+kF,iBACnDC,GAAqB,EAAAxC,EAAAyC,8BAA6BvvF,KAAKqE,MAAOrE,KAAK0tF,MAAOa,EAASvuF,KAAKwU,MAAQxU,KAAKmU,EAAGnU,KAAK2gF,YAAYjzE,EAAAmT,mBAAoBwuE,GACnJ,GAAIC,EAAS/tF,OAAS,EAAG,CACvB,MAAMiuF,GAAkB,EAAA1C,EAAA2C,6BAA4BzvF,KAAKqE,MAAOirF,IAChE,EAAAxC,EAAA4C,4BAA2B1vF,KAAKqE,MAAOmrF,EAAgBG,QACvD3vF,KAAK4vF,4BAA4BrB,EAASC,EAASgB,EAAgBK,aACrE,CACF,CAEQ,2BAAAD,CAA4BrB,EAAiBC,EAAiBqB,GACpE,MAAMpB,EAAWzuF,KAAK2gF,YAAYjzE,EAAAmT,mBAElC,IAAIivE,EAAsBD,EAC1B,KAAOC,KAAwB,GACV,IAAf9vF,KAAKwU,OACHxU,KAAKmU,EAAI,GACXnU,KAAKmU,IAEHnU,KAAKqE,MAAM9C,OAASitF,GAEtBxuF,KAAKqE,MAAMJ,KAAK,IAAIyJ,EAAA6yE,WAAWvgF,KAAK+tF,aAAcQ,EAASE,GAAU,MAGnEzuF,KAAKwE,QAAUxE,KAAKwU,OACtBxU,KAAKwE,QAEPxE,KAAKwU,SAGTxU,KAAKqlF,OAAS1wE,KAAKkZ,IAAI7tB,KAAKqlF,OAASwK,EAAc,EACrD,CAEQ,cAAAT,CAAeb,EAAiBC,GACtC,MAAMa,EAAmBrvF,KAAKkqB,gBAAgB5f,WAAW+kF,iBACnDZ,EAAWzuF,KAAK2gF,YAAYjzE,EAAAmT,mBAG5BkvE,EAAW,GACjB,IAAIC,EAAgB,EAEpB,IAAK,IAAI77E,EAAInU,KAAKqE,MAAM9C,OAAS,EAAG4S,GAAK,EAAGA,IAAK,CAE/C,IAAIoY,EAAWvsB,KAAKqE,MAAMP,IAAIqQ,GAC9B,IAAKoY,IAAaA,EAASL,WAAaK,EAAS9B,oBAAsB8jE,EACrE,SAIF,MAAM0B,EAA6B,CAAC1jE,GACpC,KAAOA,EAASL,WAAa/X,EAAI,GAC/BoY,EAAWvsB,KAAKqE,MAAMP,MAAMqQ,GAC5B87E,EAAapqF,QAAQ0mB,GAGvB,IAAK8iE,EAAkB,CAGrB,MAAMa,EAAYlwF,KAAKwU,MAAQxU,KAAKmU,EACpC,GAAI+7E,GAAa/7E,GAAK+7E,EAAY/7E,EAAI87E,EAAa1uF,OACjD,QAEJ,CAEA,MAAM4uF,EAAiBF,EAAaA,EAAa1uF,OAAS,GAAGkpB,mBACvD2lE,GAAkB,EAAAtD,EAAAuD,gCAA+BJ,EAAcjwF,KAAK0tF,MAAOa,GAC3E+B,EAAaF,EAAgB7uF,OAAS0uF,EAAa1uF,OACzD,IAAIgvF,EAGFA,EAFiB,IAAfvwF,KAAKwU,OAAexU,KAAKmU,IAAMnU,KAAKqE,MAAM9C,OAAS,EAEtCoT,KAAKkZ,IAAI,EAAG7tB,KAAKmU,EAAInU,KAAKqE,MAAMqnE,UAAY4kB,GAE5C37E,KAAKkZ,IAAI,EAAG7tB,KAAKqE,MAAM9C,OAASvB,KAAKqE,MAAMqnE,UAAY4kB,GAIxE,MAAME,EAAyB,GAC/B,IAAK,IAAI1xF,EAAI,EAAGA,EAAIwxF,EAAYxxF,IAAK,CACnC,MAAM2xF,EAAUzwF,KAAK4gB,aAAalT,EAAAmT,mBAAmB,GACrD2vE,EAASvsF,KAAKwsF,EAChB,CACID,EAASjvF,OAAS,IACpBwuF,EAAS9rF,KAAK,CAGZ5B,MAAO8R,EAAI87E,EAAa1uF,OAASyuF,EACjCQ,aAEFR,GAAiBQ,EAASjvF,QAE5B0uF,EAAahsF,QAAQusF,GAGrB,IAAIE,EAAgBN,EAAgB7uF,OAAS,EACzCovF,EAAUP,EAAgBM,GACd,IAAZC,IACFD,IACAC,EAAUP,EAAgBM,IAE5B,IAAIE,EAAeX,EAAa1uF,OAAS+uF,EAAa,EAClDO,EAASV,EACb,KAAOS,GAAgB,GAAG,CACxB,MAAME,EAAcn8E,KAAKC,IAAIi8E,EAAQF,GACrC,QAAoC/rF,IAAhCqrF,EAAaS,GAGf,MASF,GAPAT,EAAaS,GAAelQ,cAAcyP,EAAaW,GAAeC,EAASC,EAAaH,EAAUG,EAAaA,GAAa,GAChIH,GAAWG,EACK,IAAZH,IACFD,IACAC,EAAUP,EAAgBM,IAE5BG,GAAUC,EACK,IAAXD,EAAc,CAChBD,IACA,MAAMG,EAAoBp8E,KAAKkZ,IAAI+iE,EAAc,GACjDC,GAAS,EAAA/D,EAAAkE,6BAA4Bf,EAAcc,EAAmB/wF,KAAK0tF,MAC7E,CACF,CAGA,IAAK,IAAI5uF,EAAI,EAAGA,EAAImxF,EAAa1uF,OAAQzC,IACnCsxF,EAAgBtxF,GAAKyvF,GACvB0B,EAAanxF,GAAGmyF,QAAQb,EAAgBtxF,GAAI2vF,GAKhD,IAAIqB,EAAsBQ,EAAaC,EACvC,KAAOT,KAAwB,GACV,IAAf9vF,KAAKwU,MACHxU,KAAKmU,EAAIq6E,EAAU,GACrBxuF,KAAKmU,IACLnU,KAAKqE,MAAMoB,QAEXzF,KAAKwU,QACLxU,KAAKwE,SAIHxE,KAAKwU,MAAQG,KAAKC,IAAI5U,KAAKqE,MAAMqnE,UAAW1rE,KAAKqE,MAAM9C,OAASyuF,GAAiBxB,IAC/ExuF,KAAKwU,QAAUxU,KAAKwE,OACtBxE,KAAKwE,QAEPxE,KAAKwU,SAIXxU,KAAKqlF,OAAS1wE,KAAKC,IAAI5U,KAAKqlF,OAASiL,EAAYtwF,KAAKwU,MAAQg6E,EAAU,EAC1E,CAKA,GAAIuB,EAASxuF,OAAS,EAAG,CAGvB,MAAM2vF,EAA+B,GAG/BC,EAA8B,GACpC,IAAK,IAAIryF,EAAI,EAAGA,EAAIkB,KAAKqE,MAAM9C,OAAQzC,IACrCqyF,EAAcltF,KAAKjE,KAAKqE,MAAMP,IAAIhF,IAEpC,MAAMsyF,EAAsBpxF,KAAKqE,MAAM9C,OAEvC,IAAI8vF,EAAoBD,EAAsB,EAC1CE,EAAoB,EACpBC,EAAexB,EAASuB,GAC5BtxF,KAAKqE,MAAM9C,OAASoT,KAAKC,IAAI5U,KAAKqE,MAAMqnE,UAAW1rE,KAAKqE,MAAM9C,OAASyuF,GACvE,IAAIwB,EAAqB,EACzB,IAAK,IAAI1yF,EAAI6V,KAAKC,IAAI5U,KAAKqE,MAAMqnE,UAAY,EAAG0lB,EAAsBpB,EAAgB,GAAIlxF,GAAK,EAAGA,IAChG,GAAIyyF,GAAgBA,EAAalvF,MAAQgvF,EAAoBG,EAAoB,CAE/E,IAAK,IAAIC,EAAQF,EAAaf,SAASjvF,OAAS,EAAGkwF,GAAS,EAAGA,IAC7DzxF,KAAKqE,MAAMS,IAAIhG,IAAKyyF,EAAaf,SAASiB,IAE5C3yF,IAGAoyF,EAAajtF,KAAK,CAChBoO,MAAOg/E,EAAoB,EAC3B52E,OAAQ82E,EAAaf,SAASjvF,SAGhCiwF,GAAsBD,EAAaf,SAASjvF,OAC5CgwF,EAAexB,IAAWuB,EAC5B,MACEtxF,KAAKqE,MAAMS,IAAIhG,EAAGqyF,EAAcE,MAKpC,IAAIK,EAAqB,EACzB,IAAK,IAAI5yF,EAAIoyF,EAAa3vF,OAAS,EAAGzC,GAAK,EAAGA,IAC5CoyF,EAAapyF,GAAGuT,OAASq/E,EACzB1xF,KAAKqE,MAAM8mE,gBAAgBl6D,KAAKigF,EAAapyF,IAC7C4yF,GAAsBR,EAAapyF,GAAG2b,OAExC,MAAMm0E,EAAej6E,KAAKkZ,IAAI,EAAGujE,EAAsBpB,EAAgBhwF,KAAKqE,MAAMqnE,WAC9EkjB,EAAe,GACjB5uF,KAAKqE,MAAMgnE,cAAcp6D,KAAK29E,EAElC,CACF,CAYO,2BAAA3uD,CAA4B0xD,EAAmBC,EAAoB/xD,EAAmB,EAAGC,GAC9F,MAAMv7B,EAAOvE,KAAKqE,MAAMP,IAAI6tF,GAC5B,OAAKptF,EAGEA,EAAKI,kBAAkBitF,EAAW/xD,EAAUC,GAF1C,EAGX,CAEO,sBAAAknC,CAAuB7yD,GAC5B,IAAI8yD,EAAQ9yD,EACR+yD,EAAO/yD,EAEX,KAAO8yD,EAAQ,GAAKjnE,KAAKqE,MAAMP,IAAImjE,GAAQ/6C,WACzC+6C,IAGF,KAAOC,EAAO,EAAIlnE,KAAKqE,MAAM9C,QAAUvB,KAAKqE,MAAMP,IAAIojE,EAAO,GAAIh7C,WAC/Dg7C,IAEF,MAAO,CAAED,QAAOC,OAClB,CAMO,aAAA2mB,CAAc/uF,GAUnB,IATIA,QACGkB,KAAKyhF,KAAK3iF,KACbA,EAAIkB,KAAK0hF,SAAS5iF,KAGpBkB,KAAKyhF,KAAO,GACZ3iF,EAAI,GAGCA,EAAIkB,KAAK0tF,MAAO5uF,GAAKkB,KAAKkqB,gBAAgB5f,WAAWunF,aAC1D7xF,KAAKyhF,KAAK3iF,IAAK,CAEnB,CAMO,QAAA4iF,CAAS7sE,GAEd,IADAA,IAAM7U,KAAK6U,GACH7U,KAAKyhF,OAAO5sE,IAAMA,EAAI,IAC9B,OAAOA,GAAK7U,KAAK0tF,MAAQ1tF,KAAK0tF,MAAQ,EAAI74E,EAAI,EAAI,EAAIA,CACxD,CAMO,QAAAqsE,CAASrsE,GAEd,IADAA,IAAM7U,KAAK6U,GACH7U,KAAKyhF,OAAO5sE,IAAMA,EAAI7U,KAAK0tF,QACnC,OAAO74E,GAAK7U,KAAK0tF,MAAQ1tF,KAAK0tF,MAAQ,EAAI74E,EAAI,EAAI,EAAIA,CACxD,CAMO,YAAAmtE,CAAa7tE,GAClBnU,KAAKwtF,aAAc,EACnB,IAAK,IAAI1uF,EAAI,EAAGA,EAAIkB,KAAK8d,QAAQvc,OAAQzC,IACnCkB,KAAK8d,QAAQhf,GAAGyF,OAAS4P,IAC3BnU,KAAK8d,QAAQhf,GAAGua,UAChBrZ,KAAK8d,QAAQgK,OAAOhpB,IAAK,IAG7BkB,KAAKwtF,aAAc,CACrB,CAKO,eAAA7sE,GACL3gB,KAAKwtF,aAAc,EACnB,IAAK,IAAI1uF,EAAI,EAAGA,EAAIkB,KAAK8d,QAAQvc,OAAQzC,IACvCkB,KAAK8d,QAAQhf,GAAGua,UAElBrZ,KAAK8d,QAAQvc,OAAS,EACtBvB,KAAKwtF,aAAc,CACrB,CAEO,SAAAvvE,CAAU9J,GACf,MAAM2f,EAAS,IAAIi5D,EAAA+E,OAAO39E,GA0B1B,OAzBAnU,KAAK8d,QAAQ7Z,KAAK6vB,GAClBA,EAAOnW,SAAS3d,KAAKqE,MAAM4+D,OAAOxoD,IAChCqZ,EAAOvvB,MAAQkW,EAEXqZ,EAAOvvB,KAAO,GAChBuvB,EAAOza,aAGXya,EAAOnW,SAAS3d,KAAKqE,MAAM+mE,SAAS78D,IAC9BulB,EAAOvvB,MAAQgK,EAAM8D,QACvByhB,EAAOvvB,MAAQgK,EAAMkM,WAGzBqZ,EAAOnW,SAAS3d,KAAKqE,MAAM6mE,SAAS38D,IAE9BulB,EAAOvvB,MAAQgK,EAAM8D,OAASyhB,EAAOvvB,KAAOgK,EAAM8D,MAAQ9D,EAAMkM,QAClEqZ,EAAOza,UAILya,EAAOvvB,KAAOgK,EAAM8D,QACtByhB,EAAOvvB,MAAQgK,EAAMkM,WAGzBqZ,EAAOnW,SAASmW,EAAOG,UAAU,IAAMj0B,KAAK+xF,cAAcj+D,KACnDA,CACT,CAEQ,aAAAi+D,CAAcj+D,GACf9zB,KAAKwtF,aACRxtF,KAAK8d,QAAQgK,OAAO9nB,KAAK8d,QAAQq9C,QAAQrnC,GAAS,EAEtD,mHC7pBF,MAAAuX,EAAAnsC,EAAA,MACA+qB,EAAA/qB,EAAA,MACAylC,EAAAzlC,EAAA,MACAy0E,EAAAz0E,EAAA,KACA8yF,EAAA9yF,EAAA,MA6BaT,EAAAoiB,kBAAoBjY,OAAO+lB,OAAO,IAAI0c,EAAAoD,eAGnD,IAAIwjD,EAAc,EAClB,MAAMC,EAAY,IAAIjoE,EAAAI,SAChB8nE,EAA4B,IAAIH,EAAAnI,cA6BtC,MAAAtJ,EASE,WAAA7gF,CACqBquF,EACnB9lF,EACAmqF,EACOlmE,GAAqB,GAHTlsB,KAAA+tF,aAAAA,EAGZ/tF,KAAAksB,UAAAA,EAVClsB,KAAAqyF,UAAuC,GAEvCryF,KAAAsyF,eAAgE,GAUxEtyF,KAAK0nF,MAAQ,IAAI5R,YAAgB,EAAJ7tE,GAC7B,MAAMS,EAAO0pF,GAAgBnoE,EAAAI,SAAS+iE,aAAa,CAAC,EAAGzoD,EAAA0oD,eAAgB1oD,EAAAk8C,gBAAiBl8C,EAAAi8C,iBACxF,IAAK,IAAI9hF,EAAI,EAAGA,EAAImJ,IAAQnJ,EAC1BkB,KAAKixF,QAAQnyF,EAAG4J,GAElB1I,KAAKuB,OAAS0G,CAChB,CAMO,GAAAnE,CAAIuO,GACT,MAAMqkD,EAAU12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GACpDq/B,EAAY,QAAPglB,EACX,MAAO,CACL12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GAClC,QAAPqkD,EACG12D,KAAKqyF,UAAUhgF,GACf,GAAO,EAAAshE,EAAAuM,qBAAoBxuC,GAAM,GACrCglB,GAAO,GACC,QAAPA,EACG12D,KAAKqyF,UAAUhgF,GAAOoN,WAAWzf,KAAKqyF,UAAUhgF,GAAO9Q,OAAS,GAChEmwC,EAER,CAMO,GAAA5sC,CAAIuN,EAAe5H,GACxBzK,KAAKuyF,yBACLvyF,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAc5H,EAAMk6B,EAAA6tD,sBAC1D/nF,EAAMk6B,EAAA8tD,sBAAsBlxF,OAAS,GACvCvB,KAAKqyF,UAAUhgF,GAAS5H,EAAM,GAC9BzK,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAwB,QAALA,EAAoC5H,EAAMk6B,EAAA+tD,wBAAsB,IAE7H1yF,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAmB5H,EAAMk6B,EAAA8tD,sBAAsBhzE,WAAW,GAAMhV,EAAMk6B,EAAA+tD,wBAAsB,EAE1I,CAMO,QAAA39E,CAAS1C,GACd,OAAOrS,KAAK0nF,MAAW,EAALr1E,EAA+B,IAAgB,EACnE,CAGO,QAAA6yD,CAAS7yD,GACd,OAAiE,SAA1DrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAGO,KAAAolD,CAAMplD,GACX,OAAOrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAGO,KAAAslD,CAAMtlD,GACX,OAAOrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAOO,UAAAwY,CAAWxY,GAChB,OAAiE,QAA1DrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAOO,YAAAm0D,CAAan0D,GAClB,MAAMqkD,EAAU12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GAC1D,OAAW,QAAPqkD,EACK12D,KAAKqyF,UAAUhgF,GAAOoN,WAAWzf,KAAKqyF,UAAUhgF,GAAO9Q,OAAS,GAE3D,QAAPm1D,CACT,CAGO,UAAAE,CAAWvkD,GAChB,OAAiE,QAA1DrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAGO,SAAAimD,CAAUjmD,GACf,MAAMqkD,EAAU12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GAC1D,OAAW,QAAPqkD,EACK12D,KAAKqyF,UAAUhgF,GAEb,QAAPqkD,GACK,EAAAid,EAAAuM,qBAA2B,QAAPxpB,GAGtB,EACT,CAGO,WAAAswB,CAAY30E,GACjB,OAA4D,UAArDrS,KAAK0nF,MAAW,EAALr1E,EAA+B,EACnD,CAMO,QAAAyY,CAASzY,EAAe3J,GAiB7B,OAhBAupF,EAAmB,EAAL5/E,EACd3J,EAAKguD,QAAU12D,KAAK0nF,MAAMuK,EAAW,GACrCvpF,EAAKuD,GAAKjM,KAAK0nF,MAAMuK,EAAW,GAChCvpF,EAAKsD,GAAKhM,KAAK0nF,MAAMuK,EAAW,GAChB,QAAZvpF,EAAKguD,QACPhuD,EAAKiuD,aAAe32D,KAAKqyF,UAAUhgF,GAEnC3J,EAAKiuD,aAAe,GAEX,UAAPjuD,EAAKsD,GACPtD,EAAKsiB,SAAWhrB,KAAKsyF,eAAejgF,GAIpC3J,EAAKsiB,SAAWvsB,EAAAoiB,kBAAkBmK,SAASuuB,QAEtC7wC,CACT,CAKO,OAAAuoF,CAAQ5+E,EAAe3J,GAC5B1I,KAAKuyF,yBACW,QAAZ7pF,EAAKguD,UACP12D,KAAKqyF,UAAUhgF,GAAS3J,EAAKiuD,cAEpB,UAAPjuD,EAAKsD,KACPhM,KAAKsyF,eAAejgF,GAAS3J,EAAKsiB,UAEpChrB,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAmB3J,EAAKguD,QAClE12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAc3J,EAAKuD,GAC7DjM,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAc3J,EAAKsD,EAC/D,CAOO,oBAAA0zE,CAAqBrtE,EAAesgF,EAAmB5pF,EAAe6pF,GAC3E5yF,KAAKuyF,yBACO,UAARK,EAAM5mF,KACRhM,KAAKsyF,eAAejgF,GAASugF,EAAM5nE,UAErChrB,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAmBsgF,EAAa5pF,GAAK,GAC/E/I,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAcugF,EAAM3mF,GAC9DjM,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAcugF,EAAM5mF,EAChE,CAQO,kBAAAy0E,CAAmBpuE,EAAesgF,EAAmB5pF,GAC1D/I,KAAKuyF,yBACL,IAAI77B,EAAU12D,KAAK0nF,MAAW,EAALr1E,EAA+B,GAC7C,QAAPqkD,EAEF12D,KAAKqyF,UAAUhgF,KAAU,EAAAshE,EAAAuM,qBAAoByS,GAElC,QAAPj8B,GAIF12D,KAAKqyF,UAAUhgF,IAAS,EAAAshE,EAAAuM,qBAA2B,QAAPxpB,IAAoC,EAAAid,EAAAuM,qBAAoByS,GACpGj8B,IAAW,QACXA,GAAO,SAIPA,EAAUi8B,EAAa,GAAC,GAGxB5pF,IACF2tD,IAAW,SACXA,GAAW3tD,GAAK,IAElB/I,KAAK0nF,MAAW,EAALr1E,EAA+B,GAAmBqkD,CAC/D,CAEO,WAAAgqB,CAAY71E,EAAa4jD,EAAW2jC,GASzC,GARApyF,KAAKuyF,0BACL1nF,GAAO7K,KAAKuB,SAG0B,IAA3BvB,KAAK+U,SAASlK,EAAM,IAC7B7K,KAAK0/E,qBAAqB70E,EAAM,EAAG,EAAG,EAAGunF,GAGvC3jC,EAAIzuD,KAAKuB,OAASsJ,EAAK,CACzB,IAAK,IAAI/L,EAAIkB,KAAKuB,OAASsJ,EAAM4jD,EAAI,EAAG3vD,GAAK,IAAKA,EAChDkB,KAAKixF,QAAQpmF,EAAM4jD,EAAI3vD,EAAGkB,KAAK8qB,SAASjgB,EAAM/L,EAAGozF,IAEnD,IAAK,IAAIpzF,EAAI,EAAGA,EAAI2vD,IAAK3vD,EACvBkB,KAAKixF,QAAQpmF,EAAM/L,EAAGszF,EAE1B,MACE,IAAK,IAAItzF,EAAI+L,EAAK/L,EAAIkB,KAAKuB,SAAUzC,EACnCkB,KAAKixF,QAAQnyF,EAAGszF,GAKmB,IAAnCpyF,KAAK+U,SAAS/U,KAAKuB,OAAS,IAC9BvB,KAAK0/E,qBAAqB1/E,KAAKuB,OAAS,EAAG,EAAG,EAAG6wF,EAErD,CAEO,WAAA/P,CAAYx3E,EAAa4jD,EAAW2jC,GAGzC,GAFApyF,KAAKuyF,yBACL1nF,GAAO7K,KAAKuB,OACRktD,EAAIzuD,KAAKuB,OAASsJ,EAAK,CACzB,IAAK,IAAI/L,EAAI,EAAGA,EAAIkB,KAAKuB,OAASsJ,EAAM4jD,IAAK3vD,EAC3CkB,KAAKixF,QAAQpmF,EAAM/L,EAAGkB,KAAK8qB,SAASjgB,EAAM4jD,EAAI3vD,EAAGozF,IAEnD,IAAK,IAAIpzF,EAAIkB,KAAKuB,OAASktD,EAAG3vD,EAAIkB,KAAKuB,SAAUzC,EAC/CkB,KAAKixF,QAAQnyF,EAAGszF,EAEpB,MACE,IAAK,IAAItzF,EAAI+L,EAAK/L,EAAIkB,KAAKuB,SAAUzC,EACnCkB,KAAKixF,QAAQnyF,EAAGszF,GAOhBvnF,GAAkC,IAA3B7K,KAAK+U,SAASlK,EAAM,IAC7B7K,KAAK0/E,qBAAqB70E,EAAM,EAAG,EAAG,EAAGunF,GAEhB,IAAvBpyF,KAAK+U,SAASlK,IAAe7K,KAAK6qB,WAAWhgB,IAC/C7K,KAAK0/E,qBAAqB70E,EAAK,EAAG,EAAGunF,EAEzC,CAEO,YAAAtQ,CAAaz/E,EAAeC,EAAa8vF,EAAyBvQ,GAA0B,GAGjG,GAFA7hF,KAAKuyF,yBAED1Q,EAOF,IANIx/E,GAAsC,IAA7BrC,KAAK+U,SAAS1S,EAAQ,KAAarC,KAAKgnF,YAAY3kF,EAAQ,IACvErC,KAAK0/E,qBAAqBr9E,EAAQ,EAAG,EAAG,EAAG+vF,GAEzC9vF,EAAMtC,KAAKuB,QAAqC,IAA3BvB,KAAK+U,SAASzS,EAAM,KAAatC,KAAKgnF,YAAY1kF,IACzEtC,KAAK0/E,qBAAqBp9E,EAAK,EAAG,EAAG8vF,GAEhC/vF,EAAQC,GAAQD,EAAQrC,KAAKuB,QAC7BvB,KAAKgnF,YAAY3kF,IACpBrC,KAAKixF,QAAQ5uF,EAAO+vF,GAEtB/vF,SAcJ,IARIA,GAAsC,IAA7BrC,KAAK+U,SAAS1S,EAAQ,IACjCrC,KAAK0/E,qBAAqBr9E,EAAQ,EAAG,EAAG,EAAG+vF,GAGzC9vF,EAAMtC,KAAKuB,QAAqC,IAA3BvB,KAAK+U,SAASzS,EAAM,IAC3CtC,KAAK0/E,qBAAqBp9E,EAAK,EAAG,EAAG8vF,GAGhC/vF,EAAQC,GAAQD,EAAQrC,KAAKuB,QAClCvB,KAAKixF,QAAQ5uF,IAAS+vF,EAE1B,CASO,MAAAj5E,CAAOlR,EAAcmqF,GAE1B,GADApyF,KAAKuyF,yBACDtqF,IAASjI,KAAKuB,OAChB,OAA2B,EAApBvB,KAAK0nF,MAAMnmF,OAAU,EAAiCvB,KAAK0nF,MAAMvjF,OAAO0uF,WAEjF,MAAMC,EAAkB,EAAJ7qF,EACpB,GAAIA,EAAOjI,KAAKuB,OAAQ,CACtB,GAAIvB,KAAK0nF,MAAMvjF,OAAO0uF,YAA4B,EAAdC,EAElC9yF,KAAK0nF,MAAQ,IAAI5R,YAAY91E,KAAK0nF,MAAMvjF,OAAQ,EAAG2uF,OAC9C,CAEL,MAAM71E,EAAO,IAAI64D,YAAYgd,GAC7B71E,EAAKnY,IAAI9E,KAAK0nF,OACd1nF,KAAK0nF,MAAQzqE,CACf,CACA,IAAK,IAAIne,EAAIkB,KAAKuB,OAAQzC,EAAImJ,IAAQnJ,EACpCkB,KAAKixF,QAAQnyF,EAAGszF,EAEpB,KAAO,CAELpyF,KAAK0nF,MAAQ1nF,KAAK0nF,MAAMxI,SAAS,EAAG4T,GAEpC,MAAMjhC,EAAOjpD,OAAOipD,KAAK7xD,KAAKqyF,WAC9B,IAAK,IAAIvzF,EAAI,EAAGA,EAAI+yD,EAAKtwD,OAAQzC,IAAK,CACpC,MAAMmE,EAAM4E,SAASgqD,EAAK/yD,GAAI,IAC1BmE,GAAOgF,UACFjI,KAAKqyF,UAAUpvF,EAE1B,CAEA,MAAM8vF,EAAUnqF,OAAOipD,KAAK7xD,KAAKsyF,gBACjC,IAAK,IAAIxzF,EAAI,EAAGA,EAAIi0F,EAAQxxF,OAAQzC,IAAK,CACvC,MAAMmE,EAAM4E,SAASkrF,EAAQj0F,GAAI,IAC7BmE,GAAOgF,UACFjI,KAAKsyF,eAAervF,EAE/B,CACF,CAEA,OADAjD,KAAKuB,OAAS0G,EACO,EAAd6qF,EAAe,EAAiC9yF,KAAK0nF,MAAMvjF,OAAO0uF,UAC3E,CAQO,aAAA3D,GACL,GAAwB,EAApBlvF,KAAK0nF,MAAMnmF,OAAU,EAAiCvB,KAAK0nF,MAAMvjF,OAAO0uF,WAAY,CACtF,MAAM51E,EAAO,IAAI64D,YAAY91E,KAAK0nF,MAAMnmF,QAGxC,OAFA0b,EAAKnY,IAAI9E,KAAK0nF,OACd1nF,KAAK0nF,MAAQzqE,EACN,CACT,CACA,OAAO,CACT,CAGO,IAAA6sB,CAAKsoD,EAAyBvQ,GAA0B,GAG7D,GAFA7hF,KAAKuyF,yBAED1Q,EACF,IAAK,IAAI/iF,EAAI,EAAGA,EAAIkB,KAAKuB,SAAUzC,EAC5BkB,KAAKgnF,YAAYloF,IACpBkB,KAAKixF,QAAQnyF,EAAGszF,OAHtB,CAQApyF,KAAKqyF,UAAY,GACjBryF,KAAKsyF,eAAiB,GACtB,IAAK,IAAIxzF,EAAI,EAAGA,EAAIkB,KAAKuB,SAAUzC,EACjCkB,KAAKixF,QAAQnyF,EAAGszF,EAJlB,CAMF,CAGO,QAAAY,CAASzuF,GACdvE,KAAKuyF,yBACDvyF,KAAKuB,SAAWgD,EAAKhD,OACvBvB,KAAK0nF,MAAQ,IAAI5R,YAAYvxE,EAAKmjF,OAGlC1nF,KAAK0nF,MAAM5iF,IAAIP,EAAKmjF,OAEtB1nF,KAAKuB,OAASgD,EAAKhD,OACnBvB,KAAKizF,oBAAoB1uF,GACzBvE,KAAKksB,UAAY3nB,EAAK2nB,SACxB,CAGO,KAAAqtB,GACL,MAAMk3C,EAAU,IAAIlQ,EAAWvgF,KAAK+tF,aAAc,OAAGnpF,GAAW,GAKhE,OAJA6rF,EAAQ/I,MAAQ,IAAI5R,YAAY91E,KAAK0nF,OACrC+I,EAAQlvF,OAASvB,KAAKuB,OACtBkvF,EAAQwC,oBAAoBjzF,MAC5BywF,EAAQvkE,UAAYlsB,KAAKksB,UAClBukE,CACT,CAEO,gBAAAhmE,GACL,IAAK,IAAI3rB,EAAIkB,KAAKuB,OAAS,EAAGzC,GAAK,IAAKA,EACtC,GAA2D,QAAtDkB,KAAK0nF,MAAO,EAAD5oF,EAA2B,GACzC,OAAOA,GAAKkB,KAAK0nF,MAAO,EAAD5oF,EAA2B,IAAgB,IAGtE,OAAO,CACT,CAEO,oBAAAotC,GACL,IAAK,IAAIptC,EAAIkB,KAAKuB,OAAS,EAAGzC,GAAK,IAAKA,EACtC,GAA2D,QAAtDkB,KAAK0nF,MAAO,EAAD5oF,EAA2B,IAAkG,SAAjDkB,KAAK0nF,MAAO,EAAD5oF,EAA2B,GAChI,OAAOA,GAAKkB,KAAK0nF,MAAO,EAAD5oF,EAA2B,IAAgB,IAGtE,OAAO,CACT,CAEO,aAAA0hF,CAAc0S,EAAiBrC,EAAgBF,EAAiBpvF,EAAgB4xF,GACrFnzF,KAAKuyF,yBACL,MAAMa,EAAUF,EAAIxL,MACpB,GAAIyL,EACF,IAAK,IAAIzqF,EAAOnH,EAAS,EAAGmH,GAAQ,EAAGA,IAAQ,CAC7C,IAAK,IAAI5J,EAAI,EAAGA,EAAC,EAA4BA,IAC3CkB,KAAK0nF,MAAsB,GAAfiJ,EAAUjoF,GAAkC5J,GAAKs0F,EAAuB,GAAdvC,EAASnoF,GAAkC5J,GAEnHkB,KAAKqzF,kBAAkBH,EAAKrC,EAASnoF,EAAMioF,EAAUjoF,EACvD,MAEA,IAAK,IAAIA,EAAO,EAAGA,EAAOnH,EAAQmH,IAAQ,CACxC,IAAK,IAAI5J,EAAI,EAAGA,EAAC,EAA4BA,IAC3CkB,KAAK0nF,MAAsB,GAAfiJ,EAAUjoF,GAAkC5J,GAAKs0F,EAAuB,GAAdvC,EAASnoF,GAAkC5J,GAEnHkB,KAAKqzF,kBAAkBH,EAAKrC,EAASnoF,EAAMioF,EAAUjoF,EACvD,CAEJ,CAgBO,iBAAA/D,CAAkBitF,EAAqB/xD,EAAmBC,EAAiBwzD,GAChF,MAAMC,QAAmC3uF,IAAbi7B,GAAuC,IAAbA,SAA8Bj7B,IAAXk7B,QAAuCl7B,IAAf0uF,EAC7FC,GACFvzF,KAAK+tF,aAAa/8B,UAEpB,MAAMwiC,EAAmBD,EAAqBvzF,KAAKyzF,sBAAqB,QAAS7uF,EACjF,GAAI2uF,QAAkD3uF,IAA5B4uF,GAAkB/oF,MAAqB,CAC/D,GAAImnF,EACF,OAAO4B,EAAiBE,UAAYF,EAAiB/oF,MAAQ+oF,EAAiB/oF,MAAMkpF,UAEtF,IAAKH,EAAiBE,UACpB,OAAOF,EAAiB/oF,KAE5B,CAUA,IATAo1B,EAAWA,GAAY,EACvBC,EAASA,GAAU9/B,KAAKuB,OACpBqwF,IACF9xD,EAASnrB,KAAKC,IAAIkrB,EAAQ9/B,KAAKyqB,qBAE7B6oE,IACFA,EAAW/xF,OAAS,GAEtB4wF,EAA0B7gF,QACnBuuB,EAAWC,GAAQ,CACxB,MAAM42B,EAAU12D,KAAK0nF,MAAc,EAAR7nD,EAAkC,GACvD6R,EAAY,QAAPglB,EACLhpB,EAAgB,QAAPgpB,EAAsC12D,KAAKqyF,UAAUxyD,GAAY,GAAO,EAAA8zC,EAAAuM,qBAAoBxuC,GAAM/M,EAAAiJ,qBAEjH,GADAukD,EAA0BpI,OAAOr8C,GAC7B4lD,EACF,IAAK,IAAIx0F,EAAI,EAAGA,EAAI4uC,EAAMnsC,SAAUzC,EAClCw0F,EAAWrvF,KAAK47B,GAGpBA,GAAa62B,GAAO,IAA4B,CAClD,CACI48B,GACFA,EAAWrvF,KAAK47B,GAElB,MAAM7gB,EAASmzE,EAA0B7tF,WAEzC,GADA6tF,EAA0B7gF,QACtBiiF,EAAoB,CACtB,MAAMK,EAAa5zF,KAAKyzF,sBAAqB,GAC7CG,EAAWnpF,MAAQuU,EACnB40E,EAAWF,YAAc9B,CAC3B,CACA,OAAO5yE,CACT,CAEU,oBAAAy0E,CAAqBI,GAC7B,MAAMC,EAAc9zF,KAAK+zF,sBAAsBj1C,QAC/C,GAAIg1C,GACEA,EAAYE,aAAeh0F,KAAK+tF,aAAaiG,WAC/C,OAAOF,EAGX,IAAKD,EACH,OAEF,MAAMD,EAAa5zF,KAAK+tF,aAAakG,gBAErC,OADAj0F,KAAK+zF,qBAAuB,IAAI11C,QAAQu1C,GACjCA,CACT,CAEQ,sBAAArB,GACN,MAAMqB,EAAa5zF,KAAKyzF,sBAAqB,GACzCG,IACFA,EAAWnpF,WAAQ7F,EACnBgvF,EAAWF,WAAY,EAE3B,CAGQ,iBAAAL,CAAkBH,EAAiBrC,EAAgBF,GACzD,MAAMuD,EAAiB,EAANrD,EACqB,QAAlCqC,EAAIxL,MAAMwM,EAAQ,KACpBl0F,KAAKqyF,UAAU1B,GAAWuC,EAAIb,UAAUxB,IAET,UAA7BqC,EAAIxL,MAAMwM,EAAQ,KACpBl0F,KAAKsyF,eAAe3B,GAAWuC,EAAIZ,eAAezB,GAEtD,CAGQ,mBAAAoC,CAAoB1uF,GAC1BvE,KAAKqyF,UAAY,GACjBryF,KAAKsyF,eAAiB,GACtB,IAAK,IAAIxzF,EAAI,EAAGA,EAAIyF,EAAKhD,OAAQzC,IAC/BkB,KAAKqzF,kBAAkB9uF,EAAMzF,EAAGA,EAEpC,8GC1mBF,MAAA6jB,EAAAzjB,EAAA,MACAE,EAAAF,EAAA,MAMA,MAAA8uF,UAA2C5uF,EAAAK,WAMzC,WAAAC,GACEK,QANKC,KAAAg0F,WAAqB,EACZh0F,KAAA6mB,QAA4C,IAAIW,IAC/CxnB,KAAAm0F,cAAgBn0F,KAAK0B,UAAU,IAAItC,EAAA0P,mBAC5C9O,KAAAo0F,qBAA+B,EAIrCp0F,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAK6mB,QAAQxa,SACjD,CAEO,KAAA2kD,GACLhxD,KAAKq0F,gBACP,CAEO,aAAAJ,GACL,MAAMhzB,EAAqC,CACzCx2D,WAAO7F,EACP8uF,WAAW,EACXM,WAAYh0F,KAAKg0F,YAInB,OAFAh0F,KAAK6mB,QAAQlmB,IAAIsgE,GACjBjhE,KAAKq0F,iBACEpzB,CACT,CAEO,KAAA50D,GACLrM,KAAKm0F,cAAc9nF,QACnBrM,KAAKo0F,qBAAuB,EAC5Bp0F,KAAKg0F,aACL,IAAK,MAAM/yB,KAASjhE,KAAK6mB,QACvBo6C,EAAMx2D,WAAQ7F,EACdq8D,EAAMyyB,WAAY,EAEpB1zF,KAAK6mB,QAAQxa,OACf,CAEQ,cAAAgoF,GACNr0F,KAAKo0F,qBAAuBn1C,KAAK3wB,MAC7BtuB,KAAKm0F,cAAc1pF,OAGvBzK,KAAKs0F,sBAAqB,KAC5B,CAEQ,qBAAAA,CAAsBC,GAC5Bv0F,KAAKm0F,cAAc1pF,OAAQ,EAAAkY,EAAA6xE,mBAAkB,KAC3C,MAAMjmE,EAAU0wB,KAAK3wB,MAAQtuB,KAAKo0F,qBAC9B7lE,GAAO,KACTvuB,KAAKqM,QAGPrM,KAAKs0F,sBAAsB,KAAyB/lE,IACnDgmE,EACL,yGC5DF,SAA+B5sE,EAAqB8sE,GAClD,GAAI9sE,EAAMtlB,MAAM8R,EAAIwT,EAAMrlB,IAAI6R,EAC5B,MAAM,IAAIpS,MAAM,qBAAqB4lB,EAAMrlB,IAAIuS,MAAM8S,EAAMrlB,IAAI6R,8BAA8BwT,EAAMtlB,MAAMwS,MAAM8S,EAAMtlB,MAAM8R,MAE7H,OAAOsgF,GAAc9sE,EAAMrlB,IAAI6R,EAAIwT,EAAMtlB,MAAM8R,IAAMwT,EAAMrlB,IAAIuS,EAAI8S,EAAMtlB,MAAMwS,EAAI,EACrF,YC0MA,SAAAm8E,EAA4C3sF,EAAqBvF,EAAWmJ,GAE1E,GAAInJ,IAAMuF,EAAM9C,OAAS,EACvB,OAAO8C,EAAMvF,GAAG2rB,mBAKlB,MAAMiqE,GAAerwF,EAAMvF,GAAG+rB,WAAW5iB,EAAO,IAAuC,IAAhC5D,EAAMvF,GAAGiW,SAAS9M,EAAO,GAC1E0sF,EAA2D,IAA7BtwF,EAAMvF,EAAI,GAAGiW,SAAS,GAC1D,OAAI2/E,GAAcC,EACT1sF,EAAO,EAETA,CACT,iFA5MA,SAA6C5D,EAAkCuwF,EAAiBrG,EAAiBsG,EAAyBpG,EAAqBY,GAG7J,MAAMC,EAAqB,GAE3B,IAAK,IAAIn7E,EAAI,EAAGA,EAAI9P,EAAM9C,OAAS,EAAG4S,IAAK,CAEzC,IAAIrV,EAAIqV,EACJoY,EAAWloB,EAAMP,MAAMhF,GAC3B,IAAKytB,EAASL,UACZ,SAIF,MAAM+jE,EAA6B,CAAC5rF,EAAMP,IAAIqQ,IAC9C,KAAOrV,EAAIuF,EAAM9C,QAAUgrB,EAASL,WAClC+jE,EAAahsF,KAAKsoB,GAClBA,EAAWloB,EAAMP,MAAMhF,GAGzB,IAAKuwF,GAGCwF,GAAmB1gF,GAAK0gF,EAAkB/1F,EAAG,CAC/CqV,GAAK87E,EAAa1uF,OAAS,EAC3B,QACF,CAIF,IAAImvF,EAAgB,EAChBC,EAAUK,EAA4Bf,EAAcS,EAAekE,GACnEhE,EAAe,EACfC,EAAS,EACb,KAAOD,EAAeX,EAAa1uF,QAAQ,CACzC,MAAMuzF,EAAuB9D,EAA4Bf,EAAcW,EAAcgE,GAC/EG,EAAoBD,EAAuBjE,EAC3CmE,EAAqBzG,EAAUoC,EAC/BG,EAAcn8E,KAAKC,IAAImgF,EAAmBC,GAEhD/E,EAAaS,GAAelQ,cAAcyP,EAAaW,GAAeC,EAAQF,EAASG,GAAa,GAEpGH,GAAWG,EACPH,IAAYpC,IACdmC,IACAC,EAAU,GAEZE,GAAUC,EACND,IAAWiE,IACblE,IACAC,EAAS,GAIK,IAAZF,GAAmC,IAAlBD,GAC2C,IAA1DT,EAAaS,EAAgB,GAAG37E,SAASw5E,EAAU,KACrD0B,EAAaS,GAAelQ,cAAcyP,EAAaS,EAAgB,GAAInC,EAAU,EAAGoC,IAAW,GAAG,GAEtGV,EAAaS,EAAgB,GAAGO,QAAQ1C,EAAU,EAAGE,GAG3D,CAGAwB,EAAaS,GAAe5O,aAAa6O,EAASpC,EAASE,GAG3D,IAAIwG,EAAgB,EACpB,IAAK,IAAIn2F,EAAImxF,EAAa1uF,OAAS,EAAGzC,EAAI,IACpCA,EAAI4xF,GAAwD,IAAvCT,EAAanxF,GAAG2rB,oBADE3rB,IAEzCm2F,IAMAA,EAAgB,IAClB3F,EAASrrF,KAAKkQ,EAAI87E,EAAa1uF,OAAS0zF,GACxC3F,EAASrrF,KAAKgxF,IAGhB9gF,GAAK87E,EAAa1uF,OAAS,CAC7B,CACA,OAAO+tF,CACT,gCAOA,SAA4CjrF,EAAkCirF,GAC5E,MAAMK,EAAmB,GAEzB,IAAIuF,EAAoB,EACpBC,EAAoB7F,EAAS4F,GAC7BE,EAAoB,EACxB,IAAK,IAAIt2F,EAAI,EAAGA,EAAIuF,EAAM9C,OAAQzC,IAChC,GAAIq2F,IAAsBr2F,EAAG,CAC3B,MAAMm2F,EAAgB3F,IAAW4F,GAGjC7wF,EAAM4mE,gBAAgBh6D,KAAK,CACzBoB,MAAOvT,EAAIs2F,EACX36E,OAAQw6E,IAGVn2F,GAAKm2F,EAAgB,EACrBG,GAAqBH,EACrBE,EAAoB7F,IAAW4F,EACjC,MACEvF,EAAO1rF,KAAKnF,GAGhB,MAAO,CACL6wF,SACAE,aAAcuF,EAElB,+BAQA,SAA2C/wF,EAAkCgxF,GAE3E,MAAMC,EAA+B,GACrC,IAAK,IAAIx2F,EAAI,EAAGA,EAAIu2F,EAAU9zF,OAAQzC,IACpCw2F,EAAerxF,KAAKI,EAAMP,IAAIuxF,EAAUv2F,KAI1C,IAAK,IAAIA,EAAI,EAAGA,EAAIw2F,EAAe/zF,OAAQzC,IACzCuF,EAAMS,IAAIhG,EAAGw2F,EAAex2F,IAE9BuF,EAAM9C,OAAS8zF,EAAU9zF,MAC3B,mCAgBA,SAA+C0uF,EAA4B2E,EAAiBrG,GAC1F,MAAMgH,EAA2B,GACjC,IAAIC,EAAc,EAClB,IAAK,IAAI12F,EAAI,EAAGA,EAAImxF,EAAa1uF,OAAQzC,IACvC02F,GAAexE,EAA4Bf,EAAcnxF,EAAG81F,GAK9D,IAAI/D,EAAS,EACT4E,EAAU,EACVC,EAAiB,EACrB,KAAOA,EAAiBF,GAAa,CACnC,GAAIA,EAAcE,EAAiBnH,EAAS,CAE1CgH,EAAetxF,KAAKuxF,EAAcE,GAClC,KACF,CACA7E,GAAUtC,EACV,MAAMoH,EAAmB3E,EAA4Bf,EAAcwF,EAASb,GACxE/D,EAAS8E,IACX9E,GAAU8E,EACVF,KAEF,MAAMG,EAA8D,IAA/C3F,EAAawF,GAAS1gF,SAAS87E,EAAS,GACzD+E,GACF/E,IAEF,MAAMrmE,EAAaorE,EAAerH,EAAU,EAAIA,EAChDgH,EAAetxF,KAAKumB,GACpBkrE,GAAkBlrE,CACpB,CAEA,OAAO+qE,CACT,mHC/MA,MAAAn2F,EAAAF,EAAA,MACA22F,EAAA32F,EAAA,MAGA8O,EAAA9O,EAAA,MAMA,MAAA42F,UAA+B12F,EAAAK,WAa7B,WAAAC,CACmBwqB,EACApY,EACAgF,GAEjB/W,QAJiBC,KAAAkqB,gBAAAA,EACAlqB,KAAA8R,eAAAA,EACA9R,KAAA8W,YAAAA,EAZF9W,KAAA+1F,cAAgB/1F,KAAK0B,UAAU,IAAItC,EAAA0P,mBACnC9O,KAAAg2F,WAAah2F,KAAK0B,UAAU,IAAItC,EAAA0P,mBAEhC9O,KAAAi2F,kBAAoBj2F,KAAK0B,UAAU,IAAIsM,EAAAsB,SACxCtP,KAAAyxB,iBAAmBzxB,KAAKi2F,kBAAkB1nF,MAWxDvO,KAAKsR,QACLtR,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,aAAc,IAAMzX,KAAKmZ,OAAOnZ,KAAK8R,eAAe7J,KAAMjI,KAAK8R,eAAe/Q,QACzIf,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,eAAgB,IAAMzX,KAAK6tF,iBACxF,CAEO,KAAAv8E,GACLtR,KAAKk2F,QAAU,IAAIL,EAAA5I,QAAO,EAAMjtF,KAAKkqB,gBAAiBlqB,KAAK8R,eAAgB9R,KAAK8W,aAChF9W,KAAK+1F,cAActrF,MAAQzK,KAAKk2F,QAChCl2F,KAAKk2F,QAAQ7H,mBAIbruF,KAAKm2F,KAAO,IAAIN,EAAA5I,QAAO,EAAOjtF,KAAKkqB,gBAAiBlqB,KAAK8R,eAAgB9R,KAAK8W,aAC9E9W,KAAKg2F,WAAWvrF,MAAQzK,KAAKm2F,KAC7Bn2F,KAAK23E,cAAgB33E,KAAKk2F,QAC1Bl2F,KAAKi2F,kBAAkBhlF,KAAK,CAC1B00D,aAAc3lE,KAAKk2F,QACnBE,eAAgBp2F,KAAKm2F,OAGvBn2F,KAAK6tF,eACP,CAKA,OAAWz6D,GACT,OAAOpzB,KAAKm2F,IACd,CAKA,UAAW1iF,GACT,OAAOzT,KAAK23E,aACd,CAKA,UAAWnhD,GACT,OAAOx2B,KAAKk2F,OACd,CAKO,oBAAAzS,GACDzjF,KAAK23E,gBAAkB33E,KAAKk2F,UAGhCl2F,KAAKk2F,QAAQrhF,EAAI7U,KAAKm2F,KAAKthF,EAC3B7U,KAAKk2F,QAAQ/hF,EAAInU,KAAKm2F,KAAKhiF,EAI3BnU,KAAKm2F,KAAKx1E,kBACV3gB,KAAKm2F,KAAK9pF,QACVrM,KAAK23E,cAAgB33E,KAAKk2F,QAC1Bl2F,KAAKi2F,kBAAkBhlF,KAAK,CAC1B00D,aAAc3lE,KAAKk2F,QACnBE,eAAgBp2F,KAAKm2F,OAEzB,CAKO,iBAAA5S,CAAkB+K,GACnBtuF,KAAK23E,gBAAkB33E,KAAKm2F,OAKhCn2F,KAAKm2F,KAAK9H,iBAAiBC,GAC3BtuF,KAAKm2F,KAAKthF,EAAI7U,KAAKk2F,QAAQrhF,EAC3B7U,KAAKm2F,KAAKhiF,EAAInU,KAAKk2F,QAAQ/hF,EAC3BnU,KAAK23E,cAAgB33E,KAAKm2F,KAC1Bn2F,KAAKi2F,kBAAkBhlF,KAAK,CAC1B00D,aAAc3lE,KAAKm2F,KACnBC,eAAgBp2F,KAAKk2F,UAEzB,CAOO,MAAA/8E,CAAOo1E,EAAiBC,GAC7BxuF,KAAKk2F,QAAQ/8E,OAAOo1E,EAASC,GAC7BxuF,KAAKm2F,KAAKh9E,OAAOo1E,EAASC,GAC1BxuF,KAAK6tF,cAAcU,EACrB,CAMO,aAAAV,CAAc/uF,GACnBkB,KAAKk2F,QAAQrI,cAAc/uF,GAC3BkB,KAAKm2F,KAAKtI,cAAc/uF,EAC1B,gGClIF,MAAA60E,EAAAz0E,EAAA,KACAylC,EAAAzlC,EAAA,MACAmsC,EAAAnsC,EAAA,MAMA,MAAAmrB,UAA8BghB,EAAAoD,cAA9B,WAAA/uC,uBAQSM,KAAA02D,QAAU,EACV12D,KAAAiM,GAAK,EACLjM,KAAAgM,GAAK,EACLhM,KAAAgrB,SAA2B,IAAIqgB,EAAAqgD,cAC/B1rF,KAAA22D,aAAe,EA4HxB,CAtIS,mBAAOy2B,CAAa3iF,GACzB,MAAM4rF,EAAM,IAAIhsE,EAEhB,OADAgsE,EAAIx/B,gBAAgBpsD,GACb4rF,CACT,CAQO,UAAAz/B,GACL,OAAmB,QAAZ52D,KAAK02D,OACd,CAEO,QAAA3hD,GACL,OAAO/U,KAAK02D,SAAO,EACrB,CAEO,QAAA/oB,GACL,OAAgB,QAAZ3tC,KAAK02D,QACA12D,KAAK22D,aAEE,QAAZ32D,KAAK02D,SACA,EAAAid,EAAAuM,qBAAgC,QAAZlgF,KAAK02D,SAE3B,EACT,CAOO,OAAAvmB,GACL,OAAQnwC,KAAK42D,aACT52D,KAAK22D,aAAal3C,WAAWzf,KAAK22D,aAAap1D,OAAS,GAC5C,QAAZvB,KAAK02D,OACX,CAEO,eAAAG,CAAgBpsD,GACrBzK,KAAKiM,GAAKxB,EAAMk6B,EAAA6tD,sBAChBxyF,KAAKgM,GAAK,EACV,IAAIsqF,GAAW,EAEf,GAAI7rF,EAAMk6B,EAAA8tD,sBAAsBlxF,OAAS,EACvC+0F,GAAW,OAER,GAA2C,IAAvC7rF,EAAMk6B,EAAA8tD,sBAAsBlxF,OAAc,CACjD,MAAMy5B,EAAOvwB,EAAMk6B,EAAA8tD,sBAAsBhzE,WAAW,GAGpD,GAAI,OAAUub,GAAQA,GAAQ,MAAQ,CACpC,MAAMyqD,EAASh7E,EAAMk6B,EAAA8tD,sBAAsBhzE,WAAW,GAClD,OAAUgmE,GAAUA,GAAU,MAChCzlF,KAAK02D,QAA6B,MAAjB17B,EAAO,OAAkByqD,EAAS,MAAS,MAAYh7E,EAAMk6B,EAAA+tD,wBAAsB,GAGpG4D,GAAW,CAEf,MAEEA,GAAW,CAEf,MAEEt2F,KAAK02D,QAAUjsD,EAAMk6B,EAAA8tD,sBAAsBhzE,WAAW,GAAMhV,EAAMk6B,EAAA+tD,wBAAsB,GAEtF4D,IACFt2F,KAAK22D,aAAelsD,EAAMk6B,EAAA8tD,sBAC1BzyF,KAAK02D,QAAU,QAA4BjsD,EAAMk6B,EAAA+tD,wBAAsB,GAE3E,CAEO,aAAA57B,GACL,MAAO,CAAC92D,KAAKiM,GAAIjM,KAAK2tC,WAAY3tC,KAAK+U,WAAY/U,KAAKmwC,UAC1D,CAEO,gBAAAomD,CAAiBh1C,GACtB,GAAIvhD,KAAKgvC,mBAAqBuS,EAAMvS,kBAAoBhvC,KAAK8uC,eAAiByS,EAAMzS,aAClF,OAAO,EAET,GAAI9uC,KAAKmvC,mBAAqBoS,EAAMpS,kBAAoBnvC,KAAKivC,eAAiBsS,EAAMtS,aAClF,OAAO,EAET,GAAIjvC,KAAKovC,cAAgBmS,EAAMnS,YAC7B,OAAO,EAET,GAAIpvC,KAAK+tC,WAAawT,EAAMxT,SAC1B,OAAO,EAET,GAAI/tC,KAAK6tC,gBAAkB0T,EAAM1T,cAC/B,OAAO,EAET,GAAI7tC,KAAK6tC,cAAe,CACtB,GAAI7tC,KAAKssF,sBAAwB/qC,EAAM+qC,oBACrC,OAAO,EAET,MAAMkK,EAAcx2F,KAAKsuC,0BACnBmoD,EAAel1C,EAAMjT,0BAC3B,IAAMkoD,IAAeC,EAAe,CAClC,GAAID,IAAgBC,EAClB,OAAO,EAET,GAAIz2F,KAAK0uC,sBAAwB6S,EAAM7S,oBACrC,OAAO,EAET,GAAI1uC,KAAKosF,0BAA4B7qC,EAAM6qC,wBACzC,OAAO,CAEX,CACF,CACA,OAAIpsF,KAAK8tC,eAAiByT,EAAMzT,cAG5B9tC,KAAKstC,YAAciU,EAAMjU,WAGzBttC,KAAKmuC,gBAAkBoT,EAAMpT,eAG7BnuC,KAAKguC,aAAeuT,EAAMvT,YAG1BhuC,KAAKouC,UAAYmT,EAAMnT,SAGvBpuC,KAAK4uC,oBAAsB2S,EAAM3S,iBAIvC,sVC/IWnwC,EAAAi4F,cAAgB,EAChBj4F,EAAAk4F,aAA4Bl4F,EAAAi4F,eAAiB,EAAM,IACnDj4F,EAAAm4F,YAAc,EAEdn4F,EAAA+zF,qBAAuB,EACvB/zF,EAAAg0F,qBAAuB,EACvBh0F,EAAAi0F,sBAAwB,EACxBj0F,EAAA+sF,qBAAuB,EAOvB/sF,EAAA4uF,eAAiB,GACjB5uF,EAAAoiF,gBAAkB,EAClBpiF,EAAAmiF,eAAiB,EAOjBniF,EAAAmvC,qBAAuB,IACvBnvC,EAAA8uF,sBAAwB,EACxB9uF,EAAAgtF,qBAAuB,iFCzBpC,MAAArsF,EAAAF,EAAA,MAEA8O,EAAA9O,EAAA,MAEA,MAAA4yF,EAOE,MAAW33D,GAAe,OAAOn6B,KAAK62F,GAAK,CAK3C,WAAAn3F,CACS6E,GAAAvE,KAAAuE,KAAAA,EAVFvE,KAAAo3B,YAAsB,EACZp3B,KAAAunF,aAA8B,GAE9BvnF,KAAA62F,IAAc/E,EAAOgF,UAGrB92F,KAAA+2F,WAAa/2F,KAAK2d,SAAS,IAAI3P,EAAAsB,SAChCtP,KAAAi0B,UAAYj0B,KAAK+2F,WAAWxoF,KAK5C,CAEO,OAAA8K,GACDrZ,KAAKo3B,aAGTp3B,KAAKo3B,YAAa,EAClBp3B,KAAKuE,MAAQ,EAEbvE,KAAK+2F,WAAW9lF,QAChB,EAAA7R,EAAAia,SAAQrZ,KAAKunF,cACbvnF,KAAKunF,aAAahmF,OAAS,EAC7B,CAEO,QAAAoc,CAAgCxB,GAErC,OADAnc,KAAKunF,aAAatjF,KAAKkY,GAChBA,CACT,aA/Be21E,EAAAgF,QAAU,kGCEdr4F,EAAAg/E,SAAoD,GAKpDh/E,EAAAwkF,gBAAwCxkF,EAAAg/E,SAAY,EAYjEh/E,EAAAg/E,SAAA,GAAgB,CACd,IAAK,IACL5+E,EAAK,IACL0lB,EAAK,IACLyK,EAAK,IACLye,EAAK,IACLtsC,EAAK,IACL2iF,EAAK,IACLj1D,EAAK,IACLmoE,EAAK,IACLl4F,EAAK,IACLkpB,EAAK,IACLivE,EAAK,IACL/R,EAAK,IACLtiD,EAAK,IACL6rB,EAAK,IACL+4B,EAAK,IACLvJ,EAAK,IACLiZ,EAAK,IACLtoE,EAAK,IACLg+C,EAAK,IACLtoB,EAAK,IACL6yC,EAAK,IACLpuE,EAAK,IACLi1B,EAAK,IACLnpC,EAAK,IACLV,EAAK,IACL2gB,EAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPr2B,EAAAg/E,SAAA2Z,EAAgB,CACd,IAAK,KAOP34F,EAAAg/E,SAAA4Z,OAAgBzyF,EAOhBnG,EAAAg/E,SAAA,GAAgB,CACd,IAAK,IACL,IAAK,IACL,IAAK,KACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPh/E,EAAAg/E,SAAA6Z,EAAgB74F,EAAAg/E,SAAA,GAAgB,CAC9B,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPh/E,EAAAg/E,SAAA8Z,EAAgB,CACd,IAAK,IACL,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQP94F,EAAAg/E,SAAA+Z,EAAgB,CACd,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQP/4F,EAAAg/E,SAAAga,EAAgB,CACd,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPh5F,EAAAg/E,SAAAia,EAAgB,CACd,IAAK,IACL,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPj5F,EAAAg/E,SAAAka,EAAgBl5F,EAAAg/E,SAAA,GAAgB,CAC9B,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPh/E,EAAAg/E,SAAAma,EAAgB,CACd,IAAK,IACL,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPn5F,EAAAg/E,SAAAoa,EAAgBp5F,EAAAg/E,SAAA,GAAgB,CAC9B,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,KAQPh/E,EAAAg/E,SAAA,KAAgB,CACd,IAAK,IACL,IAAK,IACL,IAAK,IACL,KAAM,IACN,IAAK,IACL,IAAK,IAELqa,EAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,IACL,IAAK,wFCtNP,SACEntF,EACAotF,EACAp5E,EACAC,GAEA,MAAMI,EAA0B,CAC9BxN,KAAI,EAGJ4N,QAAQ,EAERnc,SAAK2B,GAEDozF,GAAartF,EAAG00C,SAAW,EAAI,IAAM10C,EAAGkU,OAAS,EAAI,IAAMlU,EAAG4U,QAAU,EAAI,IAAM5U,EAAG6U,QAAU,EAAI,GACzG,OAAQ7U,EAAGqV,SACT,KAAK,EACY,sBAAXrV,EAAG1H,IAEH+b,EAAO/b,IADL80F,EACW,MAEA,MAGG,wBAAXptF,EAAG1H,IAER+b,EAAO/b,IADL80F,EACW,MAEA,MAGG,yBAAXptF,EAAG1H,IAER+b,EAAO/b,IADL80F,EACW,MAEA,MAGG,wBAAXptF,EAAG1H,MAER+b,EAAO/b,IADL80F,EACW,MAEA,OAGjB,MACF,KAAK,EAEH/4E,EAAO/b,IAAM0H,EAAG4U,QAAU,KAAM,IAC5B5U,EAAGkU,SACLG,EAAO/b,IAAM,IAAS+b,EAAO/b,KAE/B,MACF,KAAK,EAEH,GAAI0H,EAAG00C,SAAU,CACfrgC,EAAO/b,IAAM,MACb,KACF,CACA+b,EAAO/b,IAAG,KACV+b,EAAOI,QAAS,EAChB,MACF,KAAK,GAEY,MAAXzU,EAAG1H,KAAe0H,EAAG4U,QAGvBP,EAAO/b,IAAG,IAEV+b,EAAO/b,IAAM0H,EAAGkU,OAAS,MAAgB,KAE3CG,EAAOI,QAAS,EAChB,MACF,KAAK,GAEHJ,EAAO/b,IAAG,IACN0H,EAAGkU,SACLG,EAAO/b,IAAM,MAEf+b,EAAOI,QAAS,EAChB,MACF,KAAK,GAEH,GAAIzU,EAAG6U,QACL,MAGAR,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAEH,GAAIptF,EAAG6U,QACL,MAGAR,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAEH,GAAIptF,EAAG6U,QACL,MAGAR,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAEH,GAAIptF,EAAG6U,QACL,MAGAR,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAEEptF,EAAG00C,UAAa10C,EAAG4U,UAGtBP,EAAO/b,IAAM,QAEf,MACF,KAAK,GAGD+b,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IAEnC,OAEf,MACF,KAAK,GAGDh5E,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAGD/4E,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IACvCD,EACI,MAEA,MAEf,MACF,KAAK,GAECptF,EAAG00C,SACLrgC,EAAOxN,KAAI,EACF7G,EAAG4U,QACZP,EAAO/b,IAAM,QAAkB+0F,EAAY,GAAK,IAEhDh5E,EAAO/b,IAAM,OAEf,MACF,KAAK,GAEC0H,EAAG00C,SACLrgC,EAAOxN,KAAI,EACF7G,EAAG4U,QACZP,EAAO/b,IAAM,QAAkB+0F,EAAY,GAAK,IAEhDh5E,EAAO/b,IAAM,OAEf,MACF,KAAK,IAGD+b,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IAEnC,MAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IAEnC,MAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IAEnC,MAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,QAAkBA,EAAY,GAAK,IAEnC,MAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,KAAK,IAEDh5E,EAAO/b,IADL+0F,EACW,SAAmBA,EAAY,GAAK,IAEpC,QAEf,MACF,QAEE,IAAIrtF,EAAG4U,SAAY5U,EAAG00C,UAAa10C,EAAGkU,QAAWlU,EAAG6U,QAmB7C,GAAMb,IAASC,IAAoBjU,EAAGkU,QAAWlU,EAAG6U,QA4BpD,IAAIb,GAAUhU,EAAGkU,QAAWlU,EAAG4U,SAAY5U,EAAG00C,WAAY10C,EAAG6U,SAI7D,GAAI7U,EAAG1H,MAAQ0H,EAAG4U,UAAY5U,EAAGkU,SAAWlU,EAAG6U,SAAW7U,EAAGqV,SAAW,IAAwB,IAAlBrV,EAAG1H,IAAI1B,OAG1Fyd,EAAO/b,IAAM0H,EAAG1H,SACX,GAAI0H,EAAG1H,KAAO0H,EAAG4U,SAAW5U,EAAG00C,SACpC,OAAQ10C,EAAGqwB,MACT,IAAK,QAAUhc,EAAO/b,IAAG,IAAW,MACpC,IAAK,SAAU+b,EAAO/b,IAAG,KAAW,MACpC,IAAK,SAAU+b,EAAO/b,IAAG,UAXR,KAAf0H,EAAGqV,UACLhB,EAAOxN,KAAI,OA9BqD,CAElE,MAAMymF,EAAaC,EAAqBvtF,EAAGqV,SACrC/c,EAAMg1F,IAActtF,EAAG00C,SAAe,EAAJ,GACxC,GAAIp8C,EACF+b,EAAO/b,IAAM,IAASA,OACjB,GAAI0H,EAAGqV,SAAW,IAAMrV,EAAGqV,SAAW,GAAI,CAC/C,MAAMA,EAAUrV,EAAG4U,QAAU5U,EAAGqV,QAAU,GAAKrV,EAAGqV,QAAU,GAC5D,IAAIm4E,EAAY/3E,OAAOC,aAAaL,GAChCrV,EAAG00C,WACL84C,EAAYA,EAAUC,eAExBp5E,EAAO/b,IAAM,IAASk1F,CACxB,MAAO,GAAmB,KAAfxtF,EAAGqV,QACZhB,EAAO/b,IAAM,KAAU0H,EAAG4U,QAAS,KAAU,UACxC,GAAe,SAAX5U,EAAG1H,KAAkB0H,EAAGqwB,KAAKoC,WAAW,OAAQ,CAMzD,IAAI+6D,EAAYxtF,EAAGqwB,KAAKzzB,MAAM,EAAG,GAC5BoD,EAAG00C,WACN84C,EAAYA,EAAUE,eAExBr5E,EAAO/b,IAAM,IAASk1F,EACtBn5E,EAAOI,QAAS,CAClB,CACF,MA9CMzU,EAAGqV,SAAW,IAAMrV,EAAGqV,SAAW,GACpChB,EAAO/b,IAAMmd,OAAOC,aAAa1V,EAAGqV,QAAU,IACtB,KAAfrV,EAAGqV,QACZhB,EAAO/b,IAAG,KACD0H,EAAGqV,SAAW,IAAMrV,EAAGqV,SAAW,GAE3ChB,EAAO/b,IAAMmd,OAAOC,aAAa1V,EAAGqV,QAAU,GAAK,IAC3B,KAAfrV,EAAGqV,QACZhB,EAAO/b,IAAG,IACU,MAAX0H,EAAG1H,IACZ+b,EAAO/b,IAAG,IACc,MAAf0H,EAAGqV,QACZhB,EAAO/b,IAAG,IACc,MAAf0H,EAAGqV,QACZhB,EAAO/b,IAAG,IACc,MAAf0H,EAAGqV,UACZhB,EAAO/b,IAAG,KAgDlB,OAAO+b,CACT,EAjXA,MAAMk5E,EAA2D,CAE/D,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KACV,GAAI,CAAC,IAAK,KAGV,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,KAAM,KACZ,IAAK,CAAC,IAAK,KACX,IAAK,CAAC,IAAM,yGCsBd,iBAAAx4F,GAKmBM,KAAAs4F,oBAAiD,CAChEC,OAAU,GACVC,MAAS,GACTC,IAAO,EACPC,UAAa,IACbC,SAAY,MACZC,WAAc,MACdC,QAAW,MACXC,YAAe,MACfC,MAAS,MACTC,YAAe,MAEfC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MACPC,IAAO,MAEPC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,KAAQ,MACRC,WAAc,MACdC,UAAa,MACbC,YAAe,MACfC,YAAe,MACfC,OAAU,MACVC,SAAY,MACZC,SAAY,MAEZC,UAAa,MACbC,WAAc,MACdC,YAAe,MACfC,aAAgB,MAChBC,QAAW,MACXC,SAAY,MACZC,SAAY,MACZC,UAAa,MAEbC,eAAkB,MAClBC,UAAa,MACbC,eAAkB,MAClBC,mBAAsB,MACtBC,gBAAmB,MACnBC,cAAiB,MACjBC,gBAAmB,OAMJ77F,KAAA87F,cAA2C,CAC1DC,OAAU,EACVC,OAAU,EACVC,OAAU,EACVC,SAAY,EACZC,GAAM,GACNC,GAAM,GACNC,GAAM,GACNC,GAAM,GACNC,GAAM,GACNC,IAAO,GACPC,IAAO,GACPC,IAAO,IAMQ18F,KAAA28F,eAA4C,CAC3DC,QAAW,IACXC,UAAa,IACbC,WAAc,IACdC,UAAa,IACbC,KAAQ,IACRC,IAAO,KAMQj9F,KAAAk9F,iBAA8C,CAC7DC,GAAM,IACNC,GAAM,IACNC,GAAM,IACNC,GAAM,IA6WV,CAvWU,iBAAAC,CAAkB5yF,GACxB,GAAIA,EAAGqwB,KAAKoC,WAAW,UAAW,CAChC,MAAMvB,EAASlxB,EAAGqwB,KAAKzzB,MAAM,GAC7B,GAAIs0B,GAAU,KAAOA,GAAU,IAC7B,OAAO,MAAQh0B,SAASg0B,EAAQ,IAElC,OAAQA,GACN,IAAK,UAAW,OAAO,MACvB,IAAK,SAAU,OAAO,MACtB,IAAK,WAAY,OAAO,MACxB,IAAK,WAAY,OAAO,MACxB,IAAK,MAAO,OAAO,MACnB,IAAK,QAAS,OAAO,MACrB,IAAK,QAAS,OAAO,MAEzB,CAEF,CAKQ,mBAAA2hE,CAAoB7yF,GAC1B,OAAQA,EAAGqwB,MACT,IAAK,YAAa,OAAO,MACzB,IAAK,aAAc,OAAO,MAC1B,IAAK,cAAe,OAAO,MAC3B,IAAK,eAAgB,OAAO,MAC5B,IAAK,UAAW,OAAO,MACvB,IAAK,WAAY,OAAO,MACxB,IAAK,WAAY,OAAO,MACxB,IAAK,YAAa,OAAO,MAG7B,CAMQ,gBAAAyiE,CAAiB9yF,GACvB,IAAI+yF,EAAO,EAKX,OAJI/yF,EAAG00C,WAAUq+C,GAAI,GACjB/yF,EAAGkU,SAAQ6+E,GAAI,GACf/yF,EAAG4U,UAASm+E,GAAI,GAChB/yF,EAAG6U,UAASk+E,GAAI,GACbA,EAAO,EAAIA,EAAO,EAAI,CAC/B,CAOQ,WAAAC,CAAYhzF,EAAoBizF,GACtC,MAAMC,EAAa79F,KAAKu9F,kBAAkB5yF,GAC1C,QAAmB/F,IAAfi5F,EACF,OAAOA,EAGT,MAAMC,EAAe99F,KAAKw9F,oBAAoB7yF,GAC9C,QAAqB/F,IAAjBk5F,EACF,OAAOA,EAGT,MAAMC,EAAW/9F,KAAKs4F,oBAAoB3tF,EAAG1H,KAC7C,QAAiB2B,IAAbm5F,EACF,OAAOA,EAGT,IAAKpzF,EAAG00C,UAAau+C,GAAkBjzF,EAAGkU,SAAYlU,EAAGqwB,KAAM,CAC7D,GAAIrwB,EAAGqwB,KAAKoC,WAAW,UAA+B,IAAnBzyB,EAAGqwB,KAAKz5B,OAAc,CACvD,MAAMy8F,EAAQrzF,EAAGqwB,KAAKsrC,OAAO,GAC7B,GAAI03B,GAAS,KAAOA,GAAS,IAC3B,OAAOA,EAAMv+E,WAAW,EAE5B,CACA,GAAI9U,EAAGqwB,KAAKoC,WAAW,QAA6B,IAAnBzyB,EAAGqwB,KAAKz5B,OAEvC,OADeoJ,EAAGqwB,KAAKsrC,OAAO,GAAG+xB,cACnB54E,WAAW,EAE7B,CAEA,GAAsB,IAAlB9U,EAAG1H,IAAI1B,OAAc,CACvB,MAAMy5B,EAAOrwB,EAAG1H,IAAIw/E,YAAY,GAChC,OAAIznD,GAAQ,IAAMA,GAAQ,GACjBA,EAAO,GAETA,CACT,CAGF,CAKQ,cAAAijE,CAAetzF,GACrB,MAAkB,UAAXA,EAAG1H,KAA8B,YAAX0H,EAAG1H,KAAgC,QAAX0H,EAAG1H,KAA4B,SAAX0H,EAAG1H,GAC9E,CAWQ,UAAAi7F,CAAWvzF,GACjB,MAAkB,aAAXA,EAAG1H,KAAiC,YAAX0H,EAAG1H,KAAgC,eAAX0H,EAAG1H,GAC7D,CAMQ,uBAAAk7F,CACNC,EACApG,EACA30E,EACAg7E,GAEA,MAAMC,EAAiBD,GAA6B,IAATh7E,EAE3C,GAAI20E,EAAY,GAAKsG,EAAgB,CACnC,IAAIC,EAAM,QAAkBvG,EAAY,EAAIA,EAAY,KAKxD,OAJIsG,IACFC,GAAO,IAAMl7E,GAEfk7E,GAAOH,EACAG,CACT,CACA,MAAO,KAAeH,CACxB,CAOQ,iBAAAI,CACNJ,EACApG,EACA30E,EACAg7E,GAEA,MAAMC,EAAiBD,GAA6B,IAATh7E,EAE3C,GAAI20E,EAAY,GAAKsG,EAAgB,CACnC,IAAIC,EAAM,QAAkBvG,EAAY,EAAIA,EAAY,KAKxD,OAJIsG,IACFC,GAAO,IAAMl7E,GAEfk7E,GAAOH,EACAG,CACT,CACA,MAAO,KAAeH,CACxB,CAMQ,sBAAAK,CACNC,EACA1G,EACA30E,EACAg7E,GAEA,MAAMC,EAAiBD,GAA6B,IAATh7E,EAE3C,IAAIk7E,EAAM,KAAeG,EAQzB,OAPI1G,EAAY,GAAKsG,KACnBC,GAAO,KAAOvG,EAAY,EAAIA,EAAY,KACtCsG,IACFC,GAAO,IAAMl7E,IAGjBk7E,GAAO,IACAA,CACT,CAMQ,kBAAAI,CACNh0F,EACAqV,EACAg4E,EACA30E,EACAy3C,EACA8jC,EACAC,GAEA,MAAMR,KAA2B,EAALvjC,GAG5B,IAEIgkC,EAFAP,EAAM,KAAev+E,EAFW,EAAL86C,GAKJnwD,EAAG00C,UAA8B,IAAlB10C,EAAG1H,IAAI1B,SAAiBq9F,IAAWC,IAC3EC,EAAan0F,EAAG1H,IAAIw/E,YAAY,GAChC8b,GAAO,IAAMO,GAGf,MAMMC,EAN+B,GAALjkC,GACrB,IAATz3C,GACkB,IAAlB1Y,EAAG1H,IAAI1B,SACNq9F,IACAC,IACAl0F,EAAG4U,QACkC5U,EAAG1H,IAAIw/E,YAAY,QAAK79E,EAE1D05F,EAAiBD,GACZ,IAATh7E,IACU,IAATA,QAA6Dze,IAAbm6F,GAmBnD,OAjBI/G,EAAY,GAAKsG,QAA+B15F,IAAbm6F,KACrCR,GAAO,IACHvG,EAAY,EACduG,GAAOvG,EACEsG,IACTC,GAAO,KAELD,IACFC,GAAO,IAAMl7E,SAIAze,IAAbm6F,IACFR,GAAO,IAAMQ,GAGfR,GAAO,IACAA,CACT,CAWO,QAAAxjC,CACLpwD,EACAmwD,EACAz3C,EAAS,EACTu6E,GAA0B,GAE1B,MAAM5+E,EAA0B,CAC9BxN,KAAI,EACJ4N,QAAQ,EACRnc,SAAK2B,GAGDozF,EAAYh4F,KAAKy9F,iBAAiB9yF,GAClCk0F,EAAQ7+F,KAAKi+F,eAAetzF,GAC5B0zF,KAA2B,EAALvjC,GAE5B,IAAKujC,GAA6B,IAATh7E,EACvB,OAAOrE,EAGT,GAAI6/E,KAAgB,EAAL/jC,GACb,OAAO97C,EAOT,GAAIhf,KAAKk+F,WAAWvzF,MAAc,EAALmwD,GAC3B,OAAO97C,EAGT,MAAMggF,EAAYh/F,KAAK28F,eAAehyF,EAAG1H,KACzC,GAAI+7F,EAGF,OAFAhgF,EAAO/b,IAAMjD,KAAKm+F,wBAAwBa,EAAWhH,EAAW30E,EAAWg7E,GAC3Er/E,EAAOI,QAAS,EACTJ,EAGT,MAAMigF,EAAYj/F,KAAKk9F,iBAAiBvyF,EAAG1H,KAC3C,GAAIg8F,EAGF,OAFAjgF,EAAO/b,IAAMjD,KAAKw+F,kBAAkBS,EAAWjH,EAAW30E,EAAWg7E,GACrEr/E,EAAOI,QAAS,EACTJ,EAGT,MAAMkgF,EAAYl/F,KAAK87F,cAAcnxF,EAAG1H,KACxC,QAAkB2B,IAAds6F,EAGF,OAFAlgF,EAAO/b,IAAMjD,KAAKy+F,uBAAuBS,EAAWlH,EAAW30E,EAAWg7E,GAC1Er/E,EAAOI,QAAS,EACTJ,EAGT,MAAMgB,EAAUhgB,KAAK29F,YAAYhzF,EAAIizF,GACrC,QAAgBh5F,IAAZob,EACF,OAAOhB,EAIT,MAAMmgF,EAAyB,KAAZn/E,GAA8B,IAAZA,GAA6B,MAAZA,EAItD,GAAIm/E,GAAuB,IAAT97E,KAAuD,EAALy3C,GAClE,OAAO97C,EAGT,MAAM4/E,OAA8Ch6F,IAArC5E,KAAKs4F,oBAAoB3tF,EAAG1H,WAAqD2B,IAA/B5E,KAAKu9F,kBAAkB5yF,GAsBxF,GAnBO,EAALmwD,GACCujC,GAA6B,IAATh7E,IAId,EAALy3C,GAAwDujC,KAKrDO,IAAWO,GAETnH,EAAY,GAAuB,IAAlBrtF,EAAG1H,IAAI1B,QACzBy2F,EAAY,EAAC,GAOnBh5E,EAAO/b,IAAMjD,KAAK2+F,mBAAmBh0F,EAAIqV,EAASg4E,EAAW30E,EAAWy3C,EAAO8jC,EAAQC,GACvF7/E,EAAOI,QAAS,MACX,CACL,MAAMggF,EAAyB,KAAZp/E,EAAiB,KAAmB,IAAZA,EAAgB,KAAmB,MAAZA,EAAkB,SAASpb,EACzFw6F,EACFpgF,EAAO/b,IAAMm8F,EACc,IAAlBz0F,EAAG1H,IAAI1B,QAAiBoJ,EAAG4U,SAAY5U,EAAGkU,QAAWlU,EAAG6U,UACjER,EAAO/b,IAAM0H,EAAG1H,IAEpB,CAEA,OAAO+b,CACT,CAKO,wBAAOi8C,CAAkBH,GAC9B,OAAOA,EAAQ,CACjB,yHChgBF,SAAoC63B,GAClC,OAAIA,EAAY,OACdA,GAAa,MACNvyE,OAAOC,aAAiC,OAAnBsyE,GAAa,KAAgBvyE,OAAOC,aAAcsyE,EAAY,KAAS,QAE9FvyE,OAAOC,aAAasyE,EAC7B,kBAOA,SAA8B11E,EAAmB5a,EAAgB,EAAGC,EAAc2a,EAAK1b,QACrF,IAAIyd,EAAS,GACb,IAAK,IAAIlgB,EAAIuD,EAAOvD,EAAIwD,IAAOxD,EAAG,CAChC,IAAIqzC,EAAYl1B,EAAKne,GACjBqzC,EAAY,OAMdA,GAAa,MACbnzB,GAAUoB,OAAOC,aAAiC,OAAnB8xB,GAAa,KAAgB/xB,OAAOC,aAAc8xB,EAAY,KAAS,QAEtGnzB,GAAUoB,OAAOC,aAAa8xB,EAElC,CACA,OAAOnzB,CACT,kBAMA,iBAAAtf,GACUM,KAAAq/F,SAAmB,CAkE7B,CA7DS,KAAAhzF,GACLrM,KAAKq/F,SAAW,CAClB,CAUO,MAAApgB,CAAOz+D,EAAerb,GAC3B,MAAM5D,EAASif,EAAMjf,OAErB,IAAKA,EACH,OAAO,EAGT,IAAI6lB,EAAO,EACPk4E,EAAW,EAGf,GAAIt/F,KAAKq/F,SAAU,CACjB,MAAM5Z,EAASjlE,EAAMf,WAAW6/E,KAC5B,OAAU7Z,GAAUA,GAAU,MAChCtgF,EAAOiiB,KAAqC,MAA1BpnB,KAAKq/F,SAAW,OAAkB5Z,EAAS,MAAS,OAGtEtgF,EAAOiiB,KAAUpnB,KAAKq/F,SACtBl6F,EAAOiiB,KAAUq+D,GAEnBzlF,KAAKq/F,SAAW,CAClB,CAEA,IAAK,IAAIvgG,EAAIwgG,EAAUxgG,EAAIyC,IAAUzC,EAAG,CACtC,MAAMk8B,EAAOxa,EAAMf,WAAW3gB,GAE9B,GAAI,OAAUk8B,GAAQA,GAAQ,MAAQ,CACpC,KAAMl8B,GAAKyC,EAET,OADAvB,KAAKq/F,SAAWrkE,EACT5T,EAET,MAAMq+D,EAASjlE,EAAMf,WAAW3gB,GAC5B,OAAU2mF,GAAUA,GAAU,MAChCtgF,EAAOiiB,KAA4B,MAAjB4T,EAAO,OAAkByqD,EAAS,MAAS,OAG7DtgF,EAAOiiB,KAAU4T,EACjB71B,EAAOiiB,KAAUq+D,GAEnB,QACF,CACa,QAATzqD,IAIJ71B,EAAOiiB,KAAU4T,EACnB,CACA,OAAO5T,CACT,iBAMF,iBAAA1nB,GACSM,KAAAu/F,QAAsB,IAAIC,WAAW,EAgO9C,CA3NS,KAAAnzF,GACLrM,KAAKu/F,QAAQz1D,KAAK,EACpB,CAUO,MAAAm1C,CAAOz+D,EAAmBrb,GAC/B,MAAM5D,EAASif,EAAMjf,OAErB,IAAKA,EACH,OAAO,EAGT,IACIk+F,EACAC,EACAC,EACAC,EACAztD,EALA/qB,EAAO,EAMPk4E,EAAW,EAGf,GAAIt/F,KAAKu/F,QAAQ,GAAI,CACnB,IAAIM,GAAiB,EACjBnuD,EAAK1xC,KAAKu/F,QAAQ,GACtB7tD,GAAyB,MAAV,IAALA,GAAwB,GAAyB,MAAV,IAALA,GAAwB,GAAO,EAC3E,IACIouD,EADAj1F,EAAM,EAEV,MAAQi1F,EAAM9/F,KAAKu/F,UAAU10F,KAASA,EAAM,GAC1C6mC,IAAO,EACPA,GAAY,GAANouD,EAGR,MAAMtuF,EAAsC,MAAV,IAAlBxR,KAAKu/F,QAAQ,IAAwB,EAAmC,MAAV,IAAlBv/F,KAAKu/F,QAAQ,IAAwB,EAAI,EAC/FQ,EAAUvuF,EAAO3G,EACvB,KAAOy0F,EAAWS,GAAS,CACzB,GAAIT,GAAY/9F,EACd,OAAO,EAGT,GADAu+F,EAAMt/E,EAAM8+E,KACS,MAAV,IAANQ,GAAsB,CAEzBR,IACAO,GAAiB,EACjB,KACF,CAEE7/F,KAAKu/F,QAAQ10F,KAASi1F,EACtBpuD,IAAO,EACPA,GAAY,GAANouD,CAEV,CACKD,IAEU,IAATruF,EACEkgC,EAAK,IAEP4tD,IAEAn6F,EAAOiiB,KAAUsqB,EAED,IAATlgC,EACLkgC,EAAK,MAAWA,GAAM,OAAUA,GAAM,OAAkB,QAAPA,IAGnDvsC,EAAOiiB,KAAUsqB,GAGfA,EAAK,OAAYA,EAAK,UAGxBvsC,EAAOiiB,KAAUsqB,IAIvB1xC,KAAKu/F,QAAQz1D,KAAK,EACpB,CAGA,MAAMk2D,EAAWz+F,EAAS,EAC1B,IAAIzC,EAAIwgG,EACR,KAAOxgG,EAAIyC,GAAQ,CAejB,SAAOzC,EAAIkhG,IACiB,KAApBP,EAAQj/E,EAAM1hB,KACU,KAAxB4gG,EAAQl/E,EAAM1hB,EAAI,KACM,KAAxB6gG,EAAQn/E,EAAM1hB,EAAI,KACM,KAAxB8gG,EAAQp/E,EAAM1hB,EAAI,MAExBqG,EAAOiiB,KAAUq4E,EACjBt6F,EAAOiiB,KAAUs4E,EACjBv6F,EAAOiiB,KAAUu4E,EACjBx6F,EAAOiiB,KAAUw4E,EACjB9gG,GAAK,EAOP,GAHA2gG,EAAQj/E,EAAM1hB,KAGV2gG,EAAQ,IACVt6F,EAAOiiB,KAAUq4E,OAGZ,GAAuB,MAAV,IAARA,GAAwB,CAClC,GAAI3gG,GAAKyC,EAEP,OADAvB,KAAKu/F,QAAQ,GAAKE,EACXr4E,EAGT,GADAs4E,EAAQl/E,EAAM1hB,KACS,MAAV,IAAR4gG,GAAwB,CAE3B5gG,IACA,QACF,CAEA,GADAqzC,GAAqB,GAARstD,IAAiB,EAAa,GAARC,EAC/BvtD,EAAY,IAAM,CAEpBrzC,IACA,QACF,CACAqG,EAAOiiB,KAAU+qB,CAGnB,MAAO,GAAuB,MAAV,IAARstD,GAAwB,CAClC,GAAI3gG,GAAKyC,EAEP,OADAvB,KAAKu/F,QAAQ,GAAKE,EACXr4E,EAGT,GADAs4E,EAAQl/E,EAAM1hB,KACS,MAAV,IAAR4gG,GAAwB,CAE3B5gG,IACA,QACF,CACA,GAAIA,GAAKyC,EAGP,OAFAvB,KAAKu/F,QAAQ,GAAKE,EAClBz/F,KAAKu/F,QAAQ,GAAKG,EACXt4E,EAGT,GADAu4E,EAAQn/E,EAAM1hB,KACS,MAAV,IAAR6gG,GAAwB,CAE3B7gG,IACA,QACF,CAEA,GADAqzC,GAAqB,GAARstD,IAAiB,IAAc,GAARC,IAAiB,EAAa,GAARC,EACtDxtD,EAAY,MAAWA,GAAa,OAAUA,GAAa,OAAyB,QAAdA,EAExE,SAEFhtC,EAAOiiB,KAAU+qB,CAGnB,MAAO,GAAuB,MAAV,IAARstD,GAAwB,CAClC,GAAI3gG,GAAKyC,EAEP,OADAvB,KAAKu/F,QAAQ,GAAKE,EACXr4E,EAGT,GADAs4E,EAAQl/E,EAAM1hB,KACS,MAAV,IAAR4gG,GAAwB,CAE3B5gG,IACA,QACF,CACA,GAAIA,GAAKyC,EAGP,OAFAvB,KAAKu/F,QAAQ,GAAKE,EAClBz/F,KAAKu/F,QAAQ,GAAKG,EACXt4E,EAGT,GADAu4E,EAAQn/E,EAAM1hB,KACS,MAAV,IAAR6gG,GAAwB,CAE3B7gG,IACA,QACF,CACA,GAAIA,GAAKyC,EAIP,OAHAvB,KAAKu/F,QAAQ,GAAKE,EAClBz/F,KAAKu/F,QAAQ,GAAKG,EAClB1/F,KAAKu/F,QAAQ,GAAKI,EACXv4E,EAGT,GADAw4E,EAAQp/E,EAAM1hB,KACS,MAAV,IAAR8gG,GAAwB,CAE3B9gG,IACA,QACF,CAEA,GADAqzC,GAAqB,EAARstD,IAAiB,IAAc,GAARC,IAAiB,IAAc,GAARC,IAAiB,EAAa,GAARC,EAC7EztD,EAAY,OAAYA,EAAY,QAEtC,SAEFhtC,EAAOiiB,KAAU+qB,CACnB,CAGF,CACA,OAAO/qB,CACT,oFCnVF,MAAAqoD,EAAAvwE,EAAA,MAEM+gG,EAAgB,CACpB,CAAC,IAAQ,KAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,MAAQ,OAC7C,CAAC,MAAQ,OAAS,CAAC,MAAQ,OAAS,CAAC,MAAQ,OAC7C,CAAC,MAAQ,OAAS,CAAC,MAAQ,OAAS,CAAC,MAAQ,OAC7C,CAAC,MAAQ,OAAS,CAAC,MAAQ,OAAS,CAAC,MAAQ,QAEzCC,EAAiB,CACrB,CAAC,MAAS,OAAU,CAAC,MAAS,OAAU,CAAC,MAAS,OAClD,CAAC,MAAS,OAAU,CAAC,MAAS,OAAU,CAAC,OAAS,QAClD,CAAC,OAAS,QAAU,CAAC,OAAS,QAAU,CAAC,OAAS,QAClD,CAAC,OAAS,QAAU,CAAC,OAAS,QAAU,CAAC,OAAS,QAClD,CAAC,OAAS,SAIZ,IAAIC,cAsBJ,MAGE,WAAAzgG,GAEE,GAJcM,KAAAogG,QAAU,KAInBD,EAAO,CACVA,EAAQ,IAAIX,WAAW,OACvBW,EAAMr2D,KAAK,GACXq2D,EAAM,GAAK,EAEXA,EAAMr2D,KAAK,EAAG,EAAG,IACjBq2D,EAAMr2D,KAAK,EAAG,IAAM,KAIpBq2D,EAAMr2D,KAAK,EAAG,KAAQ,MACtBq2D,EAAM,MAAU,EAChBA,EAAM,MAAU,EAChBA,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAM,OAAU,EAEhBA,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAMr2D,KAAK,EAAG,MAAQ,OACtBq2D,EAAMr2D,KAAK,EAAG,MAAQ,OAOtB,IAAK,IAAIlb,EAAI,EAAGA,EAAIqxE,EAAc1+F,SAAUqtB,EAC1CuxE,EAAMr2D,KAAK,EAAGm2D,EAAcrxE,GAAG,GAAIqxE,EAAcrxE,GAAG,GAAK,EAE7D,CACF,CAEO,OAAAyxE,CAAQC,GACb,OAAIA,EAAM,GAAW,EACjBA,EAAM,IAAY,EAClBA,EAAM,MAAcH,EAAMG,GA9DlC,SAAkBC,EAAatjF,GAC7B,IAEI0sE,EAFA/0E,EAAM,EACNiZ,EAAM5Q,EAAK1b,OAAS,EAExB,GAAIg/F,EAAMtjF,EAAK,GAAG,IAAMsjF,EAAMtjF,EAAK4Q,GAAK,GACtC,OAAO,EAET,KAAOA,GAAOjZ,GAEZ,GADA+0E,EAAO/0E,EAAMiZ,GAAQ,EACjB0yE,EAAMtjF,EAAK0sE,GAAK,GAClB/0E,EAAM+0E,EAAM,MACP,MAAI4W,EAAMtjF,EAAK0sE,GAAK,IAGzB,OAAO,EAFP97D,EAAM87D,EAAM,CAGd,CAEF,OAAO,CACT,CA6CQ6W,CAASF,EAAKJ,GAAwB,EACrCI,GAAO,QAAWA,GAAO,QAAaA,GAAO,QAAWA,GAAO,OAAiB,EAC9E,CACT,CAEO,cAAAxgB,CAAe3tC,EAAmBsuD,GACvC,IAAI13F,EAAQ/I,KAAKqgG,QAAQluD,GACrB6tC,EAAuB,IAAVj3E,GAA6B,IAAd03F,EAEhC,GAAIzgB,EAAY,CACd,MAAM59B,EAAWqtB,EAAAoB,eAAekP,aAAa0gB,GAC5B,IAAbr+C,EACF49B,GAAa,EACJ59B,EAAWr5C,IACpBA,EAAQq5C,EAEZ,CACA,OAAOqtB,EAAAoB,eAAe6vB,oBAAoB,EAAG33F,EAAOi3E,EACtD,wGC1GF,iBAAAtgF,GAKmBM,KAAA2gG,UAAwC,CAEvDC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAGRC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAC1EC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAAMC,OAAU,GAG1E5F,GAAM,IAAMC,GAAM,IAAMC,GAAM,IAAMC,GAAM,IAAMnB,GAAM,IAAMC,GAAM,IAClEC,GAAM,IAAMC,GAAM,IAAMC,GAAM,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IACrEzD,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IACxEC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAAMC,IAAO,IAGxEoJ,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,IAC/EC,QAAW,IAAMC,QAAW,IAAMC,QAAW,IAAMC,QAAW,IAAMC,QAAW,IAC/EC,eAAkB,IAAMC,UAAa,IAAMC,gBAAmB,IAC9DC,eAAkB,IAAMC,cAAiB,IAAMC,aAAgB,IAC/DC,YAAe,GACfnL,QAAW,IAGX+D,QAAW,GAAMC,UAAa,GAAME,UAAa,GAAMD,WAAc,GACrEE,KAAQ,GAAMC,IAAO,GAAMhB,OAAU,GAAMC,SAAY,GACvDH,OAAU,GAAMC,OAAU,GAG1BjB,UAAa,GAAMC,WAAc,GACjCC,YAAe,GAAMC,aAAgB,GACrCC,QAAW,GAAMC,SAAY,GAC7BC,SAAY,GAAMC,UAAa,GAC/B3C,SAAY,GAAMC,WAAc,IAGhCL,OAAU,GAAMC,MAAS,GAAMC,IAAO,EAAMwL,MAAS,GACrDvL,UAAa,EAAMK,MAAS,GAAMC,YAAe,GAAMF,YAAe,GAGtEoL,UAAa,IACbC,MAAS,IACTC,MAAS,IACTC,MAAS,IACTC,OAAU,IACVC,MAAS,IACTC,UAAa,IACbC,YAAe,IACfC,UAAa,IACbC,aAAgB,IAChBC,MAAS,IACTC,cAAiB,KAQF7kG,KAAA8kG,gBAA8C,CAE7DlD,KAAQ,GAAMM,KAAQ,GAAMlB,KAAQ,GAAMa,KAAQ,GAAME,KAAQ,GAChEK,KAAQ,GAAMJ,KAAQ,GAAMZ,KAAQ,GAAMM,KAAQ,GAAMC,KAAQ,GAChEf,KAAQ,GAAMkB,KAAQ,GAAMf,KAAQ,GAAME,KAAQ,GAAMC,KAAQ,GAChEC,KAAQ,GAAME,KAAQ,GAAMC,KAAQ,GAAMC,KAAQ,GAClDc,KAAQ,GAAMF,KAAQ,GAAMrB,KAAQ,GAAMmB,KAAQ,GAAMpB,KAAQ,GAChEY,KAAQ,GAAMD,KAAQ,GAGtBe,OAAU,EAAMC,OAAU,EAAMC,OAAU,EAAMC,OAAU,EAAMC,OAAU,EAC1EC,OAAU,EAAMC,OAAU,EAAMC,OAAU,EAAMC,OAAU,GAAMT,OAAU,GAG1EnF,GAAM,GAAMC,GAAM,GAAMC,GAAM,GAAMC,GAAM,GAAMnB,GAAM,GAAMC,GAAM,GAClEC,GAAM,GAAMC,GAAM,GAAMC,GAAM,GAAMC,IAAO,GAAMC,IAAO,GAAMC,IAAO,GAGrEsG,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAC/EC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAAMC,QAAW,GAC/EC,eAAkB,GAAMC,UAAa,GAAME,eAAkB,GAC7DC,cAAiB,GAAMC,aAAgB,GAAMC,YAAe,GAC5DnL,QAAW,GAGX+D,QAAW,GAAMC,UAAa,GAAME,UAAa,GAAMD,WAAc,GACrEE,KAAQ,GAAMC,IAAO,GAAMhB,OAAU,GAAMC,SAAY,GACvDH,OAAU,GAAMC,OAAU,GAG1BjB,UAAa,GAAMC,WAAc,GACjCC,YAAe,GAAMC,aAAgB,GACrCC,QAAW,GAAMC,SAAY,GAC7BzC,SAAY,GAAMC,WAAc,GAGhCL,OAAU,EAAMC,MAAS,GAAMC,IAAO,GAAMwL,MAAS,GACrDvL,UAAa,GAAMK,MAAS,GAG5BmL,UAAa,GAAMC,MAAS,GAAMC,MAAS,GAAMC,MAAS,GAC1DC,OAAU,GAAMC,MAAS,GAAMC,UAAa,GAC5CC,YAAe,GAAMC,UAAa,GAAMC,aAAgB,GAAMC,MAAS,IAMxD5kG,KAAA+kG,kBAAoB,IAAIv9E,IAAI,CAC3C,UAAW,YAAa,YAAa,aACrC,OAAQ,MAAO,SAAU,WAAY,SAAU,SAC/C,cAAe,eACf,eAAgB,WAChB,cAAe,QAAS,cACxB,WAAY,cAQGxnB,KAAAglG,kBAA+C,CAC9DxM,MAAS,GACTE,UAAa,EACbD,IAAO,EACPF,OAAU,GA4Hd,CAtHU,kBAAA0M,CAAmBt6F,GACzB,MAAMu6F,EAAKllG,KAAK2gG,UAAUh2F,EAAGqwB,MAC7B,YAAWp2B,IAAPsgG,EACKA,EAGFv6F,EAAGqV,SAAW,CACvB,CAMQ,YAAAmlF,CAAax6F,GACnB,OAAO3K,KAAK8kG,gBAAgBn6F,EAAGqwB,OAAS,CAC1C,CAMQ,eAAAoqE,CAAgBz6F,GAGtB,GAAIA,EAAG4U,UAAY5U,EAAGkU,SAAWlU,EAAG6U,QAAS,CAC3C,GAAe,UAAX7U,EAAG1H,IACL,OAAO,GAET,GAAe,cAAX0H,EAAG1H,IACL,OAAO,GAEX,CAGA,MAAMoiG,EAAcrlG,KAAKglG,kBAAkBr6F,EAAG1H,KAC9C,QAAoB2B,IAAhBygG,EACF,OAAOA,EAIT,GAAsB,IAAlB16F,EAAG1H,IAAI1B,OAAc,CACvB,MAAMoxF,EAAYhoF,EAAG1H,IAAIw/E,YAAY,IAAM,EAG3C,GAAI93E,EAAG4U,UAAY5U,EAAGkU,SAAWlU,EAAG6U,QAAS,CAE3C,GAAImzE,GAAa,IAAQA,GAAa,GACpC,OAAOA,EAAY,GAErB,GAAIA,GAAa,IAAQA,GAAa,IACpC,OAAOA,EAAY,EAEvB,CAEA,OAAOA,CACT,CACA,OAAO,CACT,CAKQ,mBAAA2S,CAAoB36F,GAC1B,IAAIoX,EAAQ,EA8BZ,OA5BIpX,EAAG00C,WACLt9B,GAAK,IAMHpX,EAAG4U,UACW,iBAAZ5U,EAAGqwB,KACLjZ,GAAK,EAELA,GAAK,GAILpX,EAAGkU,SACW,aAAZlU,EAAGqwB,KACLjZ,GAAK,EAELA,GAAK,GAKL/hB,KAAK+kG,kBAAkBl9E,IAAIld,EAAGqwB,QAChCjZ,GAAK,KAGAA,CACT,CASO,qBAAA44C,CAAsBhwD,EAAoB46F,GAS/C,MAAO,CACL/zF,KAAI,EACJ4N,QAAQ,EACRnc,IAAK,KAXIjD,KAAKilG,mBAAmBt6F,MACxB3K,KAAKmlG,aAAax6F,MAClB3K,KAAKolG,gBAAgBz6F,MACrB46F,EAAY,EAAI,KAChBvlG,KAAKslG,oBAAoB36F,QAStC,sFCjSF,MAAAgY,EAAAzjB,EAAA,MACAE,EAAAF,EAAA,MACA8O,EAAA9O,EAAA,MA2BA,MAAAyyE,UAAiCvyE,EAAAK,WAa/B,WAAAC,CAAoB8lG,GAClBzlG,QADkBC,KAAAwlG,QAAAA,EAZZxlG,KAAAsxE,aAAwC,GACxCtxE,KAAAylG,WAA2C,GAC3CzlG,KAAA0lG,aAAe,EACf1lG,KAAA2lG,cAAgB,EAChB3lG,KAAA4lG,gBAAiB,EACjB5lG,KAAA6lG,WAAa,EACb7lG,KAAA8lG,eAAgB,EAEP9lG,KAAA+lG,iBAAmB/lG,KAAK0B,UAAU,IAAIihB,EAAAomC,cACtC/oD,KAAAqwE,eAAiBrwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SACrCtP,KAAAmiC,cAAgBniC,KAAKqwE,eAAe9hE,MAIlDvO,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKsxE,aAAa/vE,OAAS,EAC3BvB,KAAKylG,WAAWlkG,OAAS,EACzBvB,KAAK0lG,aAAe,EACpB1lG,KAAK2lG,cAAgB,IAEzB,CAEO,eAAAp0B,GACLvxE,KAAK8lG,eAAgB,CACvB,CAUO,SAAA5zB,GACL,GAAIlyE,KAAKm3B,OAAOC,WACd,OAGF,GAAIp3B,KAAK4lG,eACP,OAKF,IAAI5b,EAHJhqF,KAAK4lG,gBAAiB,EAItB,IAAII,GAAa,EACjB,KAAOhc,EAAQhqF,KAAKsxE,aAAa3tE,SAAS,CACxCqiG,GAAa,EACbhmG,KAAKwlG,QAAQxb,GACb,MAAMh6D,EAAKhwB,KAAKylG,WAAW9hG,QACvBqsB,GAAIA,GACV,CAGAhwB,KAAK0lG,aAAe,EACpB1lG,KAAK2lG,cAAgB,WACrB3lG,KAAKsxE,aAAa/vE,OAAS,EAC3BvB,KAAKylG,WAAWlkG,OAAS,EAEzBvB,KAAK4lG,gBAAiB,EAClBI,GACFhmG,KAAKqwE,eAAep/D,MAExB,CAKO,SAAA6gE,CAAU70D,EAA2B80D,GAC1C,GAAI/xE,KAAKm3B,OAAOC,WACd,OAKF,QAA2BxyB,IAAvBmtE,GAAoC/xE,KAAK6lG,WAAa9zB,EAIxD,YADA/xE,KAAK6lG,WAAa,GAWpB,GAPA7lG,KAAK0lG,cAAgBzoF,EAAK1b,OAC1BvB,KAAKsxE,aAAartE,KAAKgZ,GACvBjd,KAAKylG,WAAWxhG,UAAKW,GAGrB5E,KAAK6lG,aAED7lG,KAAK4lG,eACP,OAQF,IAAI5b,EACJ,IAPAhqF,KAAK4lG,gBAAiB,EAOf5b,EAAQhqF,KAAKsxE,aAAa3tE,SAAS,CACxC3D,KAAKwlG,QAAQxb,GACb,MAAMh6D,EAAKhwB,KAAKylG,WAAW9hG,QACvBqsB,GAAIA,GACV,CAGAhwB,KAAK0lG,aAAe,EACpB1lG,KAAK2lG,cAAgB,WAGrB3lG,KAAK4lG,gBAAiB,EACtB5lG,KAAK6lG,WAAa,CACpB,CAEO,KAAA3hE,CAAMjnB,EAA2BqN,GACtC,IAAItqB,KAAKm3B,OAAOC,WAAhB,CAGA,GAAIp3B,KAAK0lG,aAAY,IACnB,MAAM,IAAI3jG,MAAM,+DAIlB,IAAK/B,KAAKsxE,aAAa/vE,OAAQ,CAM7B,GALAvB,KAAK2lG,cAAgB,EAKjB3lG,KAAK8lG,cAMP,OALA9lG,KAAK8lG,eAAgB,EACrB9lG,KAAK0lG,cAAgBzoF,EAAK1b,OAC1BvB,KAAKsxE,aAAartE,KAAKgZ,GACvBjd,KAAKylG,WAAWxhG,KAAKqmB,QACrBtqB,KAAKimG,cAIPjmG,KAAKkmG,qBACP,CAEAlmG,KAAK0lG,cAAgBzoF,EAAK1b,OAC1BvB,KAAKsxE,aAAartE,KAAKgZ,GACvBjd,KAAKylG,WAAWxhG,KAAKqmB,EA1BrB,CA2BF,CA8BQ,mBAAA47E,CAAoBC,EAAmB,EAAGv0B,GAAyB,GACrE5xE,KAAKm3B,OAAOC,YAGhBp3B,KAAK+lG,iBAAiBlhF,aAAa,IAAM7kB,KAAKimG,YAAYE,EAAUv0B,GAAgB,EACtF,CAEU,WAAAq0B,CAAYE,EAAmB,EAAGv0B,GAAyB,GACnE,GAAI5xE,KAAKm3B,OAAOC,WACd,OAEF,MAAMusB,EAAYwiD,GAAY93E,YAAYC,MAC1C,KAAOtuB,KAAKsxE,aAAa/vE,OAASvB,KAAK2lG,eAAe,CACpD,MAAM1oF,EAAOjd,KAAKsxE,aAAatxE,KAAK2lG,eAC9B3mF,EAAShf,KAAKwlG,QAAQvoF,EAAM20D,GAClC,GAAI5yD,EAAQ,CAwBV,MAAMonF,EAAsCx3E,IACtC5uB,KAAKm3B,OAAOC,aAGZ/I,YAAYC,MAAQq1B,GAAS,GAC/B3jD,KAAKkmG,oBAAoB,EAAGt3E,GAE5B5uB,KAAKimG,YAAYtiD,EAAW/0B,KA6BhC,YAJA5P,EAAOqnF,MAAM7nB,IACXrlB,eAAe,KAAO,MAAMqlB,IACrBlU,QAAQC,SAAQ,KACtBgU,KAAK6nB,EAEV,CAEA,MAAMp2E,EAAKhwB,KAAKylG,WAAWzlG,KAAK2lG,eAKhC,GAJI31E,GAAIA,IACRhwB,KAAK2lG,gBACL3lG,KAAK0lG,cAAgBzoF,EAAK1b,OAEtB8sB,YAAYC,MAAQq1B,GAAS,GAC/B,KAEJ,CACI3jD,KAAKsxE,aAAa/vE,OAASvB,KAAK2lG,eAG9B3lG,KAAK2lG,cAAa,KACpB3lG,KAAKsxE,aAAetxE,KAAKsxE,aAAa/pE,MAAMvH,KAAK2lG,eACjD3lG,KAAKylG,WAAazlG,KAAKylG,WAAWl+F,MAAMvH,KAAK2lG,eAC7C3lG,KAAK2lG,cAAgB,GAEvB3lG,KAAKkmG,wBAELlmG,KAAKsxE,aAAa/vE,OAAS,EAC3BvB,KAAKylG,WAAWlkG,OAAS,EACzBvB,KAAK0lG,aAAe,EACpB1lG,KAAK2lG,cAAgB,GAEvB3lG,KAAKqwE,eAAep/D,MACtB,2FCpSF,SAA2BgM,GACzB,IAAKA,EAAM,OAEX,IAAIqpF,EAAMrpF,EAAKo7E,cACf,GAAIiO,EAAIlpE,WAAW,QAAS,CAE1BkpE,EAAMA,EAAI/+F,MAAM,GAChB,MAAMq7B,EAAI2jE,EAAQrgB,KAAKogB,GACvB,GAAI1jE,EAAG,CACL,MAAM4jE,EAAO5jE,EAAE,GAAK,GAAKA,EAAE,GAAK,IAAMA,EAAE,GAAK,KAAO,MACpD,MAAO,CACLjuB,KAAK6d,MAAM3qB,SAAS+6B,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAK,IAAM4jE,EAAO,KAChE7xF,KAAK6d,MAAM3qB,SAAS+6B,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAK,IAAM4jE,EAAO,KAChE7xF,KAAK6d,MAAM3qB,SAAS+6B,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAMA,EAAE,IAAK,IAAM4jE,EAAO,KAEpE,CACF,MAAO,GAAIF,EAAIlpE,WAAW,OAExBkpE,EAAMA,EAAI/+F,MAAM,GACZk/F,EAASvgB,KAAKogB,IAAQ,CAAC,EAAG,EAAG,EAAG,IAAI76E,SAAS66E,EAAI/kG,SAAS,CAC5D,MAAMmlG,EAAMJ,EAAI/kG,OAAS,EACnByd,EAAmC,CAAC,EAAG,EAAG,GAChD,IAAK,IAAIlgB,EAAI,EAAGA,EAAI,IAAKA,EAAG,CAC1B,MAAMkwB,EAAInnB,SAASy+F,EAAI/+F,MAAMm/F,EAAM5nG,EAAG4nG,EAAM5nG,EAAI4nG,GAAM,IACtD1nF,EAAOlgB,GAAa,IAAR4nG,EAAY13E,GAAK,EAAY,IAAR03E,EAAY13E,EAAY,IAAR03E,EAAY13E,GAAK,EAAIA,GAAK,CAC7E,CACA,OAAOhQ,CACT,CAMJ,gBAqBA,SAA4BzM,EAAiCo0F,EAAe,IAC1E,MAAO/3E,EAAGC,EAAGtK,GAAKhS,EAClB,MAAO,OAAOq0F,EAAIh4E,EAAG+3E,MAASC,EAAI/3E,EAAG83E,MAASC,EAAIriF,EAAGoiF,IACvD,EAxEA,MAAMJ,EAAU,qKAEVE,EAAW,aAiDjB,SAASG,EAAIn4C,EAAWk4C,GACtB,MAAM/5B,EAAIne,EAAEnqD,SAAS,IACfuiG,EAAKj6B,EAAErrE,OAAS,EAAI,IAAMqrE,EAAIA,EACpC,OAAQ+5B,GACN,KAAK,EACH,OAAO/5B,EAAE,GACX,KAAK,EACH,OAAOi6B,EACT,KAAK,GACH,OAAQA,EAAKA,GAAIt/F,MAAM,EAAG,GAC5B,QACE,OAAOs/F,EAAKA,EAElB,gGChEA,MAAAlzB,EAAAz0E,EAAA,KAEA8yF,EAAA9yF,EAAA,MAEM4nG,EAAgC,eAUtC,iBAAApnG,GACUM,KAAA+mG,UAA6Cn+F,OAAOo+F,OAAO,MAC3DhnG,KAAAinG,QAAUH,EACV9mG,KAAAknG,OAAiB,EACjBlnG,KAAAmnG,WAAqC,OACrCnnG,KAAAonG,OAA+B,CACrChwB,QAAQ,EACRiwB,aAAc,EACdC,aAAa,EAsHjB,CA9GS,eAAAC,CAAgBn1F,EAAeqL,GACpCzd,KAAK+mG,UAAU30F,KAAW,GAC1B,MAAMo1F,EAAcxnG,KAAK+mG,UAAU30F,GAEnC,OADAo1F,EAAYvjG,KAAKwZ,GACV,CACLpE,QAAS,KACP,MAAMouF,EAAeD,EAAYrsC,QAAQ19C,IACnB,IAAlBgqF,GACFD,EAAY1/E,OAAO2/E,EAAc,IAIzC,CAEO,YAAAC,CAAat1F,GACdpS,KAAK+mG,UAAU30F,WAAepS,KAAK+mG,UAAU30F,EACnD,CAEO,kBAAAu1F,CAAmBlqF,GACxBzd,KAAKmnG,WAAa1pF,CACpB,CAEO,OAAApE,GACLrZ,KAAK+mG,UAAYn+F,OAAOo+F,OAAO,MAC/BhnG,KAAKmnG,WAAa,OAClBnnG,KAAKinG,QAAUH,CACjB,CAEO,KAAAx1F,GAEL,GAAItR,KAAKinG,QAAQ1lG,OACf,IAAK,IAAIymB,EAAIhoB,KAAKonG,OAAOhwB,OAASp3E,KAAKonG,OAAOC,aAAe,EAAIrnG,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,IAAKA,EAClGhoB,KAAKinG,QAAQj/E,GAAG1lB,KAAI,GAGxBtC,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKinG,QAAUH,EACf9mG,KAAKknG,OAAS,CAChB,CAEO,KAAA7kG,CAAM+P,GAKX,GAHApS,KAAKsR,QACLtR,KAAKknG,OAAS90F,EACdpS,KAAKinG,QAAUjnG,KAAK+mG,UAAU30F,IAAU00F,EACnC9mG,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAG3lB,aAHlBrC,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,QAMjC,CAEO,GAAAU,CAAI3qF,EAAmB5a,EAAeC,GAC3C,GAAKtC,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAG4/E,IAAI3qF,EAAM5a,EAAOC,QAHnCtC,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,OAAO,EAAAvzB,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,GAMnE,CAOO,GAAAA,CAAIwlG,EAAkBl2B,GAAyB,GACpD,GAAK5xE,KAAKinG,QAAQ1lG,OAEX,CACL,IAAIwmG,GAA4C,EAC5C//E,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAC1B+lG,GAAc,EAOlB,GANItnG,KAAKonG,OAAOhwB,SACdpvD,EAAIhoB,KAAKonG,OAAOC,aAAe,EAC/BU,EAAgBn2B,EAChB01B,EAActnG,KAAKonG,OAAOE,YAC1BtnG,KAAKonG,OAAOhwB,QAAS,IAElBkwB,IAAiC,IAAlBS,EAAyB,CAC3C,KAAO//E,GAAK,IACV+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAG1lB,IAAIwlG,IACd,IAAlBC,GAFS//E,IAIN,GAAI+/E,aAAyBz9B,QAIlC,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,EAGX//E,GACF,CAEA,KAAOA,GAAK,EAAGA,IAEb,GADA+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAG1lB,KAAI,GAChCylG,aAAyBz9B,QAI3B,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,CAGb,MAnCE/nG,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,MAAOY,GAoCtC9nG,KAAKinG,QAAUH,EACf9mG,KAAKknG,OAAS,CAChB,GAOF,MAAApmB,EAME,WAAAphF,CAAoBwjB,GAAAljB,KAAAkjB,SAAAA,EAHZljB,KAAA0nF,MAAQ,IAAIsK,EAAAgW,qBAAqBlnB,EAAWmnB,eAC5CjoG,KAAAkoG,WAAqB,CAEiD,CAEvE,KAAA7lG,GACLrC,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,CACnB,CAEO,GAAAN,CAAI3qF,EAAmB5a,EAAeC,GACvCtC,KAAKkoG,WAGLloG,KAAK0nF,MAAMqC,QAAO,EAAApW,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,MAC/CtC,KAAKkoG,WAAY,EAErB,CAEO,GAAA5lG,CAAIwlG,GACT,IAAIK,GAAkC,EACtC,GAAInoG,KAAKkoG,UACPC,GAAM,OACD,GAAIL,IACTK,EAAMnoG,KAAKkjB,SAASljB,KAAK0nF,MAAMpjF,YAC3B6jG,aAAe79B,SAGjB,OAAO69B,EAAI5pB,KAAK6pB,IACdpoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVE,IAMb,OAFApoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVC,CACT,iBAxCernB,EAAAmnB,cAAa,kGCnJ9B,MAAAt0B,EAAAz0E,EAAA,KACAmpG,EAAAnpG,EAAA,MAEA8yF,EAAA9yF,EAAA,MAEM4nG,EAAgC,eAEtC,iBAAApnG,GACUM,KAAA+mG,UAA6Cn+F,OAAOo+F,OAAO,MAC3DhnG,KAAAinG,QAAyBH,EACzB9mG,KAAAknG,OAAiB,EACjBlnG,KAAAmnG,WAAqC,OACrCnnG,KAAAonG,OAA+B,CACrChwB,QAAQ,EACRiwB,aAAc,EACdC,aAAa,EA4GjB,CAzGS,OAAAjuF,GACLrZ,KAAK+mG,UAAYn+F,OAAOo+F,OAAO,MAC/BhnG,KAAKmnG,WAAa,OAClBnnG,KAAKinG,QAAUH,CACjB,CAEO,eAAAS,CAAgBn1F,EAAeqL,GACpCzd,KAAK+mG,UAAU30F,KAAW,GAC1B,MAAMo1F,EAAcxnG,KAAK+mG,UAAU30F,GAEnC,OADAo1F,EAAYvjG,KAAKwZ,GACV,CACLpE,QAAS,KACP,MAAMouF,EAAeD,EAAYrsC,QAAQ19C,IACnB,IAAlBgqF,GACFD,EAAY1/E,OAAO2/E,EAAc,IAIzC,CAEO,YAAAC,CAAat1F,GACdpS,KAAK+mG,UAAU30F,WAAepS,KAAK+mG,UAAU30F,EACnD,CAEO,kBAAAu1F,CAAmBlqF,GACxBzd,KAAKmnG,WAAa1pF,CACpB,CAEO,KAAAnM,GAEL,GAAItR,KAAKinG,QAAQ1lG,OACf,IAAK,IAAIymB,EAAIhoB,KAAKonG,OAAOhwB,OAASp3E,KAAKonG,OAAOC,aAAe,EAAIrnG,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,IAAKA,EAClGhoB,KAAKinG,QAAQj/E,GAAGsgF,QAAO,GAG3BtoG,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKinG,QAAUH,EACf9mG,KAAKknG,OAAS,CAChB,CAEO,IAAAqB,CAAKn2F,EAAeylE,GAKzB,GAHA73E,KAAKsR,QACLtR,KAAKknG,OAAS90F,EACdpS,KAAKinG,QAAUjnG,KAAK+mG,UAAU30F,IAAU00F,EACnC9mG,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAGugF,KAAK1wB,QAHvB73E,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,OAAQrvB,EAMzC,CAEO,GAAA+vB,CAAI3qF,EAAmB5a,EAAeC,GAC3C,GAAKtC,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAG4/E,IAAI3qF,EAAM5a,EAAOC,QAHnCtC,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,OAAO,EAAAvzB,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,GAMnE,CAEO,MAAAgmG,CAAOR,EAAkBl2B,GAAyB,GACvD,GAAK5xE,KAAKinG,QAAQ1lG,OAEX,CACL,IAAIwmG,GAA4C,EAC5C//E,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAC1B+lG,GAAc,EAOlB,GANItnG,KAAKonG,OAAOhwB,SACdpvD,EAAIhoB,KAAKonG,OAAOC,aAAe,EAC/BU,EAAgBn2B,EAChB01B,EAActnG,KAAKonG,OAAOE,YAC1BtnG,KAAKonG,OAAOhwB,QAAS,IAElBkwB,IAAiC,IAAlBS,EAAyB,CAC3C,KAAO//E,GAAK,IACV+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAGsgF,OAAOR,IACjB,IAAlBC,GAFS//E,IAIN,GAAI+/E,aAAyBz9B,QAIlC,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,EAGX//E,GACF,CAEA,KAAOA,GAAK,EAAGA,IAEb,GADA+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAGsgF,QAAO,GACnCP,aAAyBz9B,QAI3B,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,CAGb,MAnCE/nG,KAAKmnG,WAAWnnG,KAAKknG,OAAQ,SAAUY,GAoCzC9nG,KAAKinG,QAAUH,EACf9mG,KAAKknG,OAAS,CAChB,GAIF,MAAMsB,EAAe,IAAIH,EAAAI,OACzBD,EAAaE,SAAS,GAMtB,MAAA7qB,EAOE,WAAAn+E,CAAoBwjB,GAAAljB,KAAAkjB,SAAAA,EAJZljB,KAAA0nF,MAAQ,IAAIsK,EAAAgW,qBAAqBnqB,EAAWoqB,eAC5CjoG,KAAA2oG,QAAmBH,EACnBxoG,KAAAkoG,WAAqB,CAEkE,CAExF,IAAAK,CAAK1wB,GAKV73E,KAAK2oG,QAAW9wB,EAAOt2E,OAAS,GAAKs2E,EAAOA,OAAO,GAAMA,EAAOt+B,QAAUivD,EAC1ExoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,CACnB,CAEO,GAAAN,CAAI3qF,EAAmB5a,EAAeC,GACvCtC,KAAKkoG,WAGLloG,KAAK0nF,MAAMqC,QAAO,EAAApW,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,MAC/CtC,KAAKkoG,WAAY,EAErB,CAEO,MAAAI,CAAOR,GACZ,IAAIK,GAAkC,EACtC,GAAInoG,KAAKkoG,UACPC,GAAM,OACD,GAAIL,IACTK,EAAMnoG,KAAKkjB,SAASljB,KAAK0nF,MAAMpjF,WAAYtE,KAAK2oG,SAC5CR,aAAe79B,SAGjB,OAAO69B,EAAI5pB,KAAK6pB,IACdpoG,KAAK2oG,QAAUH,EACfxoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVE,IAOb,OAHApoG,KAAK2oG,QAAUH,EACfxoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVC,CACT,iBAhDetqB,EAAAoqB,cAAa,2ICtI9B,MAAA7oG,EAAAF,EAAA,MAEAmpG,EAAAnpG,EAAA,MACA00E,EAAA10E,EAAA,MACA20E,EAAA30E,EAAA,MACA40E,EAAA50E,EAAA,MAkCA,MAAA0pG,EAGE,WAAAlpG,CAAY6B,GACVvB,KAAKmgG,MAAQ,IAAI0I,YAAYtnG,EAC/B,CAOO,UAAAunG,CAAWjsC,EAAsB16C,GACtCniB,KAAKmgG,MAAMr2D,KAAK+yB,GAAM,EAA0C16C,EAClE,CASO,GAAAxhB,CAAIq6B,EAAcjZ,EAAoB86C,EAAsB16C,GACjEniB,KAAKmgG,MAAMp+E,GAAK,EAAoCiZ,GAAQ6hC,GAAM,EAA0C16C,CAC9G,CASO,OAAA4mF,CAAQC,EAAiBjnF,EAAoB86C,EAAsB16C,GACxE,IAAK,IAAIrjB,EAAI,EAAGA,EAAIkqG,EAAMznG,OAAQzC,IAChCkB,KAAKmgG,MAAMp+E,GAAK,EAAoCinF,EAAMlqG,IAAM+9D,GAAM,EAA0C16C,CAEpH,sBAKF,MAAM8mF,EAAsB,IAOfxqG,EAAAyqG,uBAAyB,WAGpC,MAAM/I,EAAyB,IAAIyI,EAAgB,MAI7CO,EAAY59B,MAAMnX,MAAM,KAAMmX,MADhB,MACoCpkD,IAAI,CAACiiF,EAAatqG,IAAcA,GAClF8vB,EAAI,CAACvsB,EAAeC,IAA0B6mG,EAAU5hG,MAAMlF,EAAOC,GAGrE+mG,EAAaz6E,EAAE,GAAM,KACrB06E,EAAc16E,EAAE,EAAM,IAC5B06E,EAAYrlG,KAAK,IACjBqlG,EAAYrlG,KAAKmwD,MAAMk1C,EAAa16E,EAAE,GAAM,KAE5C,MAAM26E,EAAmB36E,EAAC,MAG1BuxE,EAAM2I,WAAU,KAEhB3I,EAAM4I,QAAQM,EAAU,OAExB,IAAK,MAAMtnF,KAASwnF,EAClBpJ,EAAM4I,QAAQ,CAAC,GAAM,GAAM,IAAM,KAAOhnF,EAAK,KAC7Co+E,EAAM4I,QAAQn6E,EAAE,IAAM,KAAO7M,EAAK,KAClCo+E,EAAM4I,QAAQn6E,EAAE,IAAM,KAAO7M,EAAK,KAClCo+E,EAAMx/F,IAAI,IAAMohB,EAAK,KACrBo+E,EAAMx/F,IAAI,GAAMohB,EAAK,MACrBo+E,EAAMx/F,IAAI,IAAMohB,EAAK,KACrBo+E,EAAM4I,QAAQ,CAAC,IAAM,KAAOhnF,EAAK,KACjCo+E,EAAMx/F,IAAI,IAAMohB,EAAK,OACrBo+E,EAAMx/F,IAAI,IAAMohB,EAAK,MACrBo+E,EAAMx/F,IAAI,IAAMohB,EAAK,MAmGvB,OAhGAo+E,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OAEdw/F,EAAMx/F,IAAI,GAAI,OACdw/F,EAAM4I,QAAQM,EAAU,OACxBlJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQ,CAAC,IAAM,GAAM,GAAM,GAAM,GAAK,OAC5C5I,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAE3BuxE,EAAM4I,QAAQ,CAAC,GAAM,IAAK,OAC1B5I,EAAM4I,QAAQM,EAAU,OACxBlJ,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAMx/F,IAAI,IAAI,OAEdw/F,EAAMx/F,IAAI,GAAI,SACdw/F,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,UAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,UAC3BuxE,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQM,EAAU,UACxBlJ,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAM4I,QAAQn6E,EAAE,EAAM,IAAK,UAC3BuxE,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQ,CAAC,GAAM,IAAM,GAAM,IAAK,SAEtC5I,EAAMx/F,IAAI,GAAI,QACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQ,CAAC,GAAM,GAAM,GAAM,IAAK,OACtC5I,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,OAC3BuxE,EAAM4I,QAAQ,CAAC,GAAM,GAAM,GAAM,IAAK,OACtC5I,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAE3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,OAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,QAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,QAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,QAC3BuxE,EAAM4I,QAAQ,CAAC,GAAM,GAAM,IAAK,QAChC5I,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,QAE3BuxE,EAAMx/F,IAAI,GAAI,QACdw/F,EAAM4I,QAAQO,EAAW,OACzBnJ,EAAMx/F,IAAI,IAAI,OACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,QAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,QAC3BuxE,EAAM4I,QAAQ,CAAC,GAAM,GAAM,GAAM,IAAK,QACtC5I,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,SAC3BuxE,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAM4I,QAAQ,CAAC,GAAM,GAAM,GAAM,IAAK,SACtC5I,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAM4I,QAAQO,EAAW,SACzBnJ,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,IAAK,SAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,UAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,UAC3BuxE,EAAM4I,QAAQn6E,EAAE,GAAM,KAAK,SAC3BuxE,EAAM4I,QAAQO,EAAW,UACzBnJ,EAAM4I,QAAQM,EAAU,UACxBlJ,EAAMx/F,IAAI,IAAI,SACdw/F,EAAM4I,QAAQ,CAAC,GAAM,IAAM,GAAM,IAAK,SAEtC5I,EAAMx/F,IAAIsoG,EAAmB,OAC7B9I,EAAMx/F,IAAIsoG,EAAmB,OAC7B9I,EAAMx/F,IAAIsoG,EAAmB,OAC7B9I,EAAMx/F,IAAIsoG,EAAmB,SAC7B9I,EAAMx/F,IAAIsoG,EAAmB,UAC7B9I,EAAMx/F,IAAIsoG,EAAmB,UACtB9I,CACR,CArIqC,GAsKtC,MAAAvqB,UAA0Cx2E,EAAAK,WAqCxC,WAAAC,CACqB8pG,EAAgC/qG,EAAAyqG,wBAEnDnpG,QAFmBC,KAAAwpG,aAAAA,EATXxpG,KAAAm3E,YAAiC,CACzCp1D,MAAK,EACL0nF,SAAU,GACVC,WAAY,EACZC,WAAY,EACZC,SAAU,GAQV5pG,KAAK6pG,aAAY,EACjB7pG,KAAK8pG,aAAe9pG,KAAK6pG,aACzB7pG,KAAK2oG,QAAU,IAAIN,EAAAI,OACnBzoG,KAAK2oG,QAAQD,SAAS,GACtB1oG,KAAK+pG,SAAW,EAChB/pG,KAAK2/E,mBAAqB,EAG1B3/E,KAAKgqG,gBAAkB,CAAC/sF,EAAM5a,EAAOC,OACrCtC,KAAKiqG,kBAAqBjvE,MAC1Bh7B,KAAKkqG,cAAgB,CAAC93F,EAAeylE,OACrC73E,KAAKmqG,cAAiB/3F,MACtBpS,KAAKoqG,gBAAmBroF,GAAwCA,EAChE/hB,KAAKqqG,cAAgBrqG,KAAKgqG,gBAC1BhqG,KAAKsqG,iBAAmB1hG,OAAOo+F,OAAO,MACtChnG,KAAKuqG,oBAAsB,IAAIh/B,MAAM,IAAMzhC,UAAKllC,GAChD5E,KAAKwqG,aAAe5hG,OAAOo+F,OAAO,MAClChnG,KAAKyqG,aAAe7hG,OAAOo+F,OAAO,MAClChnG,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKwqG,aAAe5hG,OAAOo+F,OAAO,MAClChnG,KAAKsqG,iBAAmB1hG,OAAOo+F,OAAO,MACtChnG,KAAKuqG,oBAAsB,IAAIh/B,MAAM,IAAMzhC,UAAKllC,GAChD5E,KAAKyqG,aAAe7hG,OAAOo+F,OAAO,SAEpChnG,KAAK0qG,WAAa1qG,KAAK0B,UAAU,IAAIkyE,EAAA+2B,WACrC3qG,KAAK4qG,WAAa5qG,KAAK0B,UAAU,IAAImyE,EAAAg3B,WACrC7qG,KAAK8qG,WAAa9qG,KAAK0B,UAAU,IAAIoyE,EAAAi3B,WACrC/qG,KAAKgrG,cAAgBhrG,KAAKoqG,gBAG1BpqG,KAAKqyE,mBAAmB,CAAEW,MAAO,MAAQ,KAAM,EACjD,CAEU,WAAAi4B,CAAY9wE,EAAyB+wE,EAAuB,CAAC,GAAM,MAC3E,IAAI9C,EAAM,EACV,GAAIjuE,EAAGk/C,OAAQ,CACb,GAAIl/C,EAAGk/C,OAAO93E,OAAS,EACrB,MAAM,IAAIQ,MAAM,qCAGlB,GADAqmG,EAAMjuE,EAAGk/C,OAAO55D,WAAW,GACvB2oF,EAAM,IAAQA,EAAM,GACtB,MAAM,IAAIrmG,MAAM,uCAEpB,CACA,GAAIo4B,EAAGs+C,cAAe,CACpB,GAAIt+C,EAAGs+C,cAAcl3E,OAAS,EAC5B,MAAM,IAAIQ,MAAM,iDAElB,IAAK,IAAIjD,EAAI,EAAGA,EAAIq7B,EAAGs+C,cAAcl3E,SAAUzC,EAAG,CAChD,MAAMqsG,EAAehxE,EAAGs+C,cAAch5D,WAAW3gB,GACjD,GAAI,GAAOqsG,GAAgBA,EAAe,GACxC,MAAM,IAAIppG,MAAM,8CAElBqmG,IAAQ,EACRA,GAAO+C,CACT,CACF,CACA,GAAwB,IAApBhxE,EAAG64C,MAAMzxE,OACX,MAAM,IAAIQ,MAAM,+BAElB,MAAMqpG,EAAYjxE,EAAG64C,MAAMvzD,WAAW,GACtC,GAAIyrF,EAAW,GAAKE,GAAaA,EAAYF,EAAW,GACtD,MAAM,IAAInpG,MAAM,0BAA0BmpG,EAAW,SAASA,EAAW,MAK3E,OAHA9C,IAAQ,EACRA,GAAOgD,EAEAhD,CACT,CAEO,aAAAtwB,CAAc1lE,GACnB,MAAMg2F,EAAgB,GACtB,KAAOh2F,GACLg2F,EAAInkG,KAAKmc,OAAOC,aAAqB,IAARjO,IAC7BA,IAAU,EAEZ,OAAOg2F,EAAIiD,UAAU75E,KAAK,GAC5B,CAEO,eAAA8mD,CAAgB76D,GACrBzd,KAAKqqG,cAAgB5sF,CACvB,CACO,iBAAA6tF,GACLtrG,KAAKqqG,cAAgBrqG,KAAKgqG,eAC5B,CAEO,kBAAA33B,CAAmBl4C,EAAyB1c,GACjD,MAAMrL,EAAQpS,KAAKirG,YAAY9wE,EAAI,CAAC,GAAM,MAC1Cn6B,KAAKyqG,aAAar4F,KAAW,GAC7B,MAAMo1F,EAAcxnG,KAAKyqG,aAAar4F,GAEtC,OADAo1F,EAAYvjG,KAAKwZ,GACV,CACLpE,QAAS,KACP,MAAMouF,EAAeD,EAAYrsC,QAAQ19C,IACnB,IAAlBgqF,GACFD,EAAY1/E,OAAO2/E,EAAc,IAIzC,CACO,eAAA8D,CAAgBpxE,GACjBn6B,KAAKyqG,aAAazqG,KAAKirG,YAAY9wE,EAAI,CAAC,GAAM,eAAgBn6B,KAAKyqG,aAAazqG,KAAKirG,YAAY9wE,EAAI,CAAC,GAAM,MAClH,CACO,qBAAA69C,CAAsBv6D,GAC3Bzd,KAAKmqG,cAAgB1sF,CACvB,CAEO,iBAAAo+D,CAAkB2B,EAAc//D,GACrC,MAAMud,EAAOwiD,EAAK/9D,WAAW,GAC7Bzf,KAAKsqG,iBAAiBtvE,GAAQvd,EAC1Bud,EAAO,KAAMh7B,KAAKuqG,oBAAoBvvE,GAAQvd,EACpD,CACO,mBAAA+tF,CAAoBhuB,GACzB,MAAMxiD,EAAOwiD,EAAK/9D,WAAW,GACzBzf,KAAKsqG,iBAAiBtvE,WAAch7B,KAAKsqG,iBAAiBtvE,GAC1DA,EAAO,KAAMh7B,KAAKuqG,oBAAoBvvE,QAAQp2B,EACpD,CACO,yBAAAqzE,CAA0Bx6D,GAC/Bzd,KAAKiqG,kBAAoBxsF,CAC3B,CAEO,kBAAA80D,CAAmBp4C,EAAyB1c,GACjD,MAAMrL,EAAQpS,KAAKirG,YAAY9wE,GAC/Bn6B,KAAKwqG,aAAap4F,KAAW,GAC7B,MAAMo1F,EAAcxnG,KAAKwqG,aAAap4F,GAEtC,OADAo1F,EAAYvjG,KAAKwZ,GACV,CACLpE,QAAS,KACP,MAAMouF,EAAeD,EAAYrsC,QAAQ19C,IACnB,IAAlBgqF,GACFD,EAAY1/E,OAAO2/E,EAAc,IAIzC,CACO,eAAAgE,CAAgBtxE,GACjBn6B,KAAKwqG,aAAaxqG,KAAKirG,YAAY9wE,YAAan6B,KAAKwqG,aAAaxqG,KAAKirG,YAAY9wE,GACzF,CACO,qBAAAy9C,CAAsBttD,GAC3BtqB,KAAKkqG,cAAgB5/E,CACvB,CAEO,kBAAAgoD,CAAmBn4C,EAAyB1c,GACjD,OAAOzd,KAAK4qG,WAAWrD,gBAAgBvnG,KAAKirG,YAAY9wE,GAAK1c,EAC/D,CACO,eAAAiuF,CAAgBvxE,GACrBn6B,KAAK4qG,WAAWlD,aAAa1nG,KAAKirG,YAAY9wE,GAChD,CACO,qBAAAg+C,CAAsB16D,GAC3Bzd,KAAK4qG,WAAWjD,mBAAmBlqF,EACrC,CAEO,kBAAA+0D,CAAmBpgE,EAAeqL,GACvC,OAAOzd,KAAK0qG,WAAWnD,gBAAgBn1F,EAAOqL,EAChD,CACO,eAAAkuF,CAAgBv5F,GACrBpS,KAAK0qG,WAAWhD,aAAat1F,EAC/B,CACO,qBAAA8lE,CAAsBz6D,GAC3Bzd,KAAK0qG,WAAW/C,mBAAmBlqF,EACrC,CAEO,kBAAAg1D,CAAmBt4C,EAAyB1c,GAEjD,OADA0c,EAAGk/C,YAASz0E,EACL5E,KAAK8qG,WAAWvD,gBAAgBvnG,KAAKirG,YAAY9wE,EAAI,CAAC,GAAM,MAAQ1c,EAC7E,CACO,eAAAmuF,CAAgBzxE,GACrBA,EAAGk/C,YAASz0E,EACZ5E,KAAK8qG,WAAWpD,aAAa1nG,KAAKirG,YAAY9wE,EAAI,CAAC,GAAM,MAC3D,CACO,qBAAAk+C,CAAsB56D,GAC3Bzd,KAAK8qG,WAAWnD,mBAAmBlqF,EACrC,CAEO,eAAAmgE,CAAgBtzD,GACrBtqB,KAAKgrG,cAAgB1gF,CACvB,CACO,iBAAAuhF,GACL7rG,KAAKgrG,cAAgBhrG,KAAKoqG,eAC5B,CAWO,KAAA94F,GACLtR,KAAK8pG,aAAe9pG,KAAK6pG,aACzB7pG,KAAK0qG,WAAWp5F,QAChBtR,KAAK4qG,WAAWt5F,QAChBtR,KAAK8qG,WAAWx5F,QAChBtR,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB/pG,KAAK2/E,mBAAqB,EAIA,IAAtB3/E,KAAKm3E,YAAYp1D,QACnB/hB,KAAKm3E,YAAYp1D,MAAK,EACtB/hB,KAAKm3E,YAAYsyB,SAAW,GAEhC,CAKU,cAAA1rB,CACRh8D,EACA0nF,EACAC,EACAC,EACAC,GAEA5pG,KAAKm3E,YAAYp1D,MAAQA,EACzB/hB,KAAKm3E,YAAYsyB,SAAWA,EAC5BzpG,KAAKm3E,YAAYuyB,WAAaA,EAC9B1pG,KAAKm3E,YAAYwyB,WAAaA,EAC9B3pG,KAAKm3E,YAAYyyB,SAAWA,CAC9B,CA+CO,KAAA/3B,CAAM50D,EAAmB1b,EAAgBqwE,GAC9C,IAAI52C,EACA2uE,EAEA5B,EADA1lG,EAAQ,EAIZ,GAAIrC,KAAKm3E,YAAYp1D,MAGnB,GAA0B,IAAtB/hB,KAAKm3E,YAAYp1D,MACnB/hB,KAAKm3E,YAAYp1D,MAAK,EACtB1f,EAAQrC,KAAKm3E,YAAYyyB,SAAW,MAC/B,CACL,QAAsBhlG,IAAlBgtE,GAAqD,IAAtB5xE,KAAKm3E,YAAYp1D,MAiBlD,MADA/hB,KAAKm3E,YAAYp1D,MAAK,EAChB,IAAIhgB,MAAM,0EAMlB,MAAM0nG,EAAWzpG,KAAKm3E,YAAYsyB,SAClC,IAAIC,EAAa1pG,KAAKm3E,YAAYuyB,WAAa,EAC/C,OAAQ1pG,KAAKm3E,YAAYp1D,OACvB,OACE,IAAsB,IAAlB6vD,GAA2B83B,GAAc,EAC3C,KAAOA,GAAc,IACnB3B,EAAiB0B,EAA8BC,GAAY1pG,KAAK2oG,UAC1C,IAAlBZ,GAFkB2B,IAIf,GAAI3B,aAAyBz9B,QAElC,OADAtqE,KAAKm3E,YAAYuyB,WAAaA,EACvB3B,EAIb/nG,KAAKm3E,YAAYsyB,SAAW,GAC5B,MACF,OACE,IAAsB,IAAlB73B,GAA2B83B,GAAc,EAC3C,KAAOA,GAAc,IACnB3B,EAAiB0B,EAA8BC,MACzB,IAAlB3B,GAFkB2B,IAIf,GAAI3B,aAAyBz9B,QAElC,OADAtqE,KAAKm3E,YAAYuyB,WAAaA,EACvB3B,EAIb/nG,KAAKm3E,YAAYsyB,SAAW,GAC5B,MACF,OAGE,GAFAzuE,EAAO/d,EAAKjd,KAAKm3E,YAAYyyB,UAC7B7B,EAAgB/nG,KAAK4qG,WAAWtC,OAAgB,KAATttE,GAA0B,KAATA,EAAe42C,GACnEm2B,EACF,OAAOA,EAEI,KAAT/sE,IAAeh7B,KAAKm3E,YAAYwyB,YAAU,GAC9C3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB,MACF,OAGE,GAFA/uE,EAAO/d,EAAKjd,KAAKm3E,YAAYyyB,UAC7B7B,EAAgB/nG,KAAK0qG,WAAWpoG,IAAa,KAAT04B,GAA0B,KAATA,EAAe42C,GAChEm2B,EACF,OAAOA,EAEI,KAAT/sE,IAAeh7B,KAAKm3E,YAAYwyB,YAAU,GAC9C3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB,MACF,OAGE,GAFA/uE,EAAO/d,EAAKjd,KAAKm3E,YAAYyyB,UAC7B7B,EAAgB/nG,KAAK8qG,WAAWxoG,IAAa,KAAT04B,GAA0B,KAATA,EAAe42C,GAChEm2B,EACF,OAAOA,EAEI,KAAT/sE,IAAeh7B,KAAKm3E,YAAYwyB,YAAU,GAC9C3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAIpB/pG,KAAKm3E,YAAYp1D,MAAK,EACtB1f,EAAQrC,KAAKm3E,YAAYyyB,SAAW,EACpC5pG,KAAK2/E,mBAAqB,EAC1B3/E,KAAK8pG,aAA0C,IAA3B9pG,KAAKm3E,YAAYwyB,UACvC,CAMF,IAAK,IAAI7qG,EAAIuD,EAAOvD,EAAIyC,IAAUzC,EAIhC,GAHAk8B,EAAO/d,EAAKne,GAGRk8B,EAAO,IAAQh7B,KAAK8pG,cAAY,GACjC9pG,KAAKuqG,oBAAoBvvE,IAASh7B,KAAKiqG,mBAAmBjvE,GAC3Dh7B,KAAK2/E,mBAAqB,MAF5B,CAOA,GAAa,KAAT3kD,GACCh7B,KAAK8pG,aAAY,GACjBhrG,EAAI,EAAIyC,GAA0B,KAAhB0b,EAAKne,EAAI,GAC9B,CACAkB,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB,IAAI9S,EAAIn4F,EAAI,EACR8gF,EAAK3iE,EAAKg6E,GACVrX,GAAM,IAAQA,GAAM,KACtB5/E,KAAK+pG,SAAWnqB,EAChBqX,KAEF,IAAI8U,GAAU,EACd,KAAO9U,EAAI11F,EAAQ01F,IAEjB,GADArX,EAAK3iE,EAAKg6E,GACNrX,GAAM,IAAQA,GAAM,GACtB5/E,KAAK2oG,QAAQqD,SAASpsB,EAAK,SACtB,GAAW,KAAPA,EACT5/E,KAAK2oG,QAAQD,SAAS,OACjB,IAAW,KAAP9oB,EAEJ,IAAIA,GAAM,IAAQA,GAAM,IAAM,CACnC,MAAM6pB,EAAWzpG,KAAKwqG,aAAaxqG,KAAK+pG,UAAY,EAAInqB,GACxD,IAAI53D,EAAIyhF,EAAWA,EAASloG,OAAS,GAAK,EAC1C,KAAOymB,GAAK,IACV+/E,EAAgB0B,EAASzhF,GAAGhoB,KAAK2oG,UACX,IAAlBZ,GAFS//E,IAIN,GAAI+/E,aAAyBz9B,QAGlC,OAFAq/B,EAAa,KACb3pG,KAAK+9E,eAAc,EAAsB0rB,EAAUzhF,EAAG2hF,EAAY1S,GAC3D8Q,EAGP//E,EAAI,GACNhoB,KAAKkqG,cAAclqG,KAAK+pG,UAAY,EAAInqB,EAAI5/E,KAAK2oG,SAEnD3oG,KAAK2/E,mBAAqB,EAC1B7gF,EAAIm4F,EACJj3F,KAAK8pG,aAAY,EACjBiC,GAAU,EACV,KACF,CACE,KACF,CAxBE/rG,KAAK2oG,QAAQsD,aAAa,EAwB5B,CAEGF,IACHjtG,EAAIm4F,EAAI,EACRj3F,KAAK8pG,aAAY,GAEnB,QACF,CAOA,OAJAH,EAAa3pG,KAAKwpG,aAAarJ,MAC7BngG,KAAK8pG,cAAY,GAChB9uE,EAAOiuE,EAAsBjuE,EAAOiuE,IAE/BU,GAAU,GAChB,OAEE,IAAI36E,EAAIlwB,EACR,MAAMotG,EAAK3qG,EAAS,EACpB,KAAOytB,EAAIk9E,GACNjvF,IAAO+R,IAAM,KAAS/R,EAAK+R,IAAM,KAAQ/R,EAAK+R,IAAMi6E,IACpDhsF,IAAO+R,IAAM,KAAS/R,EAAK+R,IAAM,KAAQ/R,EAAK+R,IAAMi6E,IACpDhsF,IAAO+R,IAAM,KAAS/R,EAAK+R,IAAM,KAAQ/R,EAAK+R,IAAMi6E,IACpDhsF,IAAO+R,IAAM,KAAS/R,EAAK+R,IAAM,KAAQ/R,EAAK+R,IAAMi6E,KAEzD,GAAIj6E,GAAKk9E,EACP,KAAOl9E,EAAIztB,GAAU0b,EAAK+R,IAAM,KAAS/R,EAAK+R,IAAM,KAAQ/R,EAAK+R,IAAMi6E,IACrEj6E,IAGJhvB,KAAKqqG,cAAcptF,EAAMne,EAAGkwB,GAC5BlwB,EAAIkwB,EAAI,EACR,MACF,OACMhvB,KAAKsqG,iBAAiBtvE,GAAOh7B,KAAKsqG,iBAAiBtvE,KAClDh7B,KAAKiqG,kBAAkBjvE,GAC5Bh7B,KAAK2/E,mBAAqB,EAC1B,MACF,OACE,MACF,OAUE,GAT8B3/E,KAAKgrG,cACjC,CACE/lG,SAAUnG,EACVk8B,OACA8uE,aAAc9pG,KAAK8pG,aACnBqC,QAASnsG,KAAK+pG,SACdlyB,OAAQ73E,KAAK2oG,QACbyD,OAAO,IAEAA,MAAO,OAElB,MACF,OAEE,MAAM3C,EAAWzpG,KAAKwqG,aAAaxqG,KAAK+pG,UAAY,EAAI/uE,GACxD,IAAIhT,EAAIyhF,EAAWA,EAASloG,OAAS,GAAK,EAC1C,KAAOymB,GAAK,IAGV+/E,EAAgB0B,EAASzhF,GAAGhoB,KAAK2oG,UACX,IAAlBZ,GAJS//E,IAMN,GAAI+/E,aAAyBz9B,QAElC,OADAtqE,KAAK+9E,eAAc,EAAsB0rB,EAAUzhF,EAAG2hF,EAAY7qG,GAC3DipG,EAGP//E,EAAI,GACNhoB,KAAKkqG,cAAclqG,KAAK+pG,UAAY,EAAI/uE,EAAMh7B,KAAK2oG,SAErD3oG,KAAK2/E,mBAAqB,EAC1B,MACF,OAEE,GACE,OAAQ3kD,GACN,KAAK,GACHh7B,KAAK2oG,QAAQD,SAAS,GACtB,MACF,KAAK,GACH1oG,KAAK2oG,QAAQsD,aAAa,GAC1B,MACF,QACEjsG,KAAK2oG,QAAQqD,SAAShxE,EAAO,aAExBl8B,EAAIyC,IAAWy5B,EAAO/d,EAAKne,IAAM,IAAQk8B,EAAO,IAC3Dl8B,IACA,MACF,OACEkB,KAAK+pG,WAAa,EAClB/pG,KAAK+pG,UAAY/uE,EACjB,MACF,QACE,MAAMqxE,EAAcrsG,KAAKyqG,aAAazqG,KAAK+pG,UAAY,EAAI/uE,GAC3D,IAAIsxE,EAAKD,EAAcA,EAAY9qG,OAAS,GAAK,EACjD,KAAO+qG,GAAM,IAGXvE,EAAgBsE,EAAYC,MACN,IAAlBvE,GAJUuE,IAMP,GAAIvE,aAAyBz9B,QAElC,OADAtqE,KAAK+9E,eAAc,EAAsBsuB,EAAaC,EAAI3C,EAAY7qG,GAC/DipG,EAGPuE,EAAK,GACPtsG,KAAKmqG,cAAcnqG,KAAK+pG,UAAY,EAAI/uE,GAE1Ch7B,KAAK2/E,mBAAqB,EAC1B,MACF,QACE3/E,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB,MACF,QACE/pG,KAAK4qG,WAAWrC,KAAKvoG,KAAK+pG,UAAY,EAAI/uE,EAAMh7B,KAAK2oG,SACrD,MACF,QAGE,IAAK,IAAI3gF,EAAIlpB,EAAI,KAAOkpB,EACtB,GAAIA,GAAKzmB,GAA+B,MAApBy5B,EAAO/d,EAAK+K,KAAyB,KAATgT,GAA0B,KAATA,GAAkBA,EAAO,KAAQA,EAAOiuE,EAAsB,CAC7HjpG,KAAK4qG,WAAWhD,IAAI3qF,EAAMne,EAAGkpB,GAC7BlpB,EAAIkpB,EAAI,EACR,KACF,CAEF,MACF,QAEE,GADA+/E,EAAgB/nG,KAAK4qG,WAAWtC,OAAgB,KAATttE,GAA0B,KAATA,GACpD+sE,EAEF,OADA/nG,KAAK+9E,eAAc,EAAsB,GAAI,EAAG4rB,EAAY7qG,GACrDipG,EAEI,KAAT/sE,IAAe2uE,GAAU,GAC7B3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB/pG,KAAK2/E,mBAAqB,EAC1B,MACF,OACE3/E,KAAK0qG,WAAWroG,QAChB,MACF,OAEE,IAAK,IAAI2lB,EAAIlpB,EAAI,GAAKkpB,IACpB,GAAIA,GAAKzmB,IAAWy5B,EAAO/d,EAAK+K,IAAM,IAASgT,EAAO,KAAQA,EAAOiuE,EAAsB,CACzFjpG,KAAK0qG,WAAW9C,IAAI3qF,EAAMne,EAAGkpB,GAC7BlpB,EAAIkpB,EAAI,EACR,KACF,CAEF,MACF,OAEE,GADA+/E,EAAgB/nG,KAAK0qG,WAAWpoG,IAAa,KAAT04B,GAA0B,KAATA,GACjD+sE,EAEF,OADA/nG,KAAK+9E,eAAc,EAAsB,GAAI,EAAG4rB,EAAY7qG,GACrDipG,EAEI,KAAT/sE,IAAe2uE,GAAU,GAC7B3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB/pG,KAAK2/E,mBAAqB,EAC1B,MACF,QACE3/E,KAAK8qG,WAAWzoG,MAAMrC,KAAK+pG,UAAY,EAAI/uE,GAC3C,MACF,QAGE,IAAK,IAAIhT,EAAIlpB,EAAI,KAAOkpB,EACtB,KAAIA,EAAIzmB,IACL0b,EAAK+K,IAAM,IAAQ/K,EAAK+K,GAAK,KAAU/K,EAAK+K,IAAM,GAAQ/K,EAAK+K,GAAK,IAAS/K,EAAK+K,IAAMihF,IAD3F,CAGAjpG,KAAK8qG,WAAWlD,IAAI3qF,EAAMne,EAAGkpB,GAC7BlpB,EAAIkpB,EAAI,EACR,KAHG,CAKL,MACF,QAEE,GADA+/E,EAAgB/nG,KAAK8qG,WAAWxoG,IAAa,KAAT04B,GAA0B,KAATA,GACjD+sE,EAEF,OADA/nG,KAAK+9E,eAAc,EAAsB,GAAI,EAAG4rB,EAAY7qG,GACrDipG,EAEI,KAAT/sE,IAAe2uE,GAAU,GAC7B3pG,KAAK2oG,QAAQmD,WACb9rG,KAAK+pG,SAAW,EAChB/pG,KAAK2/E,mBAAqB,EAG9B3/E,KAAK8pG,aAAyB,IAAVH,CA/OpB,CAiPJ,yHC75BF,MAAAh2B,EAAAz0E,EAAA,KAEA8yF,EAAA9yF,EAAA,MAEM4nG,EAAgC,eAEtC,iBAAApnG,GACUM,KAAA6iD,OAAM,EACN7iD,KAAAinG,QAAUH,EACV9mG,KAAA62F,KAAO,EACP72F,KAAA+mG,UAA6Cn+F,OAAOo+F,OAAO,MAC3DhnG,KAAAmnG,WAAqC,OACrCnnG,KAAAonG,OAA+B,CACrChwB,QAAQ,EACRiwB,aAAc,EACdC,aAAa,EAsKjB,CAnKS,eAAAC,CAAgBn1F,EAAeqL,GACpCzd,KAAK+mG,UAAU30F,KAAW,GAC1B,MAAMo1F,EAAcxnG,KAAK+mG,UAAU30F,GAEnC,OADAo1F,EAAYvjG,KAAKwZ,GACV,CACLpE,QAAS,KACP,MAAMouF,EAAeD,EAAYrsC,QAAQ19C,IACnB,IAAlBgqF,GACFD,EAAY1/E,OAAO2/E,EAAc,IAIzC,CACO,YAAAC,CAAat1F,GACdpS,KAAK+mG,UAAU30F,WAAepS,KAAK+mG,UAAU30F,EACnD,CACO,kBAAAu1F,CAAmBlqF,GACxBzd,KAAKmnG,WAAa1pF,CACpB,CAEO,OAAApE,GACLrZ,KAAK+mG,UAAYn+F,OAAOo+F,OAAO,MAC/BhnG,KAAKmnG,WAAa,OAClBnnG,KAAKinG,QAAUH,CACjB,CAEO,KAAAx1F,GAEL,GAAe,IAAXtR,KAAK6iD,OACP,IAAK,IAAI76B,EAAIhoB,KAAKonG,OAAOhwB,OAASp3E,KAAKonG,OAAOC,aAAe,EAAIrnG,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,IAAKA,EAClGhoB,KAAKinG,QAAQj/E,GAAG1lB,KAAI,GAGxBtC,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKinG,QAAUH,EACf9mG,KAAK62F,KAAO,EACZ72F,KAAK6iD,OAAM,CACb,CAEQ,MAAA8e,GAEN,GADA3hE,KAAKinG,QAAUjnG,KAAK+mG,UAAU/mG,KAAK62F,MAAQiQ,EACtC9mG,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAG3lB,aAHlBrC,KAAKmnG,WAAWnnG,KAAK62F,IAAK,QAM9B,CAEQ,IAAA0V,CAAKtvF,EAAmB5a,EAAeC,GAC7C,GAAKtC,KAAKinG,QAAQ1lG,OAGhB,IAAK,IAAIymB,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAAGymB,GAAK,EAAGA,IAC5ChoB,KAAKinG,QAAQj/E,GAAG4/E,IAAI3qF,EAAM5a,EAAOC,QAHnCtC,KAAKmnG,WAAWnnG,KAAK62F,IAAK,OAAO,EAAAljB,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,GAMhE,CAEO,KAAAD,GAELrC,KAAKsR,QACLtR,KAAK6iD,OAAM,CACb,CASO,GAAA+kD,CAAI3qF,EAAmB5a,EAAeC,GAC3C,GAAe,IAAXtC,KAAK6iD,OAAT,CAGA,GAAe,IAAX7iD,KAAK6iD,OACP,KAAOxgD,EAAQC,GAAK,CAClB,MAAM04B,EAAO/d,EAAK5a,KAClB,GAAa,KAAT24B,EAAe,CACjBh7B,KAAK6iD,OAAM,EACX7iD,KAAK2hE,SACL,KACF,CACA,GAAI3mC,EAAO,IAAQ,GAAOA,EAExB,YADAh7B,KAAK6iD,OAAM,IAGK,IAAd7iD,KAAK62F,MACP72F,KAAK62F,IAAM,GAEb72F,KAAK62F,IAAiB,GAAX72F,KAAK62F,IAAW77D,EAAO,EACpC,CAEa,IAAXh7B,KAAK6iD,QAA+BvgD,EAAMD,EAAQ,GACpDrC,KAAKusG,KAAKtvF,EAAM5a,EAAOC,EApBzB,CAsBF,CAOO,GAAAA,CAAIwlG,EAAkBl2B,GAAyB,GACpD,GAAe,IAAX5xE,KAAK6iD,OAAT,CAIA,GAAe,IAAX7iD,KAAK6iD,OAQP,GAJe,IAAX7iD,KAAK6iD,QACP7iD,KAAK2hE,SAGF3hE,KAAKinG,QAAQ1lG,OAEX,CACL,IAAIwmG,GAA4C,EAC5C//E,EAAIhoB,KAAKinG,QAAQ1lG,OAAS,EAC1B+lG,GAAc,EAOlB,GANItnG,KAAKonG,OAAOhwB,SACdpvD,EAAIhoB,KAAKonG,OAAOC,aAAe,EAC/BU,EAAgBn2B,EAChB01B,EAActnG,KAAKonG,OAAOE,YAC1BtnG,KAAKonG,OAAOhwB,QAAS,IAElBkwB,IAAiC,IAAlBS,EAAyB,CAC3C,KAAO//E,GAAK,IACV+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAG1lB,IAAIwlG,IACd,IAAlBC,GAFS//E,IAIN,GAAI+/E,aAAyBz9B,QAIlC,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,EAGX//E,GACF,CAIA,KAAOA,GAAK,EAAGA,IAEb,GADA+/E,EAAgB/nG,KAAKinG,QAAQj/E,GAAG1lB,KAAI,GAChCylG,aAAyBz9B,QAI3B,OAHAtqE,KAAKonG,OAAOhwB,QAAS,EACrBp3E,KAAKonG,OAAOC,aAAer/E,EAC3BhoB,KAAKonG,OAAOE,aAAc,EACnBS,CAGb,MArCE/nG,KAAKmnG,WAAWnnG,KAAK62F,IAAK,MAAOiR,GAwCrC9nG,KAAKinG,QAAUH,EACf9mG,KAAK62F,KAAO,EACZ72F,KAAK6iD,OAAM,CArDX,CAsDF,GAOF,MAAAy5B,EAME,WAAA58E,CAAoBwjB,GAAAljB,KAAAkjB,SAAAA,EAHZljB,KAAA0nF,MAAQ,IAAIsK,EAAAgW,qBAAqB1rB,EAAW2rB,eAC5CjoG,KAAAkoG,WAAqB,CAEiD,CAEvE,KAAA7lG,GACLrC,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,CACnB,CAEO,GAAAN,CAAI3qF,EAAmB5a,EAAeC,GACvCtC,KAAKkoG,WAGLloG,KAAK0nF,MAAMqC,QAAO,EAAApW,EAAAk0B,eAAc5qF,EAAM5a,EAAOC,MAC/CtC,KAAKkoG,WAAY,EAErB,CAEO,GAAA5lG,CAAIwlG,GACT,IAAIK,GAAkC,EACtC,GAAInoG,KAAKkoG,UACPC,GAAM,OACD,GAAIL,IACTK,EAAMnoG,KAAKkjB,SAASljB,KAAK0nF,MAAMpjF,YAC3B6jG,aAAe79B,SAGjB,OAAO69B,EAAI5pB,KAAK6pB,IACdpoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVE,IAMb,OAFApoG,KAAK0nF,MAAMp2E,QACXtR,KAAKkoG,WAAY,EACVC,CACT,iBAxCe7rB,EAAA2rB,cAAa,gFC/J9B,MAAAQ,EAkBS,gBAAO+D,CAAUjoE,GACtB,MAAMszC,EAAS,IAAI4wB,EACnB,IAAKlkE,EAAOhjC,OACV,OAAOs2E,EAGT,IAAK,IAAI/4E,EAAKysE,MAAM8H,QAAQ9uC,EAAO,IAAO,EAAI,EAAGzlC,EAAIylC,EAAOhjC,SAAUzC,EAAG,CACvE,MAAM2L,EAAQ85B,EAAOzlC,GACrB,GAAIysE,MAAM8H,QAAQ5oE,GAChB,IAAK,IAAIwsF,EAAI,EAAGA,EAAIxsF,EAAMlJ,SAAU01F,EAClCpf,EAAOo0B,YAAYxhG,EAAMwsF,SAG3Bpf,EAAO6wB,SAASj+F,EAEpB,CACA,OAAOotE,CACT,CAMA,WAAAn4E,CAAmBgsE,EAAoB,GAAW+gC,EAA6B,IAC7E,kBADiB/gC,0BAA+B+gC,EAC5CA,EAAkB,IACpB,MAAM,IAAI1qG,MAAM,mDAElB/B,KAAK63E,OAAS,IAAI60B,WAAWhhC,GAC7B1rE,KAAKuB,OAAS,EACdvB,KAAK2sG,WAAa,IAAID,WAAWD,GACjCzsG,KAAK4sG,iBAAmB,EACxB5sG,KAAK6sG,cAAgB,IAAIhE,YAAYn9B,GACrC1rE,KAAK8sG,eAAgB,EACrB9sG,KAAK+sG,kBAAmB,EACxB/sG,KAAKgtG,aAAc,CACrB,CAKO,KAAAzzD,GACL,MAAM0zD,EAAY,IAAIxE,EAAOzoG,KAAK0rE,UAAW1rE,KAAKysG,oBASlD,OARAQ,EAAUp1B,OAAO/yE,IAAI9E,KAAK63E,QAC1Bo1B,EAAU1rG,OAASvB,KAAKuB,OACxB0rG,EAAUN,WAAW7nG,IAAI9E,KAAK2sG,YAC9BM,EAAUL,iBAAmB5sG,KAAK4sG,iBAClCK,EAAUJ,cAAc/nG,IAAI9E,KAAK6sG,eACjCI,EAAUH,cAAgB9sG,KAAK8sG,cAC/BG,EAAUF,iBAAmB/sG,KAAK+sG,iBAClCE,EAAUD,YAAchtG,KAAKgtG,YACtBC,CACT,CAQO,OAAAl1B,GACL,MAAMqwB,EAAmB,GACzB,IAAK,IAAItpG,EAAI,EAAGA,EAAIkB,KAAKuB,SAAUzC,EAAG,CACpCspG,EAAInkG,KAAKjE,KAAK63E,OAAO/4E,IACrB,MAAMuD,EAAQrC,KAAK6sG,cAAc/tG,IAAM,EACjCwD,EAA8B,IAAxBtC,KAAK6sG,cAAc/tG,GAC3BwD,EAAMD,EAAQ,GAChB+lG,EAAInkG,KAAKsnE,MAAMqT,UAAUr3E,MAAM+rE,KAAKtzE,KAAK2sG,WAAYtqG,EAAOC,GAEhE,CACA,OAAO8lG,CACT,CAKO,KAAA92F,GACLtR,KAAKuB,OAAS,EACdvB,KAAK4sG,iBAAmB,EACxB5sG,KAAK8sG,eAAgB,EACrB9sG,KAAK+sG,kBAAmB,EACxB/sG,KAAKgtG,aAAc,CACrB,CAKO,QAAAlB,GACL9rG,KAAKuB,OAAS,EACdvB,KAAK4sG,iBAAmB,EACxB5sG,KAAK8sG,eAAgB,EACrB9sG,KAAK+sG,kBAAmB,EACxB/sG,KAAKgtG,aAAc,EACnBhtG,KAAK6sG,cAAc,GAAK,EACxB7sG,KAAK63E,OAAO,GAAK,CACnB,CASO,QAAA6wB,CAASj+F,GAEd,GADAzK,KAAKgtG,aAAc,EACfhtG,KAAKuB,QAAUvB,KAAK0rE,UACtB1rE,KAAK8sG,eAAgB,MADvB,CAIA,GAAIriG,GAAS,EACX,MAAM,IAAI1I,MAAM,uCAElB/B,KAAK6sG,cAAc7sG,KAAKuB,QAAUvB,KAAK4sG,kBAAoB,EAAI5sG,KAAK4sG,iBACpE5sG,KAAK63E,OAAO73E,KAAKuB,UAAYkJ,EAAK,WAAwB,WAAuBA,CALjF,CAMF,CASO,WAAAwhG,CAAYxhG,GAEjB,GADAzK,KAAKgtG,aAAc,EACdhtG,KAAKuB,OAGV,GAAIvB,KAAK8sG,eAAiB9sG,KAAK4sG,kBAAoB5sG,KAAKysG,mBACtDzsG,KAAK+sG,kBAAmB,MAD1B,CAIA,GAAItiG,GAAS,EACX,MAAM,IAAI1I,MAAM,uCAElB/B,KAAK2sG,WAAW3sG,KAAK4sG,oBAAsBniG,EAAK,WAAwB,WAAuBA,EAC/FzK,KAAK6sG,cAAc7sG,KAAKuB,OAAS,IALjC,CAMF,CAKO,YAAAojF,CAAavR,GAClB,OAAmC,IAA1BpzE,KAAK6sG,cAAcz5B,KAAgBpzE,KAAK6sG,cAAcz5B,IAAQ,GAAK,CAC9E,CAOO,YAAAyR,CAAazR,GAClB,MAAM/wE,EAAQrC,KAAK6sG,cAAcz5B,IAAQ,EACnC9wE,EAAgC,IAA1BtC,KAAK6sG,cAAcz5B,GAC/B,OAAI9wE,EAAMD,EAAQ,EACTrC,KAAK2sG,WAAWztB,SAAS78E,EAAOC,GAElC,IACT,CAMO,eAAA4qG,GACL,MAAMluF,EAAsC,GAC5C,IAAK,IAAIlgB,EAAI,EAAGA,EAAIkB,KAAKuB,SAAUzC,EAAG,CACpC,MAAMuD,EAAQrC,KAAK6sG,cAAc/tG,IAAM,EACjCwD,EAA8B,IAAxBtC,KAAK6sG,cAAc/tG,GAC3BwD,EAAMD,EAAQ,IAChB2c,EAAOlgB,GAAKkB,KAAK2sG,WAAWplG,MAAMlF,EAAOC,GAE7C,CACA,OAAO0c,CACT,CAMO,QAAAgtF,CAASvhG,GACd,IAAIlJ,EACJ,GAAIvB,KAAK8sG,iBACFvrG,EAASvB,KAAKgtG,YAAchtG,KAAK4sG,iBAAmB5sG,KAAKuB,SAC1DvB,KAAKgtG,aAAehtG,KAAK+sG,iBAE7B,OAGF,MAAMhuC,EAAQ/+D,KAAKgtG,YAAchtG,KAAK2sG,WAAa3sG,KAAK63E,OAClDs1B,EAAMpuC,EAAMx9D,EAAS,GAC3Bw9D,EAAMx9D,EAAS,IAAM4rG,EAAMx4F,KAAKC,IAAU,GAANu4F,EAAW1iG,EAAK,YAAyBA,CAC/E,8GCzOF,iBAAA/K,GACYM,KAAAotG,QAA0B,EAsCtC,CApCS,OAAA/zF,GACL,IAAK,IAAIva,EAAIkB,KAAKotG,QAAQ7rG,OAAS,EAAGzC,GAAK,EAAGA,IAC5CkB,KAAKotG,QAAQtuG,GAAGuuG,SAASh0F,SAE7B,CAEO,SAAA+qB,CAAUuO,EAAoB06D,GACnC,MAAMC,EAA4B,CAChCD,WACAh0F,QAASg0F,EAASh0F,QAClB+d,YAAY,GAEdp3B,KAAKotG,QAAQnpG,KAAKqpG,GAClBD,EAASh0F,QAAU,IAAMrZ,KAAKutG,qBAAqBD,GACnDD,EAAShlF,SAASsqB,EACpB,CAEQ,oBAAA46D,CAAqBD,GAC3B,GAAIA,EAAYl2E,WAEd,OAEF,IAAI/kB,GAAS,EACb,IAAK,IAAIvT,EAAI,EAAGA,EAAIkB,KAAKotG,QAAQ7rG,OAAQzC,IACvC,GAAIkB,KAAKotG,QAAQtuG,KAAOwuG,EAAa,CACnCj7F,EAAQvT,EACR,KACF,CAEF,IAAe,IAAXuT,EACF,MAAM,IAAItQ,MAAM,uDAElBurG,EAAYl2E,YAAa,EACzBk2E,EAAYj0F,QAAQ+6C,MAAMk5C,EAAYD,UACtCrtG,KAAKotG,QAAQtlF,OAAOzV,EAAO,EAC7B,wFC5CF,MAAAm7F,EAAAtuG,EAAA,KACA+qB,EAAA/qB,EAAA,sBAEA,MACE,WAAAQ,CACU+iC,EACQjxB,gBADRixB,YACQjxB,CACd,CAEG,IAAAi8F,CAAKtpG,GAEV,OADAnE,KAAKyiC,QAAUt+B,EACRnE,IACT,CAEA,WAAWuU,GAAoB,OAAOvU,KAAKyiC,QAAQtuB,CAAG,CACtD,WAAWO,GAAoB,OAAO1U,KAAKyiC,QAAQ5tB,CAAG,CACtD,aAAW+9B,GAAsB,OAAO5yC,KAAKyiC,QAAQj+B,KAAO,CAC5D,SAAWkpG,GAAkB,OAAO1tG,KAAKyiC,QAAQjuB,KAAO,CACxD,UAAWjT,GAAmB,OAAOvB,KAAKyiC,QAAQp+B,MAAM9C,MAAQ,CACzD,OAAAosG,CAAQx5F,GACb,MAAM5P,EAAOvE,KAAKyiC,QAAQp+B,MAAMP,IAAIqQ,GACpC,GAAK5P,EAGL,OAAO,IAAIipG,EAAAI,kBAAkBrpG,EAC/B,CACO,WAAAo8E,GAAgC,OAAO,IAAI12D,EAAAI,QAAY,2FC5BhE,MAAAJ,EAAA/qB,EAAA,0BAIA,MACE,WAAAQ,CAAoBmuG,cAAAA,CAAsB,CAE1C,aAAW3hF,GAAuB,OAAOlsB,KAAK6tG,MAAM3hF,SAAW,CAC/D,UAAW3qB,GAAmB,OAAOvB,KAAK6tG,MAAMtsG,MAAQ,CACjD,OAAAusG,CAAQj5F,EAAWnM,GACxB,KAAImM,EAAI,GAAKA,GAAK7U,KAAK6tG,MAAMtsG,QAI7B,OAAImH,GACF1I,KAAK6tG,MAAM/iF,SAASjW,EAAGnM,GAChBA,GAEF1I,KAAK6tG,MAAM/iF,SAASjW,EAAG,IAAIoV,EAAAI,SACpC,CACO,iBAAA1lB,CAAkBitF,EAAqBmc,EAAsBC,GAClE,OAAOhuG,KAAK6tG,MAAMlpG,kBAAkBitF,EAAWmc,EAAaC,EAC9D,6FCrBF,MAAAC,EAAA/uG,EAAA,MAEAE,EAAAF,EAAA,MACA8O,EAAA9O,EAAA,MAEA,MAAAwjC,UAAwCtjC,EAAAK,WAOtC,WAAAC,CAAoB2hC,GAClBthC,QADkBC,KAAAqhC,MAAAA,EAHHrhC,KAAAkuG,gBAAkBluG,KAAK0B,UAAU,IAAIsM,EAAAsB,SACtCtP,KAAAmuG,eAAiBnuG,KAAKkuG,gBAAgB3/F,MAIpDvO,KAAKk2F,QAAU,IAAI+X,EAAAG,cAAcpuG,KAAKqhC,MAAM7tB,QAAQgjB,OAAQ,UAC5Dx2B,KAAKquG,WAAa,IAAIJ,EAAAG,cAAcpuG,KAAKqhC,MAAM7tB,QAAQ4f,IAAK,aAC5DpzB,KAAK0B,UAAU1B,KAAKqhC,MAAM7tB,QAAQie,iBAAiB,IAAMzxB,KAAKkuG,gBAAgBj9F,KAAKjR,KAAKyT,SAC1F,CACA,UAAWA,GACT,GAAIzT,KAAKqhC,MAAM7tB,QAAQC,SAAWzT,KAAKqhC,MAAM7tB,QAAQgjB,OAAU,OAAOx2B,KAAKw2B,OAC3E,GAAIx2B,KAAKqhC,MAAM7tB,QAAQC,SAAWzT,KAAKqhC,MAAM7tB,QAAQ4f,IAAO,OAAOpzB,KAAKsuG,UACxE,MAAM,IAAIvsG,MAAM,gDAClB,CACA,UAAWy0B,GACT,OAAOx2B,KAAKk2F,QAAQuX,KAAKztG,KAAKqhC,MAAM7tB,QAAQgjB,OAC9C,CACA,aAAW83E,GACT,OAAOtuG,KAAKquG,WAAWZ,KAAKztG,KAAKqhC,MAAM7tB,QAAQ4f,IACjD,oHCzBF,MACE,WAAA1zB,CAAoB2hC,cAAAA,CAAwB,CAErC,kBAAAkxC,CAAmBp4C,EAAyB7P,GACjD,OAAOtqB,KAAKqhC,MAAMkxC,mBAAmBp4C,EAAK09C,GAAoBvtD,EAASutD,EAAOE,WAChF,CACO,aAAAw2B,CAAcp0E,EAAyB7P,GAC5C,OAAOtqB,KAAKuyE,mBAAmBp4C,EAAI7P,EACrC,CACO,kBAAAgoD,CAAmBn4C,EAAyB7P,GACjD,OAAOtqB,KAAKqhC,MAAMixC,mBAAmBn4C,EAAI,CAACld,EAAc46D,IAAoBvtD,EAASrN,EAAM46D,EAAOE,WACpG,CACO,aAAAy2B,CAAcr0E,EAAyB7P,GAC5C,OAAOtqB,KAAKsyE,mBAAmBn4C,EAAI7P,EACrC,CACO,kBAAA+nD,CAAmBl4C,EAAyB1c,GACjD,OAAOzd,KAAKqhC,MAAMgxC,mBAAmBl4C,EAAI1c,EAC3C,CACO,aAAAgxF,CAAct0E,EAAyB1c,GAC5C,OAAOzd,KAAKqyE,mBAAmBl4C,EAAI1c,EACrC,CACO,kBAAA+0D,CAAmBpgE,EAAekY,GACvC,OAAOtqB,KAAKqhC,MAAMmxC,mBAAmBpgE,EAAOkY,EAC9C,CACO,aAAAokF,CAAct8F,EAAekY,GAClC,OAAOtqB,KAAKwyE,mBAAmBpgE,EAAOkY,EACxC,CACO,kBAAAmoD,CAAmBt4C,EAAyB7P,GACjD,OAAOtqB,KAAKqhC,MAAMoxC,mBAAmBt4C,EAAI7P,EAC3C,gGC9BF,MACE,WAAA5qB,CAAoB2hC,cAAAA,CAAwB,CAErC,QAAA1jB,CAASgxF,GACd3uG,KAAKqhC,MAAMuvC,eAAejzD,SAASgxF,EACrC,CAEA,YAAWC,GACT,OAAO5uG,KAAKqhC,MAAMuvC,eAAeg+B,QACnC,CAEA,iBAAWC,GACT,OAAO7uG,KAAKqhC,MAAMuvC,eAAei+B,aACnC,CAEA,iBAAWA,CAAczO,GACvBpgG,KAAKqhC,MAAMuvC,eAAei+B,cAAgBzO,CAC5C,6fCpBF,MAAAhhG,EAAAF,EAAA,MAEA4vG,EAAA5vG,EAAA,MACAG,EAAAH,EAAA,MACA8O,EAAA9O,EAAA,MAOO,IAAMuxE,EAAN,cAA4BrxE,EAAAK,WAcjC,UAAW0E,GAAoB,OAAOnE,KAAKwT,QAAQC,MAAQ,CAK3D,WAAA/T,CACmB0K,EACJ+9E,GAEbpoF,QAhBKC,KAAA+uG,iBAA2B,EAEjB/uG,KAAAowE,UAAYpwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAiC,SAAWjC,KAAKowE,UAAU7hE,MACzBvO,KAAAgb,UAAYhb,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAuC,SAAWvC,KAAKgb,UAAUzM,MAYxCvO,KAAKiI,KAAO0M,KAAKkZ,IAAIzjB,EAAeE,WAAWrC,MAAQ,EAAC,GACxDjI,KAAKe,KAAO4T,KAAKkZ,IAAIzjB,EAAeE,WAAWvJ,MAAQ,EAAC,GACxDf,KAAKwT,QAAUxT,KAAK0B,UAAU,IAAIotG,EAAAhZ,UAAU1rF,EAAgBpK,KAAMmoF,IAClEnoF,KAAK0B,UAAU1B,KAAKwT,QAAQie,iBAAiBtwB,IAC3CnB,KAAKgb,UAAU/J,KAAK9P,EAAEwkE,aAAanhE,SAEvC,CAEO,MAAA2U,CAAOlR,EAAclH,GAC1B,MAAMiuG,EAAchvG,KAAKiI,OAASA,EAC5Bu7D,EAAcxjE,KAAKe,OAASA,EAClCf,KAAKiI,KAAOA,EACZjI,KAAKe,KAAOA,EACZf,KAAKwT,QAAQ2F,OAAOlR,EAAMlH,GAC1Bf,KAAKowE,UAAUn/D,KAAK,CAAEhJ,OAAMlH,OAAMiuG,cAAaxrC,eACjD,CAEO,KAAAlyD,GACLtR,KAAKwT,QAAQlC,QACbtR,KAAK+uG,iBAAkB,CACzB,CAOO,MAAA58B,CAAOC,EAA2BlmD,GAAqB,GAC5D,MAAM/nB,EAASnE,KAAKmE,OAEpB,IAAIssF,EACJA,EAAUzwF,KAAKivG,iBACVxe,GAAWA,EAAQlvF,SAAWvB,KAAKiI,MAAQwoF,EAAQh5B,MAAM,KAAO2a,EAAUnmE,IAAMwkF,EAAQ94B,MAAM,KAAOya,EAAUpmE,KAClHykF,EAAUtsF,EAAOyc,aAAawxD,EAAWlmD,GACzClsB,KAAKivG,iBAAmBxe,GAE1BA,EAAQvkE,UAAYA,EAEpB,MAAMgjF,EAAS/qG,EAAOqQ,MAAQrQ,EAAO6tB,UAC/Bm9E,EAAYhrG,EAAOqQ,MAAQrQ,EAAOutE,aAExC,GAAyB,IAArBvtE,EAAO6tB,UAAiB,CAE1B,MAAMo9E,EAAsBjrG,EAAOE,MAAM2nE,OAGrCmjC,IAAchrG,EAAOE,MAAM9C,OAAS,EAClC6tG,EACFjrG,EAAOE,MAAM0nE,UAAUinB,SAASvC,GAEhCtsF,EAAOE,MAAMJ,KAAKwsF,EAAQl3C,SAG5Bp1C,EAAOE,MAAMyjB,OAAOqnF,EAAY,EAAG,EAAG1e,EAAQl3C,SAI3C61D,EASCpvG,KAAK+uG,kBACP5qG,EAAOK,MAAQmQ,KAAKkZ,IAAI1pB,EAAOK,MAAQ,EAAG,KAT5CL,EAAOqQ,QAEFxU,KAAK+uG,iBACR5qG,EAAOK,QASb,KAAO,CAGL,MAAMoiF,EAAqBuoB,EAAYD,EAAS,EAChD/qG,EAAOE,MAAMgoE,cAAc6iC,EAAS,EAAGtoB,EAAqB,GAAI,GAChEziF,EAAOE,MAAMS,IAAIqqG,EAAW1e,EAAQl3C,QACtC,CAIKv5C,KAAK+uG,kBACR5qG,EAAOK,MAAQL,EAAOqQ,OAGxBxU,KAAKgb,UAAU/J,KAAK9M,EAAOK,MAC7B,CASO,WAAAsB,CAAY2W,EAAc/B,GAC/B,MAAMvW,EAASnE,KAAKmE,OACpB,GAAIsY,EAAO,EAAG,CACZ,GAAqB,IAAjBtY,EAAOK,MACT,OAEFxE,KAAK+uG,iBAAkB,CACzB,MAAWtyF,EAAOtY,EAAOK,OAASL,EAAOqQ,QACvCxU,KAAK+uG,iBAAkB,GAGzB,MAAMM,EAAWlrG,EAAOK,MACxBL,EAAOK,MAAQmQ,KAAKkZ,IAAIlZ,KAAKC,IAAIzQ,EAAOK,MAAQiY,EAAMtY,EAAOqQ,OAAQ,GAGjE66F,IAAalrG,EAAOK,QAInBkW,GACH1a,KAAKgb,UAAU/J,KAAK9M,EAAOK,OAE/B,qCA5IWisE,EAAalnE,EAAA,CAoBrBC,EAAA,EAAAnK,EAAA0tB,iBACAvjB,EAAA,EAAAnK,EAAAu/D,cArBQ6R,wGCRb,iBAAA/wE,GAISM,KAAA6lF,OAAiB,EAEhB7lF,KAAAsvG,UAAsC,EAuBhD,CArBE,YAAW3pB,GACT,OAAO3lF,KAAKsvG,SACd,CAEO,KAAAh+F,GACLtR,KAAKs/E,aAAU16E,EACf5E,KAAKsvG,UAAY,GACjBtvG,KAAK6lF,OAAS,CAChB,CAEO,SAAAvI,CAAUzuD,GACf7uB,KAAK6lF,OAASh3D,EACd7uB,KAAKs/E,QAAUt/E,KAAKsvG,UAAUzgF,EAChC,CAEO,WAAAm0D,CAAYn0D,EAAWywD,GAC5Bt/E,KAAKsvG,UAAUzgF,GAAKywD,EAChBt/E,KAAK6lF,SAAWh3D,IAClB7uB,KAAKs/E,QAAUA,EAEnB,2fC/BF,MAAAlgF,EAAAF,EAAA,MAEAG,EAAAH,EAAA,MACA8O,EAAA9O,EAAA,MAEMqwG,EAAwB3mG,OAAO+lB,OAAO,CAC1CwU,YAAY,IAGRqsE,EAA8C5mG,OAAO+lB,OAAO,CAChEqU,uBAAuB,EACvBE,mBAAmB,EACnBl5B,oBAAoB,EACpB4O,oBAAoB,EACpBqxB,iBAAarlC,EACbslC,iBAAatlC,EACby+B,QAAQ,EACRE,mBAAmB,EACnB1vB,WAAW,EACXye,oBAAoB,EACpBsR,gBAAgB,EAChBE,YAAY,IAWP,IAAM4sC,EAAN,cAA0BtxE,EAAAK,WAkB/B,WAAAC,CACmCoS,EACHgF,EACIoT,GAElCnqB,QAJiCC,KAAA8R,eAAAA,EACH9R,KAAA8W,YAAAA,EACI9W,KAAAkqB,gBAAAA,EAjB7BlqB,KAAA0jC,gBAA0B,EAKhB1jC,KAAAkwE,QAAUlwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC9BtP,KAAAkiC,OAASliC,KAAKkwE,QAAQ3hE,MACrBvO,KAAAyvG,aAAezvG,KAAK0B,UAAU,IAAIsM,EAAAsB,SACnCtP,KAAAgjE,YAAchjE,KAAKyvG,aAAalhG,MAC/BvO,KAAAiwE,UAAYjwE,KAAK0B,UAAU,IAAIsM,EAAAsB,SAChCtP,KAAAiiC,SAAWjiC,KAAKiwE,UAAU1hE,MACzBvO,KAAA0vG,yBAA2B1vG,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC/CtP,KAAAqxE,wBAA0BrxE,KAAK0vG,yBAAyBnhG,MAQtEvO,KAAKwc,oBAAsB0N,EAAgB5f,WAAWqlG,wBAAyB,EAC/E3vG,KAAK2iC,MAAQitE,gBAAgBL,GAC7BvvG,KAAKqK,gBAAkBulG,gBAAgBJ,GACvCxvG,KAAK66D,cAnCuD,CAC9DC,MAAO,EACPuoB,UAAW,EACXC,SAAU,EACV+D,UAAW,GACXD,SAAU,GA+BV,CAEO,KAAA91E,GACLtR,KAAK2iC,MAAQitE,gBAAgBL,GAC7BvvG,KAAKqK,gBAAkBulG,gBAAgBJ,GACvCxvG,KAAK66D,cAzCuD,CAC9DC,MAAO,EACPuoB,UAAW,EACXC,SAAU,EACV+D,UAAW,GACXD,SAAU,GAqCV,CAEO,gBAAA58E,CAAiByS,EAAc8mB,GAAwB,GAE5D,GAAI/jC,KAAKkqB,gBAAgB5f,WAAW4N,aAClC,OAIF,MAAM/T,EAASnE,KAAK8R,eAAe3N,OAC/B4/B,GAAgB/jC,KAAKkqB,gBAAgB5f,WAAWyU,mBAAqB5a,EAAOqQ,QAAUrQ,EAAOK,OAC/FxE,KAAK0vG,yBAAyBz+F,OAI5B8yB,GACF/jC,KAAKyvG,aAAax+F,OAIpBjR,KAAK8W,YAAYC,MAAM,iBAAiBkG,MACxCjd,KAAK8W,YAAYgoE,MAAM,uBAAwB,IAAM7hE,EAAK8hE,MAAM,IAAI53D,IAAIhmB,GAAKA,EAAEse,WAAW,KAC1Fzf,KAAKkwE,QAAQj/D,KAAKgM,EACpB,CAEO,kBAAAqhD,CAAmBrhD,GACpBjd,KAAKkqB,gBAAgB5f,WAAW4N,eAGpClY,KAAK8W,YAAYC,MAAM,mBAAmBkG,MAC1Cjd,KAAK8W,YAAYgoE,MAAM,yBAA0B,IAAM7hE,EAAK8hE,MAAM,IAAI53D,IAAIhmB,GAAKA,EAAEse,WAAW,KAC5Fzf,KAAKiwE,UAAUh/D,KAAKgM,GACtB,iCAlEWyzD,EAAWnnE,EAAA,CAmBnBC,EAAA,EAAAnK,EAAAyqB,gBACAtgB,EAAA,EAAAnK,EAAAu/D,aACAp1D,EAAA,EAAAnK,EAAA0tB,kBArBQ2jD,uhBC/Bb,MAAA/tD,EAAAzjB,EAAA,MACAqO,EAAArO,EAAA,MACAE,EAAAF,EAAA,MACAG,EAAAH,EAAA,MACA2wG,EAAA3wG,EAAA,MAGA8O,EAAA9O,EAAA,MAGA,IAAI4wG,EAAQ,EACRC,EAAQ,EAEC3/F,EAAN,cAAgChR,EAAAK,WAiBrC,eAAWgpB,GAAuD,OAAOzoB,KAAKgwG,aAAazrE,QAAU,CAErG,WAAA7kC,CACgCoX,EACGhF,GAEjC/R,QAH8BC,KAAA8W,YAAAA,EACG9W,KAAA8R,eAAAA,EAXlB9R,KAAAiwG,WAAajwG,KAAK0B,UAAU,IAAIwuG,GAEhClwG,KAAAmwG,wBAA0BnwG,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC9CtP,KAAAqzB,uBAAyBrzB,KAAKmwG,wBAAwB5hG,MACrDvO,KAAAowG,qBAAuBpwG,KAAK0B,UAAU,IAAIsM,EAAAsB,SAC3CtP,KAAAszB,oBAAsBtzB,KAAKowG,qBAAqB7hG,MAU9DvO,KAAKgwG,aAAe,IAAIH,EAAAQ,WAAWlvG,GAAKA,GAAG2yB,OAAOvvB,KAAMvE,KAAK8W,aAE7D9W,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,IAAMzD,KAAKsR,UACvCtR,KAAK0B,UAAU1B,KAAK8R,eAAe0B,QAAQie,iBAAiB,KAC1DzxB,KAAKiwG,WAAWK,oBAAoBtwG,KAAK8R,eAAe3N,OAAOE,UAEjErE,KAAKiwG,WAAWK,oBAAoBtwG,KAAK8R,eAAe3N,OAAOE,MACjE,CAEO,kBAAA6Z,CAAmBhV,GACxB,GAAIA,EAAQ4qB,OAAOsD,WACjB,OAEF,MAAM7D,EAAa,IAAIg9E,EAAWrnG,GAClC,GAAIqqB,EAAY,CACd,MAAMi9E,EAAgBj9E,EAAWO,OAAOG,UAAU,IAAMV,EAAWla,WAC7Dy7C,EAAWvhC,EAAWU,UAAU,KACpC6gC,EAASz7C,UACLka,IACEvzB,KAAKgwG,aAAa97E,OAAOX,KAC3BvzB,KAAKiwG,WAAWvsG,OAAO6vB,GACvBvzB,KAAKowG,qBAAqBn/F,KAAKsiB,IAEjCi9E,EAAcn3F,aAGlBrZ,KAAKgwG,aAAarnB,OAAOp1D,GACzBvzB,KAAKiwG,WAAWtvG,IAAI4yB,GACpBvzB,KAAKmwG,wBAAwBl/F,KAAKsiB,EACpC,CACA,OAAOA,CACT,CAEO,KAAAjiB,GACL,IAAK,MAAMm8B,KAAKztC,KAAKgwG,aAAazrE,SAChCkJ,EAAEp0B,UAEJrZ,KAAKgwG,aAAa3jG,QAClBrM,KAAKiwG,WAAW5jG,OAClB,CAEO,qBAACokG,CAAqB57F,EAAWtQ,EAAcsvB,GACpD,MAAM68E,EAAS1wG,KAAKiwG,WAAWU,qBAAqBpsG,GACpD,GAAKmsG,EAGL,IAAK,MAAMjjE,KAAKijE,EACdZ,EAAQriE,EAAEvkC,QAAQ2L,GAAK,EACvBk7F,EAAQD,GAASriE,EAAEvkC,QAAQH,OAAS,GAChC8L,GAAKi7F,GAASj7F,EAAIk7F,KAAWl8E,IAAU4Z,EAAEvkC,QAAQ2qB,OAAS,YAAcA,WACpE4Z,EAGZ,CAEO,uBAAAD,CAAwB34B,EAAWtQ,EAAcsvB,EAAqCvJ,GAC3F,MAAMomF,EAAS1wG,KAAKiwG,WAAWU,qBAAqBpsG,GACpD,GAAKmsG,EAGL,IAAK,MAAMjjE,KAAKijE,EACdZ,EAAQriE,EAAEvkC,QAAQ2L,GAAK,EACvBk7F,EAAQD,GAASriE,EAAEvkC,QAAQH,OAAS,GAChC8L,GAAKi7F,GAASj7F,EAAIk7F,KAAWl8E,IAAU4Z,EAAEvkC,QAAQ2qB,OAAS,YAAcA,IAC1EvJ,EAASmjB,EAGf,6CA5FWr9B,EAAiB7G,EAAA,CAoBzBC,EAAA,EAAAnK,EAAAu/D,aACAp1D,EAAA,EAAAnK,EAAAyqB,iBArBQ1Z,GAsGb,MAAA8/F,UAAyC9wG,EAAAK,WAAzC,WAAAC,uBACmBM,KAAA4wG,mBAAyD,IAAInsF,IAC7DzkB,KAAAgwG,aAAe,IAAIxoF,IACnBxnB,KAAA6wG,qBAAuB7wG,KAAK0B,UAAU,IAAItC,EAAA0P,mBAC1C9O,KAAA8wG,oBAAsB9wG,KAAK0B,UAAU,IAAIihB,EAAAouF,gBAClD/wG,KAAAgxG,wBAA0C,EA6MpD,CA3MS,KAAA3kG,GACLrM,KAAKgxG,wBAAwBzvG,OAAS,EACtCvB,KAAK8wG,oBAAoB1xF,SACzBpf,KAAK4wG,mBAAmBvkG,QACxBrM,KAAKgwG,aAAa3jG,OACpB,CAEO,GAAA1L,CAAI4yB,GACTvzB,KAAKgwG,aAAarvG,IAAI4yB,GACtBvzB,KAAKixG,kBAAkB19E,EACzB,CAEO,MAAA7vB,CAAO6vB,GACZvzB,KAAKgwG,aAAa97E,OAAOX,GACzBvzB,KAAKkxG,uBAAuB39E,EAC9B,CAEO,oBAAAo9E,CAAqBpsG,GAC1B,OAAOvE,KAAK4wG,mBAAmB9sG,IAAIS,EACrC,CAEO,mBAAA+rG,CAAoBjsG,GACzB,MAAM06D,EAAQ,IAAI3/D,EAAAy8C,gBAClB77C,KAAK6wG,qBAAqBpmG,MAAQs0D,EAClCA,EAAMp+D,IAAI0D,EAAM4+D,OAAOxoD,GAAUza,KAAKmxG,uBAAuB12F,KAC7DskD,EAAMp+D,IAAI0D,EAAM+mE,SAAS78D,GAASvO,KAAKoxG,yBAAyB7iG,KAChEwwD,EAAMp+D,IAAI0D,EAAM6mE,SAAS38D,GAASvO,KAAKqxG,yBAAyB9iG,IAClE,CAEQ,oBAAA+iG,CAAqB/9E,GAC3B,OAAOA,EAAWrqB,QAAQP,QAAU,CACtC,CAEQ,iBAAAsoG,CAAkB19E,GACxB,MAAMlxB,EAAQkxB,EAAWO,OAAOvvB,KAChC,GAAIlC,EAAQ,EACV,OAEFkxB,EAAWg+E,kBAAoBlvG,EAC/B,MAAMsG,EAAS3I,KAAKsxG,qBAAqB/9E,GACzC,IAAK,IAAIhvB,EAAOlC,EAAOkC,EAAOlC,EAAQsG,EAAQpE,IAAQ,CACpD,IAAImsG,EAAS1wG,KAAK4wG,mBAAmB9sG,IAAIS,GACpCmsG,IACHA,EAAS,GACT1wG,KAAK4wG,mBAAmB9rG,IAAIP,EAAMmsG,IAEpCA,EAAOzsG,KAAKsvB,EACd,CACF,CAEQ,sBAAA29E,CAAuB39E,GAC7B,MAAMlxB,EAAQkxB,EAAWg+E,kBACnB5oG,EAAS3I,KAAKsxG,qBAAqB/9E,GACzC,IAAK,IAAIhvB,EAAOlC,EAAOkC,EAAOlC,EAAQsG,EAAQpE,IAAQ,CACpD,MAAMmsG,EAAS1wG,KAAK4wG,mBAAmB9sG,IAAIS,GAC3C,IAAKmsG,EACH,SAEF,MAAMr+F,EAAQq+F,EAAOv1C,QAAQ5nC,IACd,IAAXlhB,GACFq+F,EAAO5oF,OAAOzV,EAAO,GAED,IAAlBq+F,EAAOnvG,QACTvB,KAAK4wG,mBAAmB18E,OAAO3vB,EAEnC,CACF,CAEQ,kBAAAitG,CAAmBj+E,GACzBvzB,KAAKkxG,uBAAuB39E,IACvBA,EAAWO,OAAOsD,YAAc7D,EAAWO,OAAOvvB,MAAQ,GAC7DvE,KAAKixG,kBAAkB19E,EAE3B,CAGQ,sBAAAk+E,CAAuBnnF,GAC7BtqB,KAAKgxG,wBAAwB/sG,KAAKqmB,GAClCtqB,KAAK8wG,oBAAoBhsG,IAAI,KAC3B,MAAM4sG,EAAY1xG,KAAKgxG,wBACvBhxG,KAAKgxG,wBAA0B,GAC/B,IAAK,MAAMhhF,KAAM0hF,EACf1hF,KAGN,CAEQ,sBAAAmhF,CAAuB12F,GAC7B,GAAIA,GAAU,EACZ,OAEF,MAAMk3F,EAAS,IAAIltF,IACnB,IAAK,MAAOlgB,EAAMmsG,KAAW1wG,KAAK4wG,mBAAoB,CACpD,MAAMngB,EAAUlsF,EAAOkW,EACnBg2E,EAAU,GAGdzwF,KAAK4xG,iBAAiBD,EAAQlhB,EAASigB,EACzC,CACA1wG,KAAK4wG,mBAAmBvkG,QACxB,IAAK,MAAO9H,EAAMmsG,KAAWiB,EAC3B3xG,KAAK4wG,mBAAmB9rG,IAAIP,EAAMmsG,GAEpC,IAAK,MAAMjjE,KAAKztC,KAAKgwG,aACdviE,EAAE3Z,OAAOsD,aACZqW,EAAE8jE,mBAAqB92F,EAG7B,CAEQ,wBAAA22F,CAAyB7iG,GAC/BvO,KAAKyxG,uBAAuB,IAAMzxG,KAAK6xG,wBAAwBtjG,GACjE,CAEQ,wBAAA8iG,CAAyB9iG,GAC/BvO,KAAKyxG,uBAAuB,IAAMzxG,KAAK8xG,wBAAwBvjG,GACjE,CAEQ,gBAAAqjG,CAAiBD,EAA4CptG,EAAcmsG,GACjF,MAAMqB,EAAWJ,EAAO7tG,IAAIS,GAC5B,GAAIwtG,EACF,IAAK,IAAIjzG,EAAI,EAAGgyD,EAAM4/C,EAAOnvG,OAAQzC,EAAIgyD,EAAKhyD,IAC5CizG,EAAS9tG,KAAKysG,EAAO5xG,SAGvB6yG,EAAO7sG,IAAIP,EAAMmsG,EAAOnpG,QAE5B,CAMQ,uBAAAsqG,CAAwBtjG,GAC9B,MAAM8D,MAAEA,EAAKoI,OAAEA,GAAWlM,EACpByjG,EAAsC,GAC5C,IAAK,MAAMvkE,KAAKztC,KAAKgwG,aAAc,CACjC,GAAIviE,EAAE3Z,OAAOsD,WACX,SAEF,MAAM/0B,EAAQorC,EAAE8jE,kBACZlvG,EAAQgQ,GAAShQ,EAAQrC,KAAKsxG,qBAAqB7jE,GAAKp7B,IAC1D2/F,EAAa/tG,KAAKwpC,GAClBztC,KAAKkxG,uBAAuBzjE,GAEhC,CACA,MAAMkkE,EAAS,IAAIltF,IACnB,IAAK,MAAOlgB,EAAMmsG,KAAW1wG,KAAK4wG,mBAAoB,CACpD,MAAMngB,EAAUlsF,GAAQ8N,EAAQ9N,EAAOkW,EAASlW,EAChDvE,KAAK4xG,iBAAiBD,EAAQlhB,EAASigB,EACzC,CACA1wG,KAAK4wG,mBAAmBvkG,QACxB,IAAK,MAAO9H,EAAMmsG,KAAWiB,EAC3B3xG,KAAK4wG,mBAAmB9rG,IAAIP,EAAMmsG,GAEpC,IAAK,MAAMjjE,KAAKztC,KAAKgwG,aACfviE,EAAE3Z,OAAOsD,YAGTqW,EAAE8jE,mBAAqBl/F,IACzBo7B,EAAE8jE,kBAAoB9jE,EAAE3Z,OAAOvvB,MAGnC,IAAK,MAAMkpC,KAAKukE,EACdhyG,KAAKixG,kBAAkBxjE,EAE3B,CAMQ,uBAAAqkE,CAAwBvjG,GAC9B,MAAM0jG,EAAY1jG,EAAM8D,MAAQ9D,EAAMkM,OAChCk3F,EAAS,IAAIltF,IACnB,IAAK,MAAOlgB,EAAMmsG,KAAW1wG,KAAK4wG,mBAAoB,CACpD,GAAIrsG,GAAQgK,EAAM8D,OAAS9N,EAAO0tG,EAChC,SAEF,MAAMxhB,EAAUlsF,GAAQ0tG,EAAY1tG,EAAOgK,EAAMkM,OAASlW,EAC1DvE,KAAK4xG,iBAAiBD,EAAQlhB,EAASigB,EACzC,CACA1wG,KAAK4wG,mBAAmBvkG,QACxB,IAAK,MAAO9H,EAAMmsG,KAAWiB,EAC3B3xG,KAAK4wG,mBAAmB9rG,IAAIP,EAAMmsG,GAEpC,MAAMwB,EAAmC,GACzC,IAAK,MAAMzkE,KAAKztC,KAAKgwG,aAAc,CACjC,GAAIviE,EAAE3Z,OAAOsD,WACX,SAEF,MAAM/0B,EAAQorC,EAAE8jE,kBACV5oG,EAAS3I,KAAKsxG,qBAAqB7jE,GACrCprC,GAAS4vG,EACXxkE,EAAE8jE,kBAAoB9jE,EAAE3Z,OAAOvvB,KACtBlC,EAAQkM,EAAM8D,OAAShQ,EAAQsG,EAASspG,GACjDC,EAAUjuG,KAAKwpC,EAEnB,CACA,IAAK,MAAMA,KAAKykE,EACdlyG,KAAKwxG,mBAAmB/jE,EAE5B,0BAGF,MAAM8iE,UAAmBnxG,EAAAy8C,gBAavB,sBAAWlM,GAQT,OAPuB,OAAnB3vC,KAAKmyG,YACHnyG,KAAKkJ,QAAQgoB,gBACflxB,KAAKmyG,UAAY5kG,EAAA9E,IAAIqK,QAAQ9S,KAAKkJ,QAAQgoB,iBAE1ClxB,KAAKmyG,eAAYvtG,GAGd5E,KAAKmyG,SACd,CAGA,sBAAWviE,GAQT,OAPuB,OAAnB5vC,KAAKoyG,YACHpyG,KAAKkJ,QAAQmpG,gBACfryG,KAAKoyG,UAAY7kG,EAAA9E,IAAIqK,QAAQ9S,KAAKkJ,QAAQmpG,iBAE1CryG,KAAKoyG,eAAYxtG,GAGd5E,KAAKoyG,SACd,CAEA,WAAA1yG,CACkBwJ,GAEhBnJ,QAFgBC,KAAAkJ,QAAAA,EA9BFlJ,KAAAg0B,gBAAkBh0B,KAAKW,IAAI,IAAIqN,EAAAsB,SAC/BtP,KAAAmC,SAAWnC,KAAKg0B,gBAAgBzlB,MAC/BvO,KAAA+2F,WAAa/2F,KAAKW,IAAI,IAAIqN,EAAAsB,SAC3BtP,KAAAi0B,UAAYj0B,KAAK+2F,WAAWxoF,MAEpCvO,KAAAmyG,UAAuC,KAYvCnyG,KAAAoyG,UAAuC,KAgB7CpyG,KAAK8zB,OAAS5qB,EAAQ4qB,OACtB9zB,KAAKuxG,kBAAoBroG,EAAQ4qB,OAAOvvB,KACpCvE,KAAKkJ,QAAQ2rB,uBAAyB70B,KAAKkJ,QAAQ2rB,qBAAqB5vB,WAC1EjF,KAAKkJ,QAAQ2rB,qBAAqB5vB,SAAW,OAEjD,CAEgB,OAAAoU,GACdrZ,KAAK+2F,WAAW9lF,OAChBlR,MAAMsZ,SACR,mHCpXF,MAAAha,EAAAH,EAAA,MACAioE,EAAAjoE,EAAA,MAEA,MAAAozG,EAIE,WAAA5yG,IAAemnB,GAFP7mB,KAAAuyG,SAAW,IAAI9tF,IAGrB,IAAK,MAAO0V,EAAIq4E,KAAY3rF,EAC1B7mB,KAAK8E,IAAIq1B,EAAIq4E,EAEjB,CAEO,GAAA1tG,CAAOq1B,EAA2BkzE,GACvC,MAAMruF,EAAShf,KAAKuyG,SAASzuG,IAAIq2B,GAEjC,OADAn6B,KAAKuyG,SAASztG,IAAIq1B,EAAIkzE,GACfruF,CACT,CAEO,OAAAwH,CAAQ8D,GACb,IAAK,MAAOrnB,EAAKwH,KAAUzK,KAAKuyG,SAAS1rF,UACvCyD,EAASrnB,EAAKwH,EAElB,CAEO,GAAAod,CAAIsS,GACT,OAAOn6B,KAAKuyG,SAAS1qF,IAAIsS,EAC3B,CAEO,GAAAr2B,CAAOq2B,GACZ,OAAOn6B,KAAKuyG,SAASzuG,IAAIq2B,EAC3B,+CAGF,MAKE,WAAAz6B,GAFiBM,KAAAyyG,UAA+B,IAAIH,EAGlDtyG,KAAKyyG,UAAU3tG,IAAIzF,EAAAoK,sBAAuBzJ,KAC5C,CAEO,UAAAqQ,CAAc8pB,EAA2BkzE,GAC9CrtG,KAAKyyG,UAAU3tG,IAAIq1B,EAAIkzE,EACzB,CAEO,UAAAqF,CAAcv4E,GACnB,OAAOn6B,KAAKyyG,UAAU3uG,IAAIq2B,EAC5B,CAEO,cAAAhqB,CAAkBwiG,KAAc3+C,GACrC,MAAM4+C,GAAsB,EAAAzrC,EAAA0rC,wBAAuBF,GAAMnwF,KAAK,CAAC3jB,EAAG0lB,IAAM1lB,EAAEwT,MAAQkS,EAAElS,OAE9EygG,EAAqB,GAC3B,IAAK,MAAMC,KAAcH,EAAqB,CAC5C,MAAMJ,EAAUxyG,KAAKyyG,UAAU3uG,IAAIivG,EAAW54E,IAC9C,IAAKq4E,EACH,MAAM,IAAIzwG,MAAM,oBAAoB4wG,EAAKh3D,mCAAmCo3D,EAAW54E,GAAG08D,QAE5Fic,EAAY7uG,KAAKuuG,EACnB,CAEA,MAAMQ,EAAqBJ,EAAoBrxG,OAAS,EAAIqxG,EAAoB,GAAGvgG,MAAQ2hD,EAAKzyD,OAGhG,GAAIyyD,EAAKzyD,SAAWyxG,EAClB,MAAM,IAAIjxG,MAAM,gDAAgD4wG,EAAKh3D,oBAAoBq3D,EAAqB,oBAAoBh/C,EAAKzyD,2BAIzI,OAAO,IAAIoxG,KAAQ,IAAI3+C,KAAS8+C,GAClC,0fC9EF,MAAA1zG,EAAAF,EAAA,MACAG,EAAAH,EAAA,MAgBM+zG,EAAwD,CAC5Dn0B,MAAOz/E,EAAA2yE,aAAa6M,MACpB9nE,MAAO1X,EAAA2yE,aAAa2M,MACpBu0B,KAAM7zG,EAAA2yE,aAAamhC,KACnBprG,KAAM1I,EAAA2yE,aAAaC,KACnBvrE,MAAOrH,EAAA2yE,aAAaohC,MACpBC,IAAKh0G,EAAA2yE,aAAashC,KAKb,IAAM9iC,EAAN,cAAyBpxE,EAAAK,WAI9B,YAAWg+D,GAA2B,OAAOz9D,KAAKuzG,SAAW,CAE7D,WAAA7zG,CACoCwqB,GAElCnqB,QAFkCC,KAAAkqB,gBAAAA,EAJ5BlqB,KAAAuzG,UAA0Bl0G,EAAA2yE,aAAashC,IAO7CtzG,KAAKwzG,kBACLxzG,KAAK0B,UAAU1B,KAAKkqB,gBAAgBzS,uBAAuB,WAAY,IAAMzX,KAAKwzG,mBACpF,CAEQ,eAAAA,GACNxzG,KAAKuzG,UAAYN,EAAqBjzG,KAAKkqB,gBAAgB5f,WAAWmzD,SACxE,CAEQ,uBAAAg2C,CAAwBC,GAC9B,IAAK,IAAI50G,EAAI,EAAGA,EAAI40G,EAAenyG,OAAQzC,IACR,mBAAtB40G,EAAe50G,KACxB40G,EAAe50G,GAAK40G,EAAe50G,KAGzC,CAEQ,IAAA60G,CAAKniG,EAAeoiG,EAAiBF,GAC3C1zG,KAAKyzG,wBAAwBC,GAC7BliG,EAAK8hE,KAAK7sE,SAAUzG,KAAKkqB,gBAAgBhhB,QAAQ2qG,OAAS,GA9B3C,cA8B8DD,KAAYF,EAC3F,CAEO,KAAA50B,CAAM80B,KAAoBF,GAC3B1zG,KAAKuzG,WAAal0G,EAAA2yE,aAAa6M,OACjC7+E,KAAK2zG,KAAK3zG,KAAKkqB,gBAAgBhhB,QAAQ2qG,QAAQ/0B,MAAMj9E,KAAK7B,KAAKkqB,gBAAgBhhB,QAAQ2qG,SAAWptG,QAAQqtG,IAAKF,EAASF,EAE5H,CAEO,KAAA38F,CAAM68F,KAAoBF,GAC3B1zG,KAAKuzG,WAAal0G,EAAA2yE,aAAa2M,OACjC3+E,KAAK2zG,KAAK3zG,KAAKkqB,gBAAgBhhB,QAAQ2qG,QAAQ98F,MAAMlV,KAAK7B,KAAKkqB,gBAAgBhhB,QAAQ2qG,SAAWptG,QAAQqtG,IAAKF,EAASF,EAE5H,CAEO,IAAAR,CAAKU,KAAoBF,GAC1B1zG,KAAKuzG,WAAal0G,EAAA2yE,aAAamhC,MACjCnzG,KAAK2zG,KAAK3zG,KAAKkqB,gBAAgBhhB,QAAQ2qG,QAAQX,KAAKrxG,KAAK7B,KAAKkqB,gBAAgBhhB,QAAQ2qG,SAAWptG,QAAQysG,KAAMU,EAASF,EAE5H,CAEO,IAAA3rG,CAAK6rG,KAAoBF,GAC1B1zG,KAAKuzG,WAAal0G,EAAA2yE,aAAaC,MACjCjyE,KAAK2zG,KAAK3zG,KAAKkqB,gBAAgBhhB,QAAQ2qG,QAAQ9rG,KAAKlG,KAAK7B,KAAKkqB,gBAAgBhhB,QAAQ2qG,SAAWptG,QAAQsB,KAAM6rG,EAASF,EAE5H,CAEO,KAAAhtG,CAAMktG,KAAoBF,GAC3B1zG,KAAKuzG,WAAal0G,EAAA2yE,aAAaohC,OACjCpzG,KAAK2zG,KAAK3zG,KAAKkqB,gBAAgBhhB,QAAQ2qG,QAAQntG,MAAM7E,KAAK7B,KAAKkqB,gBAAgBhhB,QAAQ2qG,SAAWptG,QAAQC,MAAOktG,EAASF,EAE9H,+BA3DWljC,EAAUjnE,EAAA,CAOlBC,EAAA,EAAAnK,EAAA0tB,kBAPQyjD,4FC3Bb,MAAApxE,EAAAF,EAAA,MACA8O,EAAA9O,EAAA,MAKM60G,EAA2D,CAM/DC,KAAM,CACJ13C,OAAM,EACN23C,SAAU,KAAM,GAOlBC,IAAK,CACH53C,OAAM,EACN23C,SAAW9yG,GAEG,IAARA,EAAEyU,QAA4C,IAARzU,EAAE07D,SAI5C17D,EAAEg8D,MAAO,EACTh8D,EAAEiyB,KAAM,EACRjyB,EAAEwC,OAAQ,GACH,IAQXwwG,MAAO,CACL73C,OAAQ,GACR23C,SAAW9yG,GAEG,KAARA,EAAE07D,QAWVu3C,KAAM,CACJ93C,OAAQ,GACR23C,SAAW9yG,GAEG,KAARA,EAAE07D,QAA2C,IAAR17D,EAAEyU,QAW/Cy+F,IAAK,CACH/3C,OACE,GAEF23C,SAAW9yG,IAAuB,IAWtC,SAASmzG,EAAUnzG,EAAoBozG,GACrC,IAAIv5E,GAAQ75B,EAAEg8D,KAAM,GAAkB,IAAMh8D,EAAEwC,MAAO,EAAmB,IAAMxC,EAAEiyB,IAAK,EAAiB,GAoBtG,OAnBY,IAARjyB,EAAEyU,QACJolB,GAAQ,GACRA,GAAQ75B,EAAE07D,SAEV7hC,GAAmB,EAAX75B,EAAEyU,OACK,EAAXzU,EAAEyU,SACJolB,GAAQ,IAEK,EAAX75B,EAAEyU,SACJolB,GAAQ,KAEE,KAAR75B,EAAE07D,OACJ7hC,GAAI,GACa,IAAR75B,EAAE07D,QAAkC03C,IAG7Cv5E,GAAI,IAGDA,CACT,CAEA,MAAMw5E,EAAIp0F,OAAOC,aAKXo0F,EAA0D,CAM9DC,QAAUvzG,IACR,MAAM02E,EAAS,CAACy8B,EAAUnzG,GAAG,GAAS,GAAIA,EAAEm6D,IAAM,GAAIn6D,EAAEyG,IAAM,IAK9D,OAAIiwE,EAAO,GAAK,KAAOA,EAAO,GAAK,KAAOA,EAAO,GAAK,IAC7C,GAEF,MAAS28B,EAAE38B,EAAO,MAAM28B,EAAE38B,EAAO,MAAM28B,EAAE38B,EAAO,OAOzD88B,IAAMxzG,IACJ,MAAM6xE,EAAiB,IAAR7xE,EAAE07D,QAAyC,IAAR17D,EAAEyU,OAAoC,IAAM,IAC9F,MAAO,MAAS0+F,EAAUnzG,GAAG,MAASA,EAAEm6D,OAAOn6D,EAAEyG,MAAMorE,KAEzD4hC,WAAazzG,IACX,MAAM6xE,EAAiB,IAAR7xE,EAAE07D,QAAyC,IAAR17D,EAAEyU,OAAoC,IAAM,IAC9F,MAAO,MAAS0+F,EAAUnzG,GAAG,MAASA,EAAE0T,KAAK1T,EAAEgT,IAAI6+D,MAoBvD,MAAArC,UAAuCvxE,EAAAK,WAYrC,WAAAC,GACEK,QAVMC,KAAA60G,WAAqD,GACrD70G,KAAA80G,WAAoD,GACpD90G,KAAA+0G,gBAA0B,GAC1B/0G,KAAAg1G,gBAA0B,GAGjBh1G,KAAAi1G,kBAAoBj1G,KAAK0B,UAAU,IAAIsM,EAAAsB,SACxCtP,KAAA6wB,iBAAmB7wB,KAAKi1G,kBAAkB1mG,MAMxD,IAAK,MAAMotC,KAAQ/yC,OAAOipD,KAAKkiD,GAAoB/zG,KAAKk1G,YAAYv5D,EAAMo4D,EAAkBp4D,IAC5F,IAAK,MAAMA,KAAQ/yC,OAAOipD,KAAK4iD,GAAoBz0G,KAAKm1G,YAAYx5D,EAAM84D,EAAkB94D,IAE5F37C,KAAKsR,OACP,CAEO,WAAA4jG,CAAYv5D,EAAcjwB,GAC/B1rB,KAAK60G,WAAWl5D,GAAQjwB,CAC1B,CAEO,WAAAypF,CAAYx5D,EAAcy5D,GAC/Bp1G,KAAK80G,WAAWn5D,GAAQy5D,CAC1B,CAEA,kBAAWtyE,GACT,OAAO9iC,KAAK+0G,eACd,CAEA,wBAAW15F,GACT,OAAwD,IAAjDrb,KAAK60G,WAAW70G,KAAK+0G,iBAAiBz4C,MAC/C,CAEA,kBAAWx5B,CAAe6Y,GACxB,IAAK37C,KAAK60G,WAAWl5D,GACnB,MAAM,IAAI55C,MAAM,qBAAqB45C,MAEvC37C,KAAK+0G,gBAAkBp5D,EACvB37C,KAAKi1G,kBAAkBhkG,KAAKjR,KAAK60G,WAAWl5D,GAAM2gB,OACpD,CAEA,kBAAW8mB,GACT,OAAOpjF,KAAKg1G,eACd,CAEA,kBAAW5xB,CAAeznC,GACxB,IAAK37C,KAAK80G,WAAWn5D,GACnB,MAAM,IAAI55C,MAAM,qBAAqB45C,MAEvC37C,KAAKg1G,gBAAkBr5D,CACzB,CAEO,KAAArqC,GACLtR,KAAK8iC,eAAiB,OACtB9iC,KAAKojF,eAAiB,SACxB,CAEO,0BAAA9lE,CAA2BD,GAChCrd,KAAKq1G,yBAA2Bh4F,CAClC,CAEO,qBAAA0/C,CAAsBpyD,GAC3B,OAAO3K,KAAKq1G,2BAAiE,IAAtCr1G,KAAKq1G,yBAAyB1qG,EACvE,CAEO,kBAAAuzD,CAAmB/8D,GACxB,OAAOnB,KAAK60G,WAAW70G,KAAK+0G,iBAAiBd,SAAS9yG,EACxD,CAEO,gBAAAi9D,CAAiBj9D,GACtB,OAAOnB,KAAK80G,WAAW90G,KAAKg1G,iBAAiB7zG,EAC/C,CAEA,qBAAWk9D,GACT,MAAgC,YAAzBr+D,KAAKg1G,eACd,CAEA,mBAAW/2C,GACT,MAAgC,eAAzBj+D,KAAKg1G,eACd,8HCvPF,MAAA51G,EAAAF,EAAA,MACAk7D,EAAAl7D,EAAA,KAGA8O,EAAA9O,EAAA,MAEaT,EAAA62G,gBAAwD,CACnErtG,KAAM,GACNlH,KAAM,GACN4uG,uBAAuB,EACvB1lE,aAAa,EACbmJ,sBAAuB,EACvBlJ,YAAa,QACbzC,YAAa,EACb0C,oBAAqB,UACrBwE,4BAA4B,EAC5Bv3B,iBAAkB,KAClBgb,sBAAuB,EACvB0L,WAAY,YACZ70B,SAAU,GACV49B,WAAY,SACZC,eAAgB,OAChBv8B,0BAA0B,EAC1B4K,WAAY,EACZ6xB,cAAe,EACfzc,YAAa,KACbkzC,SAAU,OACVo2C,OAAQ,KACRzlB,WAAY,IACZzyE,UAAW,CAAED,eAAe,GAC5BumE,wBAAwB,EACxBljE,mBAAmB,EACnBoT,kBAAmB,EACnB1W,kBAAkB,EAClBqU,qBAAsB,EACtBlR,iBAAiB,EACjB4lD,+BAA+B,EAC/Bv0B,qBAAsB,EACtB30B,uBAAuB,EACvBpD,cAAc,EACd8pB,kBAAkB,EAClBxqB,mBAAmB,EACnBq6E,aAAc,EACdrpB,MAAO,GACP6mB,kBAAkB,EAClBkmB,0BAA0B,EAC1Bz/F,sBAAuBskD,EAAAz7C,MACvBw8D,cAAe,GACfzI,WAAY,GACZ5L,cAAe,eACfvB,qBAAqB,EACrBwb,YAAY,EACZgC,SAAU,QACVG,OAAQ,GACRloB,aAAc,IAGhB,MAAMw6C,EAAqD,CAAC,SAAU,OAAQ,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAEtI,MAAAjlC,UAAoCnxE,EAAAK,WASlC,WAAAC,CAAYwJ,GACVnJ,QAJeC,KAAAy1G,gBAAkBz1G,KAAK0B,UAAU,IAAIsM,EAAAsB,SACtCtP,KAAA4lC,eAAiB5lC,KAAKy1G,gBAAgBlnG,MAKpD,MAAMmnG,EAAiB,IAAKj3G,EAAA62G,iBAC5B,IAAK,MAAMryG,KAAOiG,EAChB,GAAIjG,KAAOyyG,EACT,IACE,MAAM93E,EAAW10B,EAAQjG,GACzByyG,EAAezyG,GAAOjD,KAAK21G,2BAA2B1yG,EAAK26B,EAC7D,CAAE,MAAOz8B,GACPsF,QAAQC,MAAMvF,EAChB,CAKJnB,KAAKsK,WAAaorG,EAClB11G,KAAKkJ,QAAU,IAAMwsG,GACrB11G,KAAK41G,gBAIL51G,KAAK0B,WAAU,EAAAtC,EAAAqE,cAAa,KAC1BzD,KAAKsK,WAAWigB,YAAc,KAC9BvqB,KAAKsK,WAAW8M,iBAAmB,OAEvC,CAGO,sBAAAK,CAAyDxU,EAAQ6xD,GACtE,OAAO90D,KAAK4lC,eAAeiwE,IACrBA,IAAa5yG,GACf6xD,EAAS90D,KAAKsK,WAAWrH,KAG/B,CAGO,sBAAA0tB,CAAuBkhC,EAAkCiD,GAC9D,OAAO90D,KAAK4lC,eAAeiwE,KACO,IAA5BhkD,EAAKsJ,QAAQ06C,IACf/gD,KAGN,CAEQ,aAAA8gD,GACN,MAAMn0E,EAAUC,IACd,KAAMA,KAAYjjC,EAAA62G,iBAChB,MAAM,IAAIvzG,MAAM,uBAAuB2/B,MAEzC,OAAO1hC,KAAKsK,WAAWo3B,IAGnBC,EAAS,CAACD,EAAkBj3B,KAChC,KAAMi3B,KAAYjjC,EAAA62G,iBAChB,MAAM,IAAIvzG,MAAM,uBAAuB2/B,MAGzCj3B,EAAQzK,KAAK21G,2BAA2Bj0E,EAAUj3B,GAE9CzK,KAAKsK,WAAWo3B,KAAcj3B,IAChCzK,KAAKsK,WAAWo3B,GAAYj3B,EAC5BzK,KAAKy1G,gBAAgBxkG,KAAKywB,KAI9B,IAAK,MAAMA,KAAY1hC,KAAKsK,WAAY,CACtC,MAAMu3B,EAAO,CACX/9B,IAAK29B,EAAO5/B,KAAK7B,KAAM0hC,GACvB58B,IAAK68B,EAAO9/B,KAAK7B,KAAM0hC,IAEzB94B,OAAOk5B,eAAe9hC,KAAKkJ,QAASw4B,EAAUG,EAChD,CACF,CAEQ,0BAAA8zE,CAA2B1yG,EAAawH,GAC9C,OAAQxH,GACN,IAAK,cAIH,GAHKwH,IACHA,EAAQhM,EAAA62G,gBAAgBryG,KA+DlC,SAAuBwH,GACrB,MAAiB,UAAVA,GAA+B,cAAVA,GAAmC,QAAVA,CACvD,CA/DaqrG,CAAcrrG,GACjB,MAAM,IAAI1I,MAAM,IAAI0I,+BAAmCxH,KAEzD,MACF,IAAK,gBACEwH,IACHA,EAAQhM,EAAA62G,gBAAgBryG,IAE1B,MACF,IAAK,aACL,IAAK,iBACH,GAAqB,iBAAVwH,GAAsB,GAAKA,GAASA,GAAS,IAEtD,MAEFA,EAAQ+qG,EAAoB/pF,SAAShhB,GAASA,EAAQhM,EAAA62G,gBAAgBryG,GACtE,MACF,IAAK,wBAEH,IADAwH,EAAQkK,KAAKkiB,MAAMpsB,IACP,EACV,MAAM,IAAI1I,MAAM,GAAGkB,mCAAqCwH,KAE1D,MACF,IAAK,cACHA,EAAQkK,KAAKkiB,MAAMpsB,GAErB,IAAK,aACL,IAAK,eACH,GAAIA,EAAQ,EACV,MAAM,IAAI1I,MAAM,GAAGkB,mCAAqCwH,KAE1D,MACF,IAAK,uBACHA,EAAQkK,KAAKkZ,IAAI,EAAGlZ,KAAKC,IAAI,GAAID,KAAK6d,MAAc,GAAR/nB,GAAc,KAC1D,MACF,IAAK,aAEH,IADAA,EAAQkK,KAAKC,IAAInK,EAAO,aACZ,EACV,MAAM,IAAI1I,MAAM,GAAGkB,mCAAqCwH,KAE1D,MACF,IAAK,wBACL,IAAK,oBACH,GAAIA,GAAS,EACX,MAAM,IAAI1I,MAAM,GAAGkB,+CAAiDwH,KAEtE,MACF,IAAK,OACL,IAAK,OACH,IAAKA,GAAmB,IAAVA,EACZ,MAAM,IAAI1I,MAAM,GAAGkB,6BAA+BwH,KAEpD,MACF,IAAK,aACHA,EAAQA,GAAS,GAGrB,OAAOA,CACT,ghBCjNF,MAAApL,EAAAH,EAAA,MAIO,IAAMiyE,EAAN,MAiBL,WAAAzxE,CACmCoS,GAAA9R,KAAA8R,eAAAA,EAf3B9R,KAAA82F,QAAU,EAKV92F,KAAA+1G,eAAmD,IAAItxF,IAOvDzkB,KAAAg2G,cAAsE,IAAIvxF,GAKlF,CAEO,YAAAgiE,CAAaxpE,GAClB,MAAM9Y,EAASnE,KAAK8R,eAAe3N,OAGnC,QAAgBS,IAAZqY,EAAKkd,GAAkB,CACzB,MAAMrG,EAAS3vB,EAAO8Z,UAAU9Z,EAAOqQ,MAAQrQ,EAAOgQ,GAChD8sD,EAA2B,CAC/BhkD,OACAkd,GAAIn6B,KAAK82F,UACTzyF,MAAO,CAACyvB,IAIV,OAFAA,EAAOG,UAAU,IAAMj0B,KAAKi2G,sBAAsBh1C,EAAOntC,IACzD9zB,KAAKg2G,cAAclxG,IAAIm8D,EAAM9mC,GAAI8mC,GAC1BA,EAAM9mC,EACf,CAGA,MAAM+7E,EAAWj5F,EACXha,EAAMjD,KAAKm2G,eAAeD,GAC1B91D,EAAQpgD,KAAK+1G,eAAejyG,IAAIb,GACtC,GAAIm9C,EAEF,OADApgD,KAAKmgF,cAAc//B,EAAMjmB,GAAIh2B,EAAOqQ,MAAQrQ,EAAOgQ,GAC5CisC,EAAMjmB,GAIf,MAAMrG,EAAS3vB,EAAO8Z,UAAU9Z,EAAOqQ,MAAQrQ,EAAOgQ,GAChD8sD,EAA6B,CACjC9mC,GAAIn6B,KAAK82F,UACT7zF,IAAKjD,KAAKm2G,eAAeD,GACzBj5F,KAAMi5F,EACN7xG,MAAO,CAACyvB,IAKV,OAHAA,EAAOG,UAAU,IAAMj0B,KAAKi2G,sBAAsBh1C,EAAOntC,IACzD9zB,KAAK+1G,eAAejxG,IAAIm8D,EAAMh+D,IAAKg+D,GACnCjhE,KAAKg2G,cAAclxG,IAAIm8D,EAAM9mC,GAAI8mC,GAC1BA,EAAM9mC,EACf,CAEO,aAAAgmD,CAAcv0D,EAAgBzX,GACnC,MAAM8sD,EAAQjhE,KAAKg2G,cAAclyG,IAAI8nB,GACrC,GAAKq1C,GAGDA,EAAM58D,MAAM+xG,MAAMj1G,GAAKA,EAAEoD,OAAS4P,GAAI,CACxC,MAAM2f,EAAS9zB,KAAK8R,eAAe3N,OAAO8Z,UAAU9J,GACpD8sD,EAAM58D,MAAMJ,KAAK6vB,GACjBA,EAAOG,UAAU,IAAMj0B,KAAKi2G,sBAAsBh1C,EAAOntC,GAC3D,CACF,CAEO,WAAA5I,CAAYU,GACjB,OAAO5rB,KAAKg2G,cAAclyG,IAAI8nB,IAAS3O,IACzC,CAEQ,cAAAk5F,CAAeE,GACrB,MAAO,GAAGA,EAASl8E,OAAOk8E,EAASlrF,KACrC,CAEQ,qBAAA8qF,CAAsBh1C,EAAgDntC,GAC5E,MAAMzhB,EAAQ4uD,EAAM58D,MAAM82D,QAAQrnC,IACnB,IAAXzhB,IAGJ4uD,EAAM58D,MAAMyjB,OAAOzV,EAAO,GACC,IAAvB4uD,EAAM58D,MAAM9C,cACQqD,IAAlBq8D,EAAMhkD,KAAKkd,IACbn6B,KAAK+1G,eAAe7hF,OAAQ+sC,EAA8Bh+D,KAE5DjD,KAAKg2G,cAAc9hF,OAAO+sC,EAAM9mC,KAEpC,uCA7FWg3C,EAAc5nE,EAAA,CAkBtBC,EAAA,EAAAnK,EAAAyqB,iBAlBQqnD,iHCgBb,SAAuCwhC,GACrC,OAAOA,EAAI,iBAA+B,EAC5C,oBAEA,SAAmCx4E,GACjC,GAAI17B,EAAA63G,gBAAgBzuF,IAAIsS,GACtB,OAAO17B,EAAA63G,gBAAgBxyG,IAAIq2B,GAG7B,MAAMo8E,EAAiB,SAAUpxG,EAAkBlC,EAAaoP,GAC9D,GAAyB,IAArBmkG,UAAUj1G,OACZ,MAAM,IAAIQ,MAAM,qEAYtB,SAAgCo4B,EAAch1B,EAAkBkN,GACzDlN,EAAc,YAA0BA,EAC1CA,EAAc,gBAA4BlB,KAAK,CAAEk2B,KAAI9nB,WAErDlN,EAAc,gBAA8B,CAAC,CAAEg1B,KAAI9nB,UACnDlN,EAAc,UAAwBA,EAE3C,CAhBIsxG,CAAuBF,EAAWpxG,EAAQkN,EAC5C,EAKA,OAHAkkG,EAAU1f,IAAM18D,EAEhB17B,EAAA63G,gBAAgBxxG,IAAIq1B,EAAIo8E,GACjBA,CACT,EAvBa93G,EAAA63G,gBAAwD,IAAI7xF,gRCdzE,MAAA0iD,EAAAjoE,EAAA,MAkIA,IAAY8yE,EA/HCvzE,EAAAqrB,gBAAiB,EAAAq9C,EAAAC,iBAAgC,iBAwBjD3oE,EAAAm0B,oBAAqB,EAAAu0C,EAAAC,iBAAoC,qBAuBzD3oE,EAAAk0B,cAAe,EAAAw0C,EAAAC,iBAA8B,eAuC7C3oE,EAAAyyE,iBAAkB,EAAA/J,EAAAC,iBAAiC,kBAgCnD3oE,EAAAgL,uBAAwB,EAAA09D,EAAAC,iBAAuC,wBAS5E,SAAY4K,GACVA,EAAAA,EAAA,iBACAA,EAAAA,EAAA,iBACAA,EAAAA,EAAA,eACAA,EAAAA,EAAA,eACAA,EAAAA,EAAA,iBACAA,EAAAA,EAAA,YACD,CAPD,CAAYA,IAAYvzE,EAAAuzE,aAAZA,EAAY,KASXvzE,EAAAmgE,aAAc,EAAAuI,EAAAC,iBAA6B,cAa3C3oE,EAAAsuB,iBAAkB,EAAAo6C,EAAAC,iBAAiC,kBAgJnD3oE,EAAAuuB,iBAAkB,EAAAm6C,EAAAC,iBAAiC,kBAuCnD3oE,EAAAsyE,iBAAkB,EAAA5J,EAAAC,iBAAiC,kBA+BnD3oE,EAAA6R,oBAAqB,EAAA62D,EAAAC,iBAAoC,2GChXtE,MAAAp5D,EAAA9O,EAAA,MAEA,MAAA2xE,EAAA,WAAAnxE,GAGUM,KAAA02G,WAAuD9tG,OAAOo+F,OAAO,MACrEhnG,KAAAinG,QAAkB,GAGTjnG,KAAA22G,UAAY,IAAI3oG,EAAAsB,QACjBtP,KAAA42G,SAAW52G,KAAK22G,UAAUpoG,KAyF5C,CAvFS,wBAAO0xE,CAAkBx1E,GAC9B,SAAgB,EAARA,EACV,CACO,mBAAOs1E,CAAat1E,GACzB,OAASA,GAAS,EAAK,CACzB,CACO,sBAAOosG,CAAgBpsG,GAC5B,OAAOA,GAAS,CAClB,CACO,0BAAOi2F,CAAoB3+E,EAAehZ,EAAei3E,GAAsB,GACpF,OAAiB,SAARj+D,IAAqB,GAAe,EAARhZ,IAAc,GAAMi3E,EAAW,EAAE,EACxE,CAEO,OAAA3mE,GACLrZ,KAAK22G,UAAUt9F,SACjB,CAEA,YAAWu1F,GACT,OAAOhmG,OAAOipD,KAAK7xD,KAAK02G,WAC1B,CAEA,iBAAW7H,GACT,OAAO7uG,KAAKinG,OACd,CAEA,iBAAW4H,CAAczO,GACvB,IAAKpgG,KAAK02G,WAAWtW,GACnB,MAAM,IAAIr+F,MAAM,4BAA4Bq+F,MAE9CpgG,KAAKinG,QAAU7G,EACfpgG,KAAK82G,gBAAkB92G,KAAK02G,WAAWtW,GACvCpgG,KAAK22G,UAAU1lG,KAAKmvF,EACtB,CAEO,QAAAziF,CAASgxF,GACd3uG,KAAK02G,WAAW/H,EAASvO,SAAWuO,EAC/B3uG,KAAKinG,UACRjnG,KAAK6uG,cAAgBF,EAASvO,QAElC,CAKO,OAAAC,CAAQC,GACb,OAAOtgG,KAAK82G,gBAAgBzW,QAAQC,EACtC,CAEO,kBAAAyW,CAAmBnqC,GACxB,IAAI5tD,EAAS,EACTg4F,EAAgB,EACpB,MAAMz1G,EAASqrE,EAAErrE,OACjB,IAAK,IAAIzC,EAAI,EAAGA,EAAIyC,IAAUzC,EAAG,CAC/B,IAAIk8B,EAAO4xC,EAAEntD,WAAW3gB,GAExB,GAAI,OAAUk8B,GAAQA,GAAQ,MAAQ,CACpC,KAAMl8B,GAAKyC,EAMT,OAAOyd,EAAShf,KAAKqgG,QAAQrlE,GAE/B,MAAMyqD,EAAS7Y,EAAEntD,WAAW3gB,GAGxB,OAAU2mF,GAAUA,GAAU,MAChCzqD,EAAyB,MAAjBA,EAAO,OAAkByqD,EAAS,MAAS,MAEnDzmE,GAAUhf,KAAKqgG,QAAQ5a,EAE3B,CACA,MAAM5F,EAAc7/E,KAAK8/E,eAAe9kD,EAAMg8E,GAC9C,IAAI33B,EAAUxO,EAAekP,aAAaF,GACtChP,EAAeoP,kBAAkBJ,KACnCR,GAAWxO,EAAekP,aAAai3B,IAEzCh4F,GAAUqgE,EACV23B,EAAgBn3B,CAClB,CACA,OAAO7gE,CACT,CAEO,cAAA8gE,CAAe3tC,EAAmBsuD,GACvC,OAAOzgG,KAAK82G,gBAAgBh3B,eAAe3tC,EAAWsuD,EACxD,uBCvGFwW,EAAA,UAGA,SAAA/3G,EAAAg4G,GAEA,IAAAC,EAAAF,EAAAC,GACA,QAAAtyG,IAAAuyG,EACA,OAAAA,EAAA14G,QAGA,IAAAC,EAAAu4G,EAAAC,GAAA,CAGAz4G,QAAA,IAOA,OAHA24G,EAAAF,GAAA5jC,KAAA50E,EAAAD,QAAAC,EAAAA,EAAAD,QAAAS,GAGAR,EAAAD,OACA,CCnBAS,CAAA","sources":["webpack://@xterm/xterm/webpack/universalModuleDefinition","webpack://@xterm/xterm/./src/browser/AccessibilityManager.ts","webpack://@xterm/xterm/./src/browser/Clipboard.ts","webpack://@xterm/xterm/./src/browser/ColorContrastCache.ts","webpack://@xterm/xterm/./src/browser/CoreBrowserTerminal.ts","webpack://@xterm/xterm/./src/browser/Dom.ts","webpack://@xterm/xterm/./src/browser/Linkifier.ts","webpack://@xterm/xterm/./src/browser/LocalizableStrings.ts","webpack://@xterm/xterm/./src/browser/OscLinkProvider.ts","webpack://@xterm/xterm/./src/browser/RenderDebouncer.ts","webpack://@xterm/xterm/./src/browser/TimeBasedDebouncer.ts","webpack://@xterm/xterm/./src/browser/Types.ts","webpack://@xterm/xterm/./src/browser/Viewport.ts","webpack://@xterm/xterm/./src/browser/decorations/BufferDecorationRenderer.ts","webpack://@xterm/xterm/./src/browser/decorations/ColorZoneStore.ts","webpack://@xterm/xterm/./src/browser/decorations/OverviewRulerRenderer.ts","webpack://@xterm/xterm/./src/browser/input/CompositionHelper.ts","webpack://@xterm/xterm/./src/browser/input/Mouse.ts","webpack://@xterm/xterm/./src/browser/input/MoveToCell.ts","webpack://@xterm/xterm/./src/browser/public/Terminal.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRenderer.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRendererRowFactory.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/WidthCache.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/Constants.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/RendererUtils.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/SelectionRenderModel.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/TextBlinkStateManager.ts","webpack://@xterm/xterm/./src/browser/scrollable/abstractScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/fastDomNode.ts","webpack://@xterm/xterm/./src/browser/scrollable/globalPointerMoveMonitor.ts","webpack://@xterm/xterm/./src/browser/scrollable/horizontalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/mouseEvent.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollable.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollableElement.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarArrow.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarState.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarVisibilityController.ts","webpack://@xterm/xterm/./src/browser/scrollable/touch.ts","webpack://@xterm/xterm/./src/browser/scrollable/verticalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/widget.ts","webpack://@xterm/xterm/./src/browser/selection/SelectionModel.ts","webpack://@xterm/xterm/./src/browser/services/CharSizeService.ts","webpack://@xterm/xterm/./src/browser/services/CharacterJoinerService.ts","webpack://@xterm/xterm/./src/browser/services/CoreBrowserService.ts","webpack://@xterm/xterm/./src/browser/services/KeyboardService.ts","webpack://@xterm/xterm/./src/browser/services/LinkProviderService.ts","webpack://@xterm/xterm/./src/browser/services/MouseCoordsService.ts","webpack://@xterm/xterm/./src/browser/services/MouseService.ts","webpack://@xterm/xterm/./src/browser/services/RenderService.ts","webpack://@xterm/xterm/./src/browser/services/SelectionService.ts","webpack://@xterm/xterm/./src/browser/services/Services.ts","webpack://@xterm/xterm/./src/browser/services/ThemeService.ts","webpack://@xterm/xterm/./src/common/Async.ts","webpack://@xterm/xterm/./src/common/CircularList.ts","webpack://@xterm/xterm/./src/common/Color.ts","webpack://@xterm/xterm/./src/common/CoreTerminal.ts","webpack://@xterm/xterm/./src/common/Event.ts","webpack://@xterm/xterm/./src/common/InputHandler.ts","webpack://@xterm/xterm/./src/common/Lifecycle.ts","webpack://@xterm/xterm/./src/common/MultiKeyMap.ts","webpack://@xterm/xterm/./src/common/Platform.ts","webpack://@xterm/xterm/./src/common/SortedList.ts","webpack://@xterm/xterm/./src/common/StringBuilder.ts","webpack://@xterm/xterm/./src/common/TaskQueue.ts","webpack://@xterm/xterm/./src/common/Version.ts","webpack://@xterm/xterm/./src/common/WindowsMode.ts","webpack://@xterm/xterm/./src/common/buffer/AttributeData.ts","webpack://@xterm/xterm/./src/common/buffer/Buffer.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLine.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLineStringCache.ts","webpack://@xterm/xterm/./src/common/buffer/BufferRange.ts","webpack://@xterm/xterm/./src/common/buffer/BufferReflow.ts","webpack://@xterm/xterm/./src/common/buffer/BufferSet.ts","webpack://@xterm/xterm/./src/common/buffer/CellData.ts","webpack://@xterm/xterm/./src/common/buffer/Constants.ts","webpack://@xterm/xterm/./src/common/buffer/Marker.ts","webpack://@xterm/xterm/./src/common/data/Charsets.ts","webpack://@xterm/xterm/./src/common/input/Keyboard.ts","webpack://@xterm/xterm/./src/common/input/KittyKeyboard.ts","webpack://@xterm/xterm/./src/common/input/TextDecoder.ts","webpack://@xterm/xterm/./src/common/input/UnicodeV6.ts","webpack://@xterm/xterm/./src/common/input/Win32InputMode.ts","webpack://@xterm/xterm/./src/common/input/WriteBuffer.ts","webpack://@xterm/xterm/./src/common/input/XParseColor.ts","webpack://@xterm/xterm/./src/common/parser/ApcParser.ts","webpack://@xterm/xterm/./src/common/parser/DcsParser.ts","webpack://@xterm/xterm/./src/common/parser/EscapeSequenceParser.ts","webpack://@xterm/xterm/./src/common/parser/OscParser.ts","webpack://@xterm/xterm/./src/common/parser/Params.ts","webpack://@xterm/xterm/./src/common/public/AddonManager.ts","webpack://@xterm/xterm/./src/common/public/BufferApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferLineApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferNamespaceApi.ts","webpack://@xterm/xterm/./src/common/public/ParserApi.ts","webpack://@xterm/xterm/./src/common/public/UnicodeApi.ts","webpack://@xterm/xterm/./src/common/services/BufferService.ts","webpack://@xterm/xterm/./src/common/services/CharsetService.ts","webpack://@xterm/xterm/./src/common/services/CoreService.ts","webpack://@xterm/xterm/./src/common/services/DecorationService.ts","webpack://@xterm/xterm/./src/common/services/InstantiationService.ts","webpack://@xterm/xterm/./src/common/services/LogService.ts","webpack://@xterm/xterm/./src/common/services/MouseStateService.ts","webpack://@xterm/xterm/./src/common/services/OptionsService.ts","webpack://@xterm/xterm/./src/common/services/OscLinkService.ts","webpack://@xterm/xterm/./src/common/services/ServiceRegistry.ts","webpack://@xterm/xterm/./src/common/services/Services.ts","webpack://@xterm/xterm/./src/common/services/UnicodeService.ts","webpack://@xterm/xterm/webpack/bootstrap","webpack://@xterm/xterm/webpack/startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (␛).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.blur();\n }\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', (e: CompositionEvent) => {\n if (this._compositionHelper instanceof CompositionHelper) {\n if (this._compositionHelper.compositionend(e)) {\n this.textarea!.dispatchEvent(new CustomEvent(\n 'xterm-composition-transaction-accepted',\n { bubbles: true }\n ));\n }\n } else {\n this._compositionHelper!.compositionend();\n }\n }));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._register(toDisposable(() => {\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.dispose();\n }\n }));\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n if (!this._compositionHelper!.keypress?.(key)) {\n this.coreService.triggerDataEvent(key, true);\n }\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n if (\n ev.data &&\n ev.inputType === 'insertText' &&\n !this.optionsService.rawOptions.screenReaderMode &&\n this._compositionHelper instanceof CompositionHelper &&\n this._compositionHelper.input(ev.data)\n ) {\n return true;\n }\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): boolean | void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n keypress?(text: string): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\ninterface IPendingComposition {\n transactionId: number;\n finalizerTimer?: ReturnType;\n lifecycleSettled: boolean;\n sessionEnded: boolean;\n position: IPosition;\n suffix: string;\n dataAlreadySent: string;\n compositionData: string;\n endData: string;\n inputData: string;\n keypressData: string;\n keypressMayOverlapComposition: boolean;\n expectsPostCompositionInput: boolean;\n nextCompositionStart?: number;\n}\n\nconst XTERM_COMPOSITION_SESSION_START_EVENT = 'xterm-composition-session-start';\nconst XTERM_COMPOSITION_SESSION_END_EVENT = 'xterm-composition-session-end';\nconst XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT =\n 'xterm-composition-transaction-accepted';\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n public get hasPendingCompositionFinalization(): boolean {\n return this._pendingComposition !== undefined;\n }\n public get _isSendingComposition(): boolean {\n return this.hasPendingCompositionFinalization;\n }\n public get _pendingKeypressData(): string {\n return this._pendingComposition?.keypressData ?? '';\n }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n private _pendingComposition?: IPendingComposition;\n\n private _isAwaitingCompositionEnd: boolean;\n\n private _compositionInputData: string;\n\n private _lastCompositionData: string;\n\n private _compositionStartValue: string;\n\n private _compositionStartSelection: IPosition;\n\n private _compositionHasObservedProgress: boolean;\n\n private _canceledKey?: Pick;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n /**\n * Identifies the composition transaction that owns deferred work.\n */\n private _compositionTransactionId: number;\n\n /**\n * Timers that still own deferred composition state.\n */\n private _compositionTimers: Set>;\n\n private _compositionPositionTimer?: ReturnType;\n\n private _compositionViewTimer?: ReturnType;\n\n private _compositionEndTimer?: ReturnType;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isAwaitingCompositionEnd = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionStartValue = '';\n this._compositionStartSelection = { start: 0, end: 0 };\n this._compositionHasObservedProgress = false;\n this._compositionTransactionId = 0;\n this._compositionTimers = new Set();\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = undefined;\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = undefined;\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._pendingComposition) {\n this._cancelPendingFinalizer(this._pendingComposition);\n this._endPendingCompositionSession(this._pendingComposition);\n this._settlePendingComposition(this._pendingComposition);\n }\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionStartValue = this._textarea.value;\n this._compositionStartSelection = { start, end };\n this._compositionHasObservedProgress = false;\n if (this._pendingComposition) {\n this._pendingComposition.nextCompositionStart = this._compositionPosition.start;\n }\n this._compositionTransactionId++;\n this._isComposing = true;\n this._isAwaitingCompositionEnd = true;\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionView.classList.add('active');\n this._dispatchCompositionSessionEvent(new CustomEvent(XTERM_COMPOSITION_SESSION_START_EVENT, {\n bubbles: true,\n detail: { id: this._compositionTransactionId }\n }));\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (ev.data?.length > 0) {\n this._lastCompositionData = ev.data;\n }\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data ?? ''}\\u200E`;\n this.updateCompositionElements();\n const transactionId = this._compositionTransactionId;\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = this._defer(() => {\n if (this._isComposing && this._compositionTransactionId === transactionId) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n });\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(ev?: Pick): boolean {\n if (!this._isAwaitingCompositionEnd) {\n return false;\n }\n if (!this._isComposing) {\n const pending = this._pendingComposition;\n if (pending?.transactionId === this._compositionTransactionId) {\n pending.endData = ev?.data ?? '';\n this._updatePostCompositionInputExpectation(pending);\n }\n return false;\n }\n const endData = ev?.data ?? '';\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (!this._compositionEndBelongsToCurrentTransaction(endData)) {\n const pending = this._pendingComposition;\n if (pending && pending.transactionId !== this._compositionTransactionId) {\n this._sendPendingComposition(pending);\n }\n this._deferCompositionEnd(endData);\n return false;\n }\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n return true;\n }\n\n public blur(): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._isComposing) {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n this._finalizeComposition(false);\n }\n }\n\n public dispose(): void {\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n for (const timer of this._compositionTimers) {\n clearTimeout(timer);\n }\n this._compositionTimers.clear();\n this._compositionPositionTimer = undefined;\n this._compositionViewTimer = undefined;\n this._compositionEndTimer = undefined;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionTransactionId++;\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._canceledKey?.code === ev.code && this._canceledKey.timeStamp === ev.timeStamp) {\n this._canceledKey = undefined;\n return false;\n }\n if (ev.key === 'Escape' && (this._isComposing || this.hasPendingCompositionFinalization)) {\n this._canceledKey = { code: ev.code, timeStamp: ev.timeStamp };\n this._cancelComposition();\n return false;\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Defers keypress text while a composition finalizer is pending so all input is emitted once\n * after reconciliation with the final textarea candidate.\n */\n public keypress(text: string): boolean {\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.keypressMayOverlapComposition) {\n pending.keypressData += text;\n return true;\n }\n if (pending.expectsPostCompositionInput && pending.keypressData.length === 0) {\n pending.keypressData = text;\n return true;\n }\n this._sendPendingComposition(pending);\n return false;\n }\n\n public input(text: string): boolean {\n if (this._isComposing) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n this._compositionInputData += text;\n return true;\n }\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.expectsPostCompositionInput) {\n pending.inputData += text;\n pending.expectsPostCompositionInput = false;\n this._sendPendingComposition(pending);\n return true;\n }\n const repeatsPendingTextareaInput =\n text.length > 0 &&\n this._getPendingTextareaInput(pending) === text &&\n this._getPendingTextareaInput(pending, true) === text;\n this._sendPendingComposition(pending);\n if (!repeatsPendingTextareaInput) {\n this._coreService.triggerDataEvent(text, true);\n }\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean, endData: string = ''): void {\n const wasComposing = this._isComposing;\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n if (waitForPropagation && !wasComposing) {\n return;\n }\n\n if (!waitForPropagation) {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition, true);\n }\n if (wasComposing) {\n const input = this._getCompositionInput(\n this._compositionPosition.start + this._dataAlreadySent.length,\n this._compositionSuffix\n );\n this._sendCompositionInput(this._compositionTransactionId, input);\n }\n } else {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition);\n }\n const pending: IPendingComposition = {\n transactionId: this._compositionTransactionId,\n lifecycleSettled: false,\n sessionEnded: false,\n position: {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n },\n suffix: this._compositionSuffix,\n dataAlreadySent: this._dataAlreadySent,\n compositionData: this._lastCompositionData,\n endData,\n inputData: this._compositionInputData,\n keypressData: '',\n keypressMayOverlapComposition:\n this._lastCompositionData.length === 0 && endData.length === 0,\n expectsPostCompositionInput: false\n };\n this._updatePostCompositionInputExpectation(pending);\n this._pendingComposition = pending;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n pending.finalizerTimer = this._defer(() => {\n pending.finalizerTimer = undefined;\n if (this._compositionTransactionId === pending.transactionId) {\n this._isAwaitingCompositionEnd = false;\n }\n if (this._pendingComposition === pending) {\n this._sendPendingComposition(pending, true);\n }\n });\n }\n }\n\n private _sendPendingComposition(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): void {\n this._cancelPendingFinalizer(pending);\n if (this._pendingComposition === pending) {\n this._pendingComposition = undefined;\n }\n const textareaInput = this._getPendingTextareaInput(pending, includeFollowingInput);\n const observedInput = this._removeAlreadySentData(\n pending.inputData || pending.keypressData,\n pending.dataAlreadySent\n );\n const input = this._mergeTextObservations(\n textareaInput || pending.endData || pending.compositionData,\n observedInput,\n pending.keypressMayOverlapComposition\n );\n this._sendCompositionInput(pending.transactionId, input, !pending.sessionEnded);\n this._settlePendingComposition(pending);\n }\n\n private _cancelPendingFinalizer(pending: IPendingComposition): void {\n if (pending.finalizerTimer === undefined) {\n return;\n }\n clearTimeout(pending.finalizerTimer);\n this._compositionTimers.delete(pending.finalizerTimer);\n pending.finalizerTimer = undefined;\n }\n\n private _settlePendingComposition(pending: IPendingComposition): void {\n if (pending.lifecycleSettled) {\n return;\n }\n pending.lifecycleSettled = true;\n this._dispatchCompositionTransactionSettled();\n }\n\n private _mergeTextObservations(\n candidate: string,\n observed: string,\n findShortestOrder: boolean\n ): string {\n if (!observed || candidate.includes(observed)) {\n return candidate;\n }\n if (!candidate || observed.includes(candidate)) {\n return observed;\n }\n if (findShortestOrder) {\n let candidateFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n candidateFirstOverlap > 0 &&\n !candidate.endsWith(observed.substring(0, candidateFirstOverlap))\n ) {\n candidateFirstOverlap--;\n }\n let observedFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n observedFirstOverlap > 0 &&\n !observed.endsWith(candidate.substring(0, observedFirstOverlap))\n ) {\n observedFirstOverlap--;\n }\n return candidateFirstOverlap > observedFirstOverlap\n ? candidate + observed.substring(candidateFirstOverlap)\n : observed + candidate.substring(observedFirstOverlap);\n }\n let overlap = Math.min(candidate.length, observed.length);\n while (overlap > 0 && !candidate.endsWith(observed.substring(0, overlap))) {\n overlap--;\n }\n return candidate + observed.substring(overlap);\n }\n\n private _updatePostCompositionInputExpectation(pending: IPendingComposition): void {\n pending.expectsPostCompositionInput =\n (pending.endData.length > 0 || pending.compositionData.length > 0) &&\n pending.inputData.length === 0 &&\n this._getPendingTextareaInput(pending).length === 0;\n }\n\n private _getPendingTextareaInput(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): string {\n const value = this._textarea.value;\n const start = pending.position.start + pending.dataAlreadySent.length;\n if (pending.nextCompositionStart !== undefined) {\n return value.substring(start, Math.max(start, pending.nextCompositionStart));\n }\n const suffixEnd =\n pending.suffix.length > 0 && value.endsWith(pending.suffix)\n ? value.length - pending.suffix.length\n : value.length;\n const compositionLength = (pending.endData || pending.compositionData).length;\n const observedEnd = includeFollowingInput\n ? suffixEnd\n : Math.max(pending.position.end, start + compositionLength);\n return value.substring(start, Math.max(start, Math.min(suffixEnd, observedEnd)));\n }\n\n private _getCompositionInput(start: number, suffix: string): string {\n const value = this._textarea.value;\n const valueEnd =\n suffix.length > 0 && value.endsWith(suffix) ? value.length - suffix.length : value.length;\n return value.substring(start, Math.max(start, valueEnd));\n }\n\n private _removeAlreadySentData(input: string, dataAlreadySent: string): string {\n if (dataAlreadySent.length === 0) {\n return input;\n }\n if (input.startsWith(dataAlreadySent)) {\n return input.substring(dataAlreadySent.length);\n }\n return dataAlreadySent.includes(input) ? '' : input;\n }\n\n private _cancelComposition(): void {\n const pending = this._pendingComposition;\n if (\n pending &&\n this._isComposing &&\n pending.transactionId !== this._compositionTransactionId\n ) {\n this._sendPendingComposition(pending);\n }\n const transactionId = this._isComposing\n ? this._compositionTransactionId\n : this._pendingComposition?.transactionId ?? 0;\n const settlesPending = pending !== undefined && this._pendingComposition === pending;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionView.classList.remove('active');\n this._textarea.value =\n this._textarea.value.substring(0, this._compositionPosition.start) + this._compositionSuffix;\n this._sendCompositionInput(transactionId, '');\n if (settlesPending && pending) {\n this._settlePendingComposition(pending);\n }\n }\n\n private _sendCompositionInput(\n transactionId: number,\n input: string,\n dispatchSessionEnd: boolean = true\n ): void {\n let prevented = false;\n if (dispatchSessionEnd) {\n const event = new CustomEvent(XTERM_COMPOSITION_SESSION_END_EVENT, {\n bubbles: true,\n cancelable: true,\n detail: { id: transactionId, data: input }\n });\n this._dispatchCompositionSessionEvent(event);\n prevented = event.defaultPrevented;\n }\n if (input.length > 0 && !prevented) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n\n private _endPendingCompositionSession(pending: IPendingComposition): void {\n if (pending.sessionEnded) {\n return;\n }\n pending.sessionEnded = true;\n const input =\n this._getPendingTextareaInput(pending) ||\n pending.endData ||\n pending.compositionData;\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_SESSION_END_EVENT,\n {\n bubbles: true,\n cancelable: true,\n detail: {\n id: pending.transactionId,\n data: input,\n dataPendingReconciliation: true\n }\n }\n ));\n }\n\n private _dispatchCompositionSessionEvent(event: CustomEvent): void {\n if (typeof this._textarea.dispatchEvent === 'function') {\n this._textarea.dispatchEvent(event);\n }\n }\n\n private _dispatchCompositionTransactionSettled(): void {\n this._dispatchCompositionSessionEvent(new CustomEvent(\n 'xterm-composition-transaction-settled',\n { bubbles: true }\n ));\n }\n\n private _deferCompositionEnd(endData: string): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n const transactionId = this._compositionTransactionId;\n const timer = this._defer(() => {\n if (\n this._compositionEndTimer !== timer ||\n !this._isComposing ||\n this._compositionTransactionId !== transactionId ||\n !this._compositionEndBelongsToCurrentTransaction(endData)\n ) {\n return;\n }\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT,\n { bubbles: true }\n ));\n const pending = this._pendingComposition;\n if (pending?.transactionId === transactionId) {\n this._sendPendingComposition(pending, true);\n }\n });\n this._compositionEndTimer = timer;\n }\n\n private _hasCompositionProgress(): boolean {\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n return this._compositionHasObservedProgress || (\n this._textarea.value !== this._compositionStartValue ||\n start !== this._compositionStartSelection.start ||\n end !== this._compositionStartSelection.end\n );\n }\n\n private _compositionEndBelongsToCurrentTransaction(endData: string): boolean {\n return (\n this._hasCompositionProgress() ||\n (endData.length > 0 && endData === this._lastCompositionData)\n );\n }\n\n private _defer(callback: () => void): ReturnType {\n const timer = setTimeout(() => {\n this._compositionTimers.delete(timer);\n callback();\n }, 0);\n this._compositionTimers.add(timer);\n return timer;\n }\n\n private _cancelDeferredTimer(timer?: ReturnType): void {\n if (timer === undefined) {\n return;\n }\n clearTimeout(timer);\n this._compositionTimers.delete(timer);\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = this._defer(() => this.updateCompositionElements(true));\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n","/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n","/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const INVERTED_DEFAULT_COLOR = 257;\n\nexport const enum RendererConstants {\n /**\n * The idle time after which cursor blinking stops.\n */\n CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n","import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n if (this._deleteAtKey(value, key)) {\n return true;\n }\n // A pending deletion whose key mutated after `delete()` (disposing a marker\n // resets `line` to -1, and `line` is the sort key) leaves `_array` out of\n // order, so the binary search above can miss a value that is present.\n // Compacting those entries out restores the order; retry before reporting\n // the value absent, else its `onDecorationRemoved` never fires and the\n // decoration paints forever. Miss path only, so the common bulk delete\n // keeps its O(log n) search and deferred-compaction batching.\n if (this._deletedIndices.length === 0) {\n return false;\n }\n this._flushCleanupDeleted();\n return this._deleteAtKey(value, key);\n }\n\n private _deleteAtKey(value: T, key: number): boolean {\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n²) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const DEFAULT_COLOR = 0;\nexport const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);\nexport const DEFAULT_EXT = 0;\n\nexport const CHAR_DATA_ATTR_INDEX = 0;\nexport const CHAR_DATA_CHAR_INDEX = 1;\nexport const CHAR_DATA_WIDTH_INDEX = 2;\nexport const CHAR_DATA_CODE_INDEX = 3;\n\n/**\n * Null cell - a real empty cell (containing nothing).\n * Note that code should always be 0 for a null cell as\n * several test condition of the buffer line rely on this.\n */\nexport const NULL_CELL_CHAR = '';\nexport const NULL_CELL_WIDTH = 1;\nexport const NULL_CELL_CODE = 0;\n\n/**\n * Whitespace cell.\n * This is meant as a replacement for empty cells when needed\n * during rendering lines to preserve correct alignment.\n */\nexport const WHITESPACE_CELL_CHAR = ' ';\nexport const WHITESPACE_CELL_WIDTH = 1;\nexport const WHITESPACE_CELL_CODE = 32;\n\n/**\n * Bitmasks for accessing data in `content`.\n */\nexport const enum Content {\n /**\n * bit 1..21 codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)\n * read: `codepoint = content & Content.CODEPOINT_MASK;`\n * write: `content |= codepoint & Content.CODEPOINT_MASK;`\n * shortcut if precondition `codepoint <= 0x10FFFF` is met:\n * `content |= codepoint;`\n */\n CODEPOINT_MASK = 0x1FFFFF,\n\n /**\n * bit 22 flag indicating whether a cell contains combined content\n * read: `isCombined = content & Content.IS_COMBINED_MASK;`\n * set: `content |= Content.IS_COMBINED_MASK;`\n * clear: `content &= ~Content.IS_COMBINED_MASK;`\n */\n IS_COMBINED_MASK = 0x200000, // 1 << 21\n\n /**\n * bit 1..22 mask to check whether a cell contains any string data\n * we need to check for codepoint and isCombined bits to see\n * whether a cell contains anything\n * read: `isEmpty = !(content & Content.HAS_CONTENT_MASK)`\n */\n HAS_CONTENT_MASK = 0x3FFFFF,\n\n /**\n * bit 23..24 wcwidth value of cell, takes 2 bits (ranges from 0..2)\n * read: `width = (content & Content.WIDTH_MASK) >> Content.WIDTH_SHIFT;`\n * `hasWidth = content & Content.WIDTH_MASK;`\n * as long as wcwidth is highest value in `content`:\n * `width = content >> Content.WIDTH_SHIFT;`\n * write: `content |= (width << Content.WIDTH_SHIFT) & Content.WIDTH_MASK;`\n * shortcut if precondition `0 <= width <= 3` is met:\n * `content |= width << Content.WIDTH_SHIFT;`\n */\n WIDTH_MASK = 0xC00000, // 3 << 22\n WIDTH_SHIFT = 22\n}\n\nexport const enum Attributes {\n /**\n * bit 1..8 blue in RGB, color in P256 and P16\n */\n BLUE_MASK = 0xFF,\n BLUE_SHIFT = 0,\n PCOLOR_MASK = 0xFF,\n PCOLOR_SHIFT = 0,\n\n /**\n * bit 9..16 green in RGB\n */\n GREEN_MASK = 0xFF00,\n GREEN_SHIFT = 8,\n\n /**\n * bit 17..24 red in RGB\n */\n RED_MASK = 0xFF0000,\n RED_SHIFT = 16,\n\n /**\n * bit 25..26 color mode: DEFAULT (0) | P16 (1) | P256 (2) | RGB (3)\n */\n CM_MASK = 0x3000000,\n CM_DEFAULT = 0,\n CM_P16 = 0x1000000,\n CM_P256 = 0x2000000,\n CM_RGB = 0x3000000,\n\n /**\n * bit 1..24 RGB room\n */\n RGB_MASK = 0xFFFFFF\n}\n\nexport const enum FgFlags {\n /**\n * bit 27..32\n */\n INVERSE = 0x4000000,\n BOLD = 0x8000000,\n UNDERLINE = 0x10000000,\n BLINK = 0x20000000,\n INVISIBLE = 0x40000000,\n STRIKETHROUGH = 0x80000000,\n}\n\nexport const enum BgFlags {\n /**\n * bit 27..32 (upper 2 unused)\n */\n ITALIC = 0x4000000,\n DIM = 0x8000000,\n HAS_EXTENDED = 0x10000000,\n PROTECTED = 0x20000000,\n OVERLINE = 0x40000000\n}\n\nexport const enum ExtFlags {\n /**\n * bit 27..29\n */\n UNDERLINE_STYLE = 0x1C000000,\n\n /**\n * bit 30..32\n *\n * An optional variant for the glyph, this can be used for example to offset underlines by a\n * number of pixels to create a perfect pattern.\n */\n VARIANT_OFFSET = 0xE0000000\n}\n\nexport const enum UnderlineStyle {\n NONE = 0,\n SINGLE = 1,\n DOUBLE = 2,\n CURLY = 3,\n DOTTED = 4,\n DASHED = 5\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u2409', // '␉' (HT)\n 'c': '\\u240c', // '␌' (FF)\n 'd': '\\u240d', // '␍' (CR)\n 'e': '\\u240a', // '␊' (LF)\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '␤' (NL)\n 'i': '\\u240b', // '␋' (VT)\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec § \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" — i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n","\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(6081);\n"],"names":["root","factory","exports","module","define","amd","a","i","globalThis","Strings","__importStar","__webpack_require__","TimeBasedDebouncer_1","Lifecycle_1","Services_1","Services_2","Dom_1","AccessibilityManager","Disposable","constructor","_terminal","instantiationService","_coreBrowserService","_renderService","super","this","_rowColumns","WeakMap","_liveRegionLineCount","_charsToConsume","_charsToAnnounce","doc","mainDocument","_accessibilityContainer","createElement","classList","add","_rowContainer","setAttribute","_rowElements","rows","_createAccessibilityTreeNode","appendChild","_topBoundaryFocusListener","e","_handleBoundaryFocus","_bottomBoundaryFocusListener","addEventListener","length","_liveRegion","_liveRegionDebouncer","_register","TimeBasedDebouncer","_renderRows","bind","element","Error","insertAdjacentElement","onResize","_handleResize","onRender","_refreshRows","start","end","onScroll","onA11yChar","char","_handleChar","onLineFeed","onA11yTab","spaceCount","_handleTab","onKey","_handleKey","key","onBlur","_clearLiveRegion","onDimensionsChange","_refreshRowsDimensions","addDisposableListener","_handleSelectionChange","onDprChange","toDisposable","remove","shift","textContent","tooMuchOutput","get","keyChar","test","push","refresh","buffer","setSize","lines","toString","line","ydisp","columns","lineData","translateToString","undefined","posInSet","set","_alignRowWidth","_announceCharacters","position","boundaryElement","target","beforeBoundaryElement","getAttribute","relatedTarget","topBoundaryElement","bottomBoundaryElement","pop","removeChild","removeEventListener","newElement","unshift","scrollLines","focus","preventDefault","stopImmediatePropagation","selection","getSelection","isCollapsed","contains","anchorNode","clearSelection","focusNode","console","error","begin","node","offset","anchorOffset","focusOffset","compareDocumentPosition","Node","DOCUMENT_POSITION_PRECEDING","DOCUMENT_POSITION_CONTAINED_BY","DOCUMENT_POSITION_FOLLOWING","childNodes","lastRowElement","slice","toRowColumn","rowElement","Text","parentNode","row","parseInt","isNaN","warn","column","cols","beginRowColumn","endRowColumn","select","children","tabIndex","_refreshRowDimensions","dimensions","css","cell","height","Object","assign","style","width","canvas","fontSize","options","transform","getBoundingClientRect","lastColumn","targetWidth","__decorate","__param","IInstantiationService","ICoreBrowserService","IRenderService","prepareTextForTerminal","text","replace","bracketTextForPaste","bracketedPasteMode","paste","textarea","coreService","optionsService","decPrivateModes","rawOptions","ignoreBracketedPasteMode","triggerDataEvent","value","moveTextAreaUnderMouseCursor","ev","screenElement","pos","left","clientX","top","clientY","zIndex","selectionService","clipboardData","setData","selectionText","stopPropagation","getData","shouldSelectWord","rightClickSelect","MultiKeyMap_1","_color","TwoKeyMap","_css","setCss","bg","fg","getCss","setColor","getColor","clear","Clipboard_1","OscLinkProvider_1","Viewport_1","BufferDecorationRenderer_1","OverviewRulerRenderer_1","CompositionHelper_1","DomRenderer_1","CharSizeService_1","CharacterJoinerService_1","CoreBrowserService_1","LinkProviderService_1","MouseCoordsService_1","MouseService_1","RenderService_1","SelectionService_1","ThemeService_1","KeyboardService_1","Color_1","CoreTerminal_1","Browser","BufferLine_1","XParseColor_1","DecorationService_1","InputHandler_1","AccessibilityManager_1","Linkifier_1","Event_1","CoreBrowserTerminal","CoreTerminal","linkifier","_linkifier","onFocus","_onFocus","event","_onBlur","_onA11yCharEmitter","_onA11yTabEmitter","onWillOpen","_onWillOpen","device","MutableDisposable","browser","_keyDownHandled","_keyDownSeen","_keyPressHandled","_unprocessedDeadKey","_accessibilityManager","_onCursorMove","Emitter","onCursorMove","_onKey","_onSelectionChange","onSelectionChange","_onTitleChange","onTitleChange","_onBell","onBell","_onDimensionsChange","_setup","_decorationService","_instantiationService","createInstance","DecorationService","setService","IDecorationService","_keyboardService","KeyboardService","IKeyboardService","_linkProviderService","LinkProviderService","ILinkProviderService","registerLinkProvider","OscLinkProvider","_inputHandler","onRequestBell","fire","onRequestRefreshRows","onRequestSendFocus","_reportFocus","onRequestReset","reset","onRequestWindowsOptionsReport","type","_reportWindowsOptions","onColor","_handleColorEvent","EventUtils","forward","_bufferService","_afterResize","_customKeyEventHandler","_themeService","req","acc","ident","index","colorRgb","color","toColorRGB","colors","ansi","toRgbString","modifyColors","channels","toColor","narrowedAcc","restoreColor","_reportColorScheme","colorSchemeMode","rgb","relativeLuminance","background","rgba","foreground","buffers","active","preventScroll","_handleScreenReaderModeOptionChange","_handleTextAreaFocus","sendFocus","_showCursor","blur","_handleTextAreaBlur","_compositionHelper","CompositionHelper","y","_syncTextArea","isCursorInViewport","isComposing","cursorY","ybase","bufferLine","cursorX","Math","min","x","cellHeight","getWidth","cellWidth","cursorTop","cursorLeft","lineHeight","_initGlobal","_bindKeys","hasSelection","copyHandler","_selectionService","pasteHandlerWrapper","handlePasteEvent","isFirefox","button","rightClickHandler","rightClickSelectsWord","isLinux","_keyUp","_keyDown","_keyPress","compositionstart","updateCompositionElements","compositionupdate","compositionend","dispatchEvent","CustomEvent","bubbles","_inputEvent","open","parent","isConnected","_logService","debug","ownerDocument","defaultView","window","_document","documentOverride","Document","dir","toggle","allowTransparency","onSpecificOptionChange","fragment","createDocumentFragment","_viewportElement","updateCursorStyle","_helperContainer","promptLabel","isChromeOS","readOnly","disableStdin","CoreBrowserService","document","_charSizeService","CharSizeService","ICharSizeService","ThemeService","IThemeService","onRequestColorSchemeQuery","onChangeColors","colorSchemeUpdates","_characterJoinerService","CharacterJoinerService","ICharacterJoinerService","RenderService","onRenderedViewportChange","_onRender","resize","_compositionView","dispose","_mouseCoordsService","MouseCoordsService","IMouseCoordsService","Linkifier","hasRenderer","setRenderer","_createRenderer","handleCursorMove","handleResize","handleBlur","handleFocus","_viewport","Viewport","onRequestScrollLines","SelectionService","ISelectionService","_mouseService","MouseService","IMouseService","amount","suppressScrollEvent","onRequestRedraw","handleSelectionChanged","columnSelectMode","onLinuxMouseSelection","any","_onScroll","queueSync","BufferDecorationRenderer","handleMouseDown","mouseStateService","areMouseEventsActive","mouseEventsRequireAlt","disable","enable","screenReaderMode","showScrollbar","scrollbar","overviewRulerWidth","_overviewRulerRenderer","OverviewRulerRenderer","shouldShow","measure","bindMouse","handleTouchScroll","disposable","DomRenderer","sync","refreshRows","shouldColumnSelect","isCursorInitialized","disp","scrollPages","pageCount","scrollToTop","scrollToBottom","disableSmoothScroll","scrollToLine","scrollAmount","data","attachCustomKeyEventHandler","customKeyEventHandler","attachCustomWheelEventHandler","customWheelEventHandler","setCustomWheelEventHandler","linkProvider","registerCharacterJoiner","handler","joinerId","register","deregisterCharacterJoiner","deregister","markers","registerMarker","cursorYOffset","addMarker","registerDecoration","decorationOptions","setSelection","getSelectionPosition","selectionStart","selectionEnd","selectAll","selectLines","shouldIgnoreComposition","isMac","macOptionIsMeta","altKey","keydown","scrollOnUserInput","result","evaluateKeyDown","scrollCount","_isThirdLevelShift","cancel","useKitty","useWin32InputMode","ctrlKey","metaKey","charCodeAt","wasModifierOnly","wasModifierKeyOnlyEvent","domEvent","thirdLevelKey","isWindows","getModifierState","keyCode","evaluateKeyUp","charCode","which","String","fromCharCode","keypress","inputType","input","composed","hasValidSize","clearAllMarkers","getBlankLine","DEFAULT_ATTR_DATA","clearTextureAtlas","WindowsOptionsReportType","GET_WIN_SIZE_PIXELS","canvasWidth","toFixed","canvasHeight","GET_CELL_SIZE_PIXELS","useCapture","domNode","bb","win","getWindow","scrollX","scrollY","targetWindow","runner","priority","state","getAnimationFrameState","item","AnimationFrameQueueItem","next","animFrameRequested","requestAnimationFrame","current","inAnimationFrameRunner","sort","execute","animationFrameRunner","Async_1","candidateNode","candidateEvent","view","DomListener","_node","_type","_handler","_options","useCaptureOrOptions","eventType","CLICK","MOUSE_DOWN","MOUSE_OVER","MOUSE_LEAVE","KEY_DOWN","KEY_UP","INPUT","BLUR","FOCUS","CHANGE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","MOUSE_WHEEL","WHEEL","_runner","_canceled","b","animationFrameState","Map","WindowIntervalTimer","IntervalTimer","_defaultTarget","cancelAndSet","interval","currentLink","_currentLink","_element","_linkCacheDisposables","_isMouseOut","_wasResized","_activeLine","_onShowLinkUnderline","onShowLinkUnderline","_onHideLinkUnderline","onHideLinkUnderline","_lastMouseEvent","_activeProviderReplies","_clearCurrentLink","_handleMouseMove","_handleMouseDown","_handleMouseUp","_positionFromMouseEvent","composedPath","_lastBufferCell","_handleHover","_askForLink","_linkAtPosition","link","useLineCache","forEach","reply","linkWithState","linkProvided","linkProviders","entries","existingReply","_checkLinkProviderResult","provideLinks","links","linksWithState","map","size","_removeIntersectingLinks","replies","occupiedCells","Set","providerReply","startX","range","endX","has","splice","hasLinkBefore","j","linkAtPosition","find","_handleNewLink","_mouseDownLink","activate","startRow","endRow","_linkLeave","decorations","underline","pointerCursor","isHovered","_linkHover","defineProperties","v","_fireUnderlineEvent","hover","showEvent","scrollOffset","_createLinkUnderlineEvent","leave","lower","upper","coords","getCoords","x1","y1","x2","y2","IBufferService","promptLabelInternal","tooMuchOutputInternal","CellData_1","_optionsService","_oscLinkService","_workCell","CellData","callback","linkHandler","lineLength","getTrimmedLength","currentLinkId","currentStart","finishLink","hasContent","loadCell","hasExtendedAttrs","extended","urlId","getLinkData","uri","_getRangeWithLineWrap","ignoreLink","allowNonHttpProtocols","parsed","URL","includes","protocol","defaultActivate","linkId","startY","finalStartX","endY","finalEndX","currentLine","isWrapped","previousLine","previousLineLength","_hasUrlId","previousStartX","nextLine","nextLineLength","nextEndX","confirm","newWindow","opener","location","href","IOptionsService","IOscLinkService","_renderCallback","_refreshCallbacks","_animationFrame","cancelAnimationFrame","addRefreshCallback","_innerRefresh","rowStart","rowEnd","rowCount","_rowCount","_rowStart","_rowEnd","max","_runRefreshCallbacks","_debounceThresholdMS","_lastRefreshMs","_additionalRefreshRequested","_refreshTimeoutID","clearTimeout","refreshRequestTime","performance","now","elapsed","waitPeriodBeforeTrailingRefresh","setTimeout","DEFAULT_ANSI_COLORS","freeze","r","g","toCss","toRgba","c","scrollableElement_1","scrollable_1","coreBrowserService","_coreService","themeService","_onRequestScrollLines","_isSyncing","_isHandlingScroll","_suppressOnScrollHandler","_needsSyncOnRender","scrollable","Scrollable","forceIntegerValues","smoothScrollDuration","scheduleAtNextAnimationFrame","cb","setSmoothScrollDuration","_scrollableElement","SmoothScrollableElement","vertical","horizontal","useShadows","mouseWheelSmoothScroll","verticalHasArrows","showArrows","_getChangeOptions","onMultipleOptionChange","updateOptions","onProtocolChange","handleMouseWheel","setScrollDimensions","scrollHeight","runAndSubscribe","backgroundColor","getDomNode","_styleElement","scrollbarSliderBackground","scrollbarSliderHoverBackground","scrollbarSliderActiveBackground","join","onBufferActivate","_latestYDisp","_sync","_handleScroll","getScrollPosition","setScrollPosition","reuseAnimation","scrollTop","verticalScrollbarSize","mouseWheelScrollSensitivity","scrollSensitivity","fastScrollSensitivity","_queuedAnimationFrame","synchronizedOutput","newRow","round","diff","translationY","ICoreService","IMouseStateService","_screenElement","_decorationElements","_altBufferIsActive","_dimensionsChanged","_container","_doRefreshDecorations","_queueRefresh","alt","onDecorationRegistered","onDecorationRemoved","decoration","_removeDecoration","_renderDecoration","_refreshStyle","_refreshXPosition","_createElement","layer","marker","display","onRenderEmitter","onDispose","delete","anchor","right","_zones","_zonePool","_zonePoolIndex","_linePadding","full","center","zones","addDecoration","overviewRulerOptions","z","_lineIntersectsZone","_lineAdjacentToZone","_addLineToZone","startBufferLine","endBufferLine","setPadding","padding","zone","ColorZoneStore_1","drawHeight","drawWidth","drawX","_width","_colorZoneStore","ColorZoneStore","_shouldUpdateDimensions","_shouldUpdateAnchor","_lastKnownBufferLength","_canvas","_refreshCanvasDimensions","parentElement","insertBefore","ctx","getContext","_ctx","normal","_refreshDrawHeightConstants","_refreshColorZonePadding","_refreshDrawConstants","outerWidth","floor","innerWidth","ceil","dpr","pixelsPerLine","nonFullHeight","_store","isDisposed","cssCanvasHeight","deviceCanvasHeight","_refreshDecorations","clearRect","lineWidth","_renderRulerOutline","_renderColorZone","fillStyle","overviewRulerBorder","fillRect","overviewRuler","showTopBorder","showBottomBorder","updateCanvasDimensions","updateAnchor","XTERM_COMPOSITION_SESSION_END_EVENT","_isComposing","hasPendingCompositionFinalization","_pendingComposition","_isSendingComposition","_pendingKeypressData","keypressData","_textarea","_isAwaitingCompositionEnd","_compositionPosition","_compositionSuffix","_dataAlreadySent","_compositionInputData","_lastCompositionData","_compositionStartValue","_compositionStartSelection","_compositionHasObservedProgress","_compositionTransactionId","_compositionTimers","_cancelDeferredTimer","_compositionPositionTimer","_compositionViewTimer","_compositionEndTimer","_cancelPendingFinalizer","_endPendingCompositionSession","_settlePendingComposition","_textareaChangeTimer","nextCompositionStart","substring","_dispatchCompositionSessionEvent","detail","id","_hasCompositionProgress","transactionId","_defer","pending","endData","_updatePostCompositionInputExpectation","_compositionEndBelongsToCurrentTransaction","_sendPendingComposition","_deferCompositionEnd","_finalizeComposition","timer","_canceledKey","code","timeStamp","_cancelComposition","_handleAnyTextareaChanges","keypressMayOverlapComposition","expectsPostCompositionInput","inputData","repeatsPendingTextareaInput","_getPendingTextareaInput","waitForPropagation","wasComposing","lifecycleSettled","sessionEnded","suffix","dataAlreadySent","compositionData","finalizerTimer","_getCompositionInput","_sendCompositionInput","includeFollowingInput","textareaInput","observedInput","_removeAlreadySentData","_mergeTextObservations","_dispatchCompositionTransactionSettled","candidate","observed","findShortestOrder","candidateFirstOverlap","endsWith","observedFirstOverlap","overlap","suffixEnd","compositionLength","observedEnd","valueEnd","startsWith","settlesPending","dispatchSessionEnd","prevented","cancelable","defaultPrevented","dataPendingReconciliation","oldValue","newValue","dontRecurse","fontFamily","maxWidth","overflow","direction","compositionViewBounds","getCoordsRelativeToElement","rect","elementStyle","getComputedStyle","leftPadding","getPropertyValue","topPadding","colCount","hasValidCharSize","cssCellWidth","cssCellHeight","isSelection","moveToRequestedRow","targetY","bufferService","applicationCursor","wrappedRowsForRow","rowsToMove","abs","wrappedRows","verticalDirection","wrappedRowsCount","repeat","sequence","currentRow","lineWraps","startCol","endCol","currentCol","bufferStr","translateBufferLineToString","count","str","rpt","targetX","hasScrollback","resetStartingRow","horizontalDirection","moveToRequestedCol","rowDifference","currX","colsFromRowEnd","CoreBrowserTerminal_1","AddonManager_1","BufferNamespaceApi_1","ParserApi_1","UnicodeApi_1","CONSTRUCTOR_ONLY_OPTIONS","$value","Terminal","_core","_addonManager","AddonManager","_publicOptions","getter","propName","setter","_checkReadonlyOptions","desc","defineProperty","_checkProposedApi","allowProposedApi","onBinary","onData","onWriteParsed","parser","_parser","ParserApi","unicode","UnicodeApi","_buffer","BufferNamespaceApi","modes","m","mouseTrackingMode","activeProtocol","applicationCursorKeysMode","applicationCursorKeys","applicationKeypadMode","applicationKeypad","insertMode","originMode","origin","reverseWraparoundMode","reverseWraparound","sendFocusMode","showCursor","isCursorHidden","synchronizedOutputMode","win32InputMode","wraparoundMode","wraparound","wasUserInput","_verifyIntegers","_verifyPositiveIntegers","write","writeln","loadAddon","addon","strings","values","Infinity","DomRendererRowFactory_1","WidthCache_1","Constants_1","RendererUtils_1","SelectionRenderModel_1","TextBlinkStateManager_1","nextTerminalId","_linkifier2","_terminalClass","_selectionRenderModel","createSelectionRenderModel","_lastSelectionColumnMode","_rowHasBlinkingCells","_rowHasBlinkingCellsCount","_onRequestRedraw","_refreshRowElements","_selectionContainer","createRenderDimensions","_updateDimensions","onOptionChange","_handleOptionsChanged","_injectCss","_rowFactory","DomRendererRowFactory","_handleLinkHover","_handleLinkLeave","_cursorBlinkStateManager","CursorBlinkStateManager","restartBlinkAnimation","_textBlinkStateManager","TextBlinkStateManager","_widthCache","_themeStyleElement","_dimensionsStyleElement","WidthCache","setFont","fontWeight","fontWeightBold","_setDefaultSpacing","letterSpacing","styles","_terminalSelector","multiplyOpacity","blinkAnimationUnderlineId","blinkAnimationBarId","blinkAnimationBlockId","cursor","cursorAccent","cursorWidth","selectionBackgroundOpaque","selectionInactiveBackgroundOpaque","INVERTED_DEFAULT_COLOR","opaque","spacing","defaultSpacing","handleDevicePixelRatioChange","handleCharSizeChanged","pause","renderRows","resume","handleViewportVisibilityChange","isVisible","setViewportVisible","replaceChildren","oldViewportStart","oldViewportEnd","_lastSelectionStart","_lastSelectionEnd","update","viewportCappedStartRow","viewportCappedEndRow","newViewportStart","newViewportEnd","viewportStartRow","viewportEndRow","documentFragment","isXFlipped","_createSelectionElement","middleRowsCount","finalEndCol","renderStartRow","renderEndRow","cursorViewportRow","colStart","colEnd","fill","setNeedsBlinkInViewport","cursorAbsoluteY","cursorBlink","cursorStyle","cursorInactiveStyle","rowInfo","hasBlinkingCells","createRow","isBlinkOn","_setRowBlinkState","_updateTextBlinkState","_setCellUnderline","enabled","maxY","bufferline","_isIdlePaused","isFocused","_resetIdleTimer","_clearIdleTimer","_idleTimeout","_stopBlinkingDueToIdle","Constants_2","AttributeData_1","_columnSelectMode","_selectionStart","_selectionEnd","isCursorRow","blinkOn","widthCache","linkStart","linkEnd","elements","joinedRanges","getJoinedCharacters","charElement","getNoBgTrimmedLength","cellAmount","oldBg","oldFg","oldExt","oldLinkHover","oldSpacing","oldIsInSelection","skipJoinedCheckUntilX","classes","hasHover","isJoined","isValidJoinRange","lastCharX","firstSelectionState","_isCellInSelection","JoinedCellData","isInSelection","isCursorCell","isLinkHover","isBlink","isDecorated","forEachDecorationAtCell","d","chars","getChars","WHITESPACE_CELL_CHAR","isUnderline","isOverline","isBold","isItalic","selectionForeground","ext","isInvisible","isDim","underlineStyle","isUnderlineColorDefault","isUnderlineColorRGB","textDecorationColor","AttributeData","getUnderlineColor","drawBoldTextInBrightColors","isStrikethrough","textDecoration","getFgColor","fgColorMode","getFgColorMode","getBgColor","bgColorMode","getBgColorMode","isInverse","temp","temp2","bgOverride","fgOverride","resolvedBg","isTop","backgroundColorRGB","foregroundColorRGB","_addStyle","padStart","_applyMinimumContrast","className","minimumContrastRatio","treatGlyphAsBackgroundColor","getCode","cache","_getContrastCache","adjustedColor","ratio","ensureContrastRatio","halfContrastCache","contrastCache","canvasFactory","WidthCacheFontVariantCanvas","_flat","Float32Array","_font","_fontSize","_weight","_weightBold","_canvasElements","_holey","font","weight","weightBold","bold","italic","cp","_measure","variant","OffscreenCanvas","throwIfFalsy","fontStyle","trim","measureText","isPowerlineGlyph","codepoint","isEmoji","glyphSizeX","deviceCellWidth","isNerdFontGlyph","isBoxOrBlockGlyph","currentOffset","SelectionRenderModel","terminal","viewportY","isCellSelected","_intervalDuration","_blinkOn","_needsBlinkInViewport","_isViewportVisible","duration","setIntervalDuration","blinkIntervalDuration","_clearInterval","isEnabled","needsBlinkInViewport","_updateIntervalState","_interval","wasBlinkOn","setInterval","clearInterval","dom","fastDomNode_1","globalPointerMoveMonitor_1","scrollbarArrow_1","scrollbarVisibilityController_1","widget_1","platform","AbstractScrollbar","Widget","opts","_lazyRender","lazyRender","_host","host","_scrollable","_scrollByPage","scrollByPage","_scrollbarState","scrollbarState","_visibilityController","ScrollbarVisibilityController","visibility","extraScrollbarClassName","setIsNeeded","isNeeded","_pointerMoveMonitor","GlobalPointerMoveMonitor","_shouldRender","FastDomNode","setDomNode","setPosition","_domNodePointerDown","_createArrow","arrow","ScrollbarArrow","bgDomNode","_createSlider","slider","setClassName","setTop","setLeft","setWidth","setHeight","setLayerHinting","setContain","_sliderPointerDown","_onclick","leftButton","_handleElementSize","visibleSize","setVisibleSize","render","_handleElementScrollSize","elementScrollSize","setScrollSize","_handleElementScrollPosition","elementScrollPosition","beginReveal","setShouldBeVisible","beginHide","_renderDomNode","getRectangleLargeSize","getRectangleSmallSize","_updateSlider","getSliderSize","getArrowSize","getSliderPosition","_handlePointerDown","delegatePointerDown","domTop","getClientRects","sliderStart","sliderStop","pointerPos","_sliderPointerPosition","offsetX","offsetY","domNodePosition","getDomNodePagePosition","pageX","pageY","_pointerDownRelativePosition","_setDesiredScrollPositionNow","getDesiredScrollPositionFromOffsetPaged","getDesiredScrollPositionFromOffset","Element","initialPointerPosition","initialPointerOrthogonalPosition","_sliderOrthogonalPointerPosition","initialScrollbarState","clone","toggleClassName","startMonitoring","pointerId","buttons","pointerMoveData","pointerOrthogonalPosition","pointerOrthogonalDelta","pointerDelta","getDesiredScrollPositionFromDelta","handleDragEnd","handleDragStart","_desiredScrollPosition","desiredScrollPosition","writeScrollPosition","setScrollPositionNow","updateScrollbarSize","scrollbarSize","_updateScrollbarSize","setScrollbarSize","numberAsPixels","_height","_top","_left","_bottom","_right","_className","_position","_layerHint","_contain","setBottom","bottom","setRight","shouldHaveIt","layerHint","contain","name","_hooks","DisposableStore","_pointerMoveCallback","_onStopCallback","stopMonitoring","invokeStopCallback","isMonitoring","onStopCallback","initialElement","initialButtons","pointerMoveCallback","eventSource","setPointerCapture","releasePointerCapture","abstractScrollbar_1","scrollbarState_1","HorizontalScrollbar","scrollDimensions","getScrollDimensions","scrollPosition","getCurrentScrollPosition","ScrollbarState","horizontalHasArrows","horizontalScrollbarSize","scrollWidth","scrollLeft","horizontalSliderSize","sliderSize","sliderPosition","largeSize","smallSize","handleScroll","setOppositeScrollbarSize","setVisibility","sameOriginWindowChainCache","getParentWindowIfSameOrigin","w","parentLocation","IframeUtils","_getSameOriginWindowChain","windowChainCache","WeakRef","iframeElement","frameElement","getPositionOfChildWindowRelativeToAncestorWindow","childWindow","ancestorWindow","windowChain","windowChainEl","windowInChain","deref","boundingRect","timestamp","Date","browserEvent","middleButton","rightButton","shiftKey","posx","posy","body","documentElement","iframeOffsets","deltaX","deltaY","targetNode","srcElement","shouldFactorDPR","isChrome","chromeVersionMatch","navigator","userAgent","match","e1","e2","devicePixelRatio","wheelDeltaY","VERTICAL_AXIS","axis","deltaMode","DOM_DELTA_LINE","wheelDeltaX","isSafari","HORIZONTAL_AXIS","wheelDelta","ScrollState","_forceIntegerValues","_scrollStateBrand","rawScrollLeft","rawScrollTop","equals","other","withScrollDimensions","useRawScrollPositions","withScrollPosition","createScrollEvent","previous","inSmoothScrolling","widthChanged","scrollWidthChanged","scrollLeftChanged","heightChanged","scrollHeightChanged","scrollTopChanged","oldWidth","oldScrollWidth","oldScrollLeft","oldHeight","oldScrollHeight","oldScrollTop","_scrollableBrand","_smoothScrollDuration","_scheduleAtNextAnimationFrame","_state","_smoothScrolling","validateScrollPosition","newState","_setState","Boolean","acceptScrollDimensions","getFutureScrollPosition","to","setScrollPositionSmooth","validTarget","newSmoothScrolling","SmoothScrollingOperation","from","startTime","animationFrameDisposable","_performSmoothScrolling","hasPendingScrollAnimation","tick","isDone","oldState","SmoothScrollingUpdate","createEaseOutCubic","delta","completion","t","pow","_initAnimations","_scrollLeft","_initAnimation","_scrollTop","viewportSize","stop1","stop2","cut","_tick","newScrollLeft","newScrollTop","mouseEvent_1","horizontalScrollbar_1","verticalScrollbar_1","MouseWheelClassifierItem","score","MouseWheelClassifier","_capacity","_memory","_front","_rear","isPhysicalMouseWheel","remainingInfluence","iteration","influence","acceptStandardWheelEvent","pageZoomFactor","getZoomFactor","accept","previousItem","_computeScore","_isAlmostInt","absDeltaX","absDeltaY","absPreviousDeltaX","absPreviousDeltaY","minDeltaX","minDeltaY","maxDeltaX","maxDeltaY","INSTANCE","resolvedScrollable","ownsScrollable","flipAxes","consumeMouseWheelIfScrollbarIsNeeded","alwaysConsumeMouseWheel","scrollYToX","scrollPredominantAxis","listenOnDomNode","verticalSliderSize","resolveOptions","scrollbarHost","mouseWheelEvent","_handleMouseWheel","_handleDragStart","_handleDragEnd","_verticalScrollbar","VerticalScrollbar","_horizontalScrollbar","_domNode","_leftShadowDomNode","_topShadowDomNode","_topLeftShadowDomNode","_listenOnDomNode","_mouseWheelToDispose","_setListeningToMouseWheel","_onmouseover","_handleMouseOver","_onmouseleave","_handleMouseLeave","_hideTimeout","TimeoutTimer","_isDragging","_mouseIsOver","_revealOnScroll","updateClassName","newClassName","newOptions","_render","delegateScrollFromMouseWheelEvent","StandardWheelEvent","shouldListen","onMouseWheel","passive","classifier","didScroll","shiftConvert","futureScrollPosition","deltaScrollTop","desiredScrollTop","deltaScrollLeft","desiredScrollLeft","consumeMouseWheel","_reveal","renderNow","scrollState","enableTop","enableLeft","leftClassName","topClassName","topLeftClassName","_hide","_scheduleHide","_handleActivate","handleActivate","bgWidth","bgHeight","arrowSize","addStandardDisposableListener","_arrowPointerDown","_pointerdownRepeatTimer","_pointerdownScheduleRepeatTimer","oppositeScrollbarSize","scrollSize","_scrollbarSize","_oppositeScrollbarSize","_arrowSize","_visibleSize","_scrollSize","_scrollPosition","_computedAvailableSize","_computedIsNeeded","_computedSliderSize","_computedSliderRatio","_computedSliderPosition","_refreshComputedValues","iVisibleSize","iScrollSize","iScrollPosition","setArrowSize","iArrowSize","_computeValues","computedAvailableSize","computedRepresentableSize","computedIsNeeded","computedSliderSize","computedSliderRatio","computedSliderPosition","desiredSliderPosition","correctedOffset","visibleClassName","invisibleClassName","_visibility","_visibleClassName","_invisibleClassName","_isVisible","_isNeeded","_rawShouldBeVisible","_shouldBeVisible","_revealTimer","_updateShouldBeVisible","rawShouldBeVisible","_applyVisibilitySetting","shouldBeVisible","ensureVisibility","setIfNotSet","withFadeAway","DomUtils","mainWindow","tail","array","n","LinkedListNode","Undefined","prev","LinkedList","_first","_last","_insert","atTheEnd","newNode","oldLast","oldFirst","didRemove","_remove","Symbol","iterator","EventType","TAP","START","END","CONTEXT_MENU","Gesture","_dispatched","_targets","_ignoreTargets","_activeTouches","_handle","_lastSetTapCountTime","_handleTouchStart","_handleTouchEnd","_handleTouchMove","addTarget","isTouchDevice","None","_instance","ignoreTarget","maxTouchPoints","len","targetTouches","touch","identifier","initialTarget","initialTimeStamp","initialPageX","initialPageY","rollingTimestamps","rollingPageX","rollingPageY","evt","_newGestureEvent","_dispatchEvent","activeTouchCount","keys","changedTouches","hasOwnProperty","holdTime","_holdDelay","finalX","finalY","deltaT","dispatchTo","filter","_inertia","createEvent","initEvent","tapCount","currentTime","getTime","setTapCount","_clearTapCountTime","targets","depth","t1","vX","dirX","vY","dirY","deltaPosX","deltaPosY","stopped","_scrollFriction","translationX","_target","descriptor","fnKey","fn","memoizeKey","args","configurable","enumerable","writable","apply","hasArrows","_arrowScrollDelta","_setArrows","_arrowScroll","currentPosition","_arrowUp","_arrowDown","arrowDelta","_updateArrowSize","listener","StandardMouseEvent","isSelectAllActive","selectionStartLength","finalSelectionStart","areSelectionValuesReversed","finalSelectionEnd","startPlusLength","handleTrim","_onCharSizeChange","onCharSizeChange","_measureStrategy","TextMetricsMeasureStrategy","DomMeasureStrategy","BaseMeasureStategy","_result","_validateAndSet","_parentElement","_measureElement","whiteSpace","fontKerning","Number","offsetWidth","offsetHeight","metrics","fontBoundingBoxAscent","fontBoundingBoxDescent","firstCell","content","combinedData","isCombined","setFromCharData","getAsCharData","_characterJoiners","_nextCharacterJoinerId","joiner","ranges","lineStr","trimmedLength","rangeStartColumn","currentStringIndex","rangeStartStringIndex","rangeAttrFG","getFg","rangeAttrBG","getBg","_getJoinedRanges","startIndex","endIndex","allJoinedRanges","joinerRanges","_mergeRanges","_stringRangesToCellRanges","currentRangeIndex","currentRangeStarted","currentRange","getString","newRange","inRange","_window","_isFocused","_cachedIsFocused","_onDprChange","_onWindowChange","onWindowChange","_screenDprMonitor","ScreenDprMonitor","setWindow","hasFocus","queueMicrotask","_parentWindow","_windowResizeListener","_outerListener","_setDprAndFireIfDiffers","_currentDevicePixelRatio","_updateDpr","_setWindowResizeListener","clearListener","parentWindow","_resolutionMediaMatchList","removeListener","matchMedia","addListener","Keyboard_1","KittyKeyboard_1","Win32InputMode_1","Platform_1","_getWin32InputMode","_win32InputMode","Win32InputMode","_getKittyKeyboard","_kittyKeyboard","KittyKeyboard","evaluateKeyboardEvent","kittyFlags","kittyKeyboard","flags","evaluate","vtExtensions","shouldUseProtocol","providerIndex","indexOf","Mouse_1","getMouseReportCoords","col","touch_1","_mouseStateService","_lastEvent","_wheelPartialScroll","_touchScrollAccumulator","requestedEvents","mouseup","wheel","mousedrag","mousemove","eventListeners","_handleWheel","_handleMouseDrag","_altMouseCursor","AltMouseCursorController","events","_handleProtocolChange","_syncMouseModeState","_handlePassiveWheel","_handleTouchChange","_sendEvent","but","action","overrideType","allowCustomWheelEvent","_consumeWheelEvent","stripAltFromReport","_triggerMouseEvent","ctrl","shouldForceSelection","_handleTouchScrollAsWheel","_handleTouchScrollAsKeys","trunc","resetClass","logLevel","_explainEvents","_applyScrollModifier","targetWheelEventPixels","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_PAGE","_equalEvents","isPixelEncoding","restrictMouseEvent","report","encodeMouseEvent","isDefaultEncoding","triggerBinaryEvent","down","up","drag","move","pixels","ILogService","_isActive","_listeners","store","syncFromModifier","_updateClass","altHeld","RenderDebouncer_1","TaskQueue_1","_renderer","decorationService","_observerDisposable","_isPaused","_needsFullRefresh","_isNextRenderRedrawOnly","_needsSelectionRefresh","_canvasWidth","_canvasHeight","_selectionState","_onRenderedViewportChange","_onRefreshRequest","onRefreshRequest","_pausedResizeTask","DebouncedIdleTask","_renderDebouncer","RenderDebouncer","_syncOutputHandler","SynchronizedOutputHandler","_fullRefresh","_registerIntersectionObserver","observer","IntersectionObserver","_handleIntersectionChange","threshold","_intersectionObserver","disconnect","observe","entry","isIntersecting","intersectionRatio","flush","isRedrawOnly","bufferRows","buffered","_fireOnCanvasResize","renderer","_onTimeout","_start","_end","_isBuffering","_timeout","MoveToCell_1","SelectionModel_1","BufferRange_1","NON_BREAKING_SPACE_CHAR","ALL_NON_BREAKING_SPACE_REGEX","RegExp","_dragScrollAmount","_enabled","_trimListener","_mouseDownTimeStamp","_oldHasSelection","_oldSelectionStart","_oldSelectionEnd","_onLinuxMouseSelection","_onRedrawRequest","_mouseMoveListener","_mouseUpListener","onUserInput","onTrim","_handleTrim","_handleBufferActivate","_model","SelectionModel","_activeSelectionMode","_removeMouseDownListeners","rowsChanged","lineText","startRowEndCol","isLinuxMouseSelection","_refreshAnimationFrame","_refresh","_isClickInSelection","_getMouseBufferCoords","_areCoordsInSelection","isCellInSelection","_selectWordAtCursor","allowWhitespaceOnlySelection","getRangeLength","_selectWordAt","_getMouseEventScrollAmount","terminalHeight","macOptionClickForcesSelection","_handleIncrementalClick","_handleSingleClick","_handleDoubleClick","_handleTripleClick","_addMouseDownListeners","_dragScrollIntervalTimer","_dragScroll","hadSelection","_fireOnSelectionChange","hasWidth","_selectLineAt","previousSelectionEnd","_selectToWordAt","timeElapsed","altClickMovesCursor","coordinates","moveToCellSequence","_fireEventIfSelectionChanged","activeBuffer","_convertViewportColToCharacterIndex","charIndex","_getWordAt","followWrappedLinesAbove","followWrappedLinesBelow","charOffset","leftWideCharCount","rightWideCharCount","leftLongCharOffset","rightLongCharOffset","charAt","_isCharWordSeparator","getCodePoint","previousBufferLine","previousLineWordPosition","nextBufferLine","nextLineWordPosition","wordPosition","wordSeparator","wrappedRange","getWrappedRangeForLine","first","last","ServiceRegistry_1","createDecorator","ColorContrastCache_1","Types_1","DEFAULT_FOREGROUND","DEFAULT_BACKGROUND","DEFAULT_CURSOR","DEFAULT_CURSOR_ACCENT","DEFAULT_SELECTION","DEFAULT_OVERVIEW_RULER_BORDER","_colors","_contrastCache","ColorContrastCache","_halfContrastCache","_onChangeColors","selectionBackgroundTransparent","blend","selectionInactiveBackgroundTransparent","opacity","_updateRestoreColors","_setTheme","theme","parseColor","selectionBackground","selectionInactiveBackground","NULL_COLOR","isOpaque","black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite","extendedAnsi","colorCount","slot","_restoreColor","_restoreColors","cssString","fallback","millis","Promise","resolve","timeout","_token","_isDisposed","_isScheduled","_disposable","context","handle","CircularList","_maxLength","onDeleteEmitter","onDelete","onInsertEmitter","onInsert","onTrimEmitter","_array","Array","_startIndex","_length","maxLength","newMaxLength","newArray","_getCyclicIndex","newLength","recycle","isFull","deleteCount","items","countToTrim","trimStart","shiftElements","expandListBy","$r","$g","$b","$a","toPaddedHex","s","contrastRatio","l1","l2","color_1","toChannels","fgR","fgG","fgB","bgR","bgG","bgB","rgbaColor","factor","css_1","$ctx","$litmusColor","willReadFrequently","globalCompositeOperation","createLinearGradient","rgbaMatch","parseFloat","getImageData","rgb_1","relativeLuminance2","rs","gs","bs","reduceLuminance","bgRgba","fgRgba","cr","increaseLuminance","bgL","fgL","resultA","resultARatio","resultB","InstantiationService_1","LogService_1","BufferService_1","OptionsService_1","CoreService_1","MouseStateService_1","UnicodeV6_1","UnicodeService_1","CharsetService_1","WindowsMode_1","WriteBuffer_1","OscLinkService_1","hasWriteSyncWarnHappened","_onScrollApi","_windowsWrappingHeuristics","_onBinary","_onData","_onLineFeed","_onResize","_onWriteParsed","InstantiationService","OptionsService","LogService","BufferService","CoreService","MouseStateService","unicodeService","UnicodeService","UnicodeV6","IUnicodeService","_charsetService","CharsetService","ICharsetService","OscLinkService","InputHandler","onRequestScrollToBottom","_writeBuffer","handleUserInput","_handleWindowsPtyOptionChange","markRangeDirty","scrollBottom","WriteBuffer","promiseResult","parse","writeSync","maxSubsequentCalls","LogLevelEnum","WARN","flushSync","scroll","eraseAttr","registerEscHandler","registerDcsHandler","registerCsiHandler","registerOscHandler","registerApcHandler","windowsPty","backend","buildNumber","_enableWindowsWrappingHeuristics","disposables","updateWindowsModeWrappedState","final","_disposed","_event","thisArgs","idx","isArray","call","listeners","initial","Charsets_1","EscapeSequenceParser_1","TextDecoder_1","OscParser_1","DcsParser_1","ApcParser_1","Version_1","GLEVEL","paramToWindowOption","setWinLines","restoreWin","minimizeWin","setWinPosition","setWinSizePixels","raiseWin","lowerWin","refreshWin","setWinSizeChars","maximizeWin","fullscreenWin","getWinState","getWinPosition","getWinSizePixels","getScreenSizePixels","getCellSizePixels","getWinSizeChars","getScreenSizeChars","getIconTitle","getWinTitle","pushTitle","popTitle","$temp","getAttrData","_curAttrData","_unicodeService","EscapeSequenceParser","_parseBuffer","Uint32Array","_stringDecoder","StringToUtf32","_utf8Decoder","Utf8ToUtf32","_windowTitle","_iconName","_windowTitleStack","_iconNameStack","_eraseAttrDataInternal","_onRequestBell","_onRequestRefreshRows","_onRequestReset","_onRequestSendFocus","_onRequestSyncScrollBar","onRequestSyncScrollBar","_onRequestWindowsOptionsReport","_onA11yChar","_onA11yTab","_onColor","_onRequestColorSchemeQuery","_parseStack","paused","cursorStartX","cursorStartY","decodedLength","_specialColors","_dirtyRowTracker","DirtyRowTracker","_activeBuffer","setCsiHandlerFallback","params","identToString","toArray","setEscHandlerFallback","setExecuteHandlerFallback","setOscHandlerFallback","setDcsHandlerFallback","payload","setApcHandlerFallback","setPrintHandler","print","insertChars","intermediates","cursorUp","scrollRight","cursorDown","cursorForward","cursorBackward","cursorNextLine","cursorPrecedingLine","cursorCharAbsolute","cursorPosition","cursorForwardTab","eraseInDisplay","prefix","eraseInLine","insertLines","deleteLines","deleteChars","scrollUp","scrollDown","eraseChars","cursorBackwardTab","charPosAbsolute","hPositionRelative","repeatPrecedingCharacter","sendDeviceAttributesPrimary","sendDeviceAttributesSecondary","linePosAbsolute","vPositionRelative","hVPosition","tabClear","setMode","setModePrivate","resetMode","resetModePrivate","charAttributes","deviceStatus","deviceStatusPrivate","softReset","sendXtVersion","setCursorStyle","setScrollRegion","saveCursor","windowOptions","restoreCursor","insertColumns","deleteColumns","selectProtected","requestMode","kittyKeyboardSet","kittyKeyboardQuery","kittyKeyboardPush","kittyKeyboardPop","setExecuteHandler","bell","lineFeed","carriageReturn","backspace","tab","shiftOut","shiftIn","tabSet","OscHandler","setTitle","setIconName","setOrReportIndexedColor","setHyperlink","setOrReportFgColor","setOrReportBgColor","setOrReportCursorColor","restoreIndexedColor","restoreFgColor","restoreBgColor","restoreCursorColor","reverseIndex","keypadApplicationMode","keypadNumericMode","fullReset","setgLevel","selectDefaultCharset","flag","CHARSETS","selectCharset","screenAlignmentPattern","setErrorHandler","DcsHandler","requestStatusString","_preserveStack","_logSlowResolvingAsync","p","slowTimeout","slowPromise","_res","rej","race","then","err","_getCurrentLinkId","wasPaused","DEBUG","prototype","TRACE","trace","split","clearRange","decode","subarray","viewportEnd","viewportStart","chWidth","charset","curAttr","bufferRow","markDirty","setCellFromCodepoint","precedingJoinState","ch","currentInfo","charProperties","extractWidth","shouldJoin","extractShouldJoin","stringFromCodePoint","addLineToLink","oldRow","oldCol","_eraseAttrData","BufferLine","copyCellsFrom","addCodepointToCell","insertCells","getNullCell","NULL_CELL_CODE","NULL_CELL_WIDTH","ApcHandler","convertEol","_restrictCursor","originalX","nextStop","maxCol","_setCursor","_moveCursor","diffToTop","diffToBottom","param","tabs","prevStop","_eraseInBufferLine","clearWrap","respectProtect","replaceCells","_resetBufferLine","clearMarkers","scrollOnEraseInDisplay","scrollBackSize","scrollBottomRowsOffset","scrollBottomAbsolute","deleteCells","joinState","idata","itext","codePointAt","tlength","copyWithin","_is","XTERM_VERSION","term","termName","setgCharset","DEFAULT_CHARSET","quirks","allowSetCursorBlink","activeEncoding","mainFlags","altFlags","activateAltBuffer","colorSchemeQuery","activateNormalBuffer","dm","mouseProtocol","mouseEncoding","cs","f","b2v","_updateAttrColor","mode","c1","c2","c3","fromColorRGB","_extractColor","attr","accu","cSpace","advance","hasSubParams","subparams","getSubParams","underlineColor","_processUnderline","updateExtended","_processSGR0","l","kittySgrBoldFaintControl","savedX","savedY","savedCurAttrData","savedCharset","isBlinking","second","savedCharsets","charsets","savedGlevel","glevel","savedOriginMode","savedWraparoundMode","slots","spec","exec","isValidColorIndex","_createHyperlink","_finishHyperlink","parsedParams","idParamIndex","findIndex","registerLink","_setOrReportSpecialColor","collectAndFlag","scrollRegionHeight","level","yOffset","markAllDirty","isProtected","block","bar","stack","altStack","mainStack","arg","_disposables","o","_value","_data","third","fourth","_targetWindow","majorVersion","isNode","process","isLegacyEdge","_getKey","logService","_insertedValues","_isFlushingInserted","_deletedIndices","_isFlushingDeleted","_flushInsertedTask","IdleTaskQueue","_flushDeletedTask","insert","_flushCleanupDeleted","enqueue","_flushInserted","sortedAddedValues","sortedAddedValuesIndex","arrayIndex","newArrayIndex","_flushCleanupInserted","_deleteAtKey","_search","_flushDeleted","sortedDeletedIndices","sortedDeletedIndicesIndex","getKeyIterator","forEachByKey","mid","midKey","StringBuilder","_chunks","append","chunk","_limit","_builder","limit","TaskQueue","_tasks","_i","task","_idleCallback","_cancelCallback","_requestCallback","_process","deadline","taskDuration","deadlineRemaining","longestTask","lastDeadlineRemaining","timeRemaining","PriorityTaskQueue","_createDeadline","requestIdleCallback","cancelIdleCallback","_queue","lastChar","CHAR_DATA_CODE_INDEX","WHITESPACE_CELL_CODE","ExtendedAttrs","newObj","isFgRGB","isBgRGB","isFgPalette","isBgPalette","isFgDefault","isBgDefault","isAttributeDefault","isEmpty","getUnderlineColorMode","isUnderlineColorPalette","getUnderlineStyle","getUnderlineVariantOffset","underlineVariantOffset","_urlId","_ext","val","CircularList_1","BufferLineStringCache_1","BufferReflow_1","Marker_1","MAX_BUFFER_SIZE","Buffer","_hasScrollback","_nullCell","fromCharData","NULL_CELL_CHAR","_whitespaceCell","WHITESPACE_CELL_WIDTH","_isClearing","_memoryCleanupPosition","_cols","_rows","_getCorrectBufferLength","setupTabStops","_memoryCleanupQueue","_stringCache","BufferLineStringCache","getWhitespaceCell","relativeY","correctBufferLength","scrollback","fillViewportRows","fillAttr","newCols","newRows","nullCell","dirtyMemoryLines","addToY","amountToTrim","_isReflowEnabled","_reflow","_batchedMemoryCleanup","normalRun","counted","cleanupMemory","_reflowLarger","_reflowSmaller","reflowCursorLine","toRemove","reflowLargerGetLinesToRemove","newLayoutResult","reflowLargerCreateNewLayout","reflowLargerApplyNewLayout","layout","_reflowLargerAdjustViewport","countRemoved","viewportAdjustments","toInsert","countToInsert","wrappedLines","absoluteY","lastLineLength","destLineLengths","reflowSmallerGetNewLineLengths","linesToAdd","trimmedLines","newLines","newLine","destLineIndex","destCol","srcLineIndex","srcCol","cellsToCopy","wrappedLinesIndex","getWrappedLineTrimmedLength","setCell","insertEvents","originalLines","originalLinesLength","originalLineIndex","nextToInsertIndex","nextToInsert","countInsertedSoFar","nextI","insertCountEmitted","lineIndex","trimRight","tabStopWidth","Marker","_removeMarker","StringBuilder_1","$startIndex","$workCell","$translateToStringBuilder","fillCellData","_combined","_extendedAttrs","_invalidateStringCache","CHAR_DATA_ATTR_INDEX","CHAR_DATA_CHAR_INDEX","CHAR_DATA_WIDTH_INDEX","codePoint","attrs","byteLength","uint32Cells","extKeys","copyFrom","_copySparseMapsFrom","src","applyInReverse","srcData","_copyCellMapsFrom","outColumns","isCanonicalRequest","stringCacheEntry","_getStringCacheEntry","isTrimmed","trimEnd","cacheEntry","createIfNeeded","cachedEntry","_stringCacheEntryRef","generation","allocateEntry","srcStart","_clearTimeout","_lastAccessTimestamp","_scheduleClear","_scheduleClearTimeout","timeoutMs","disposableTimeout","bufferCols","endsInNull","followingLineStartsWithWide","oldCols","bufferAbsoluteY","srcTrimmedTineLength","srcRemainingCells","destRemainingCells","countToRemove","nextToRemoveIndex","nextToRemoveStart","countRemovedSoFar","newLayout","newLayoutLines","newLineLengths","cellsNeeded","srcLine","cellsAvailable","oldTrimmedLength","endsWithWide","Buffer_1","BufferSet","_normalBuffer","_altBuffer","_onBufferActivate","_normal","_alt","inactiveBuffer","obj","combined","attributesEquals","thisDefault","otherDefault","DEFAULT_COLOR","DEFAULT_ATTR","DEFAULT_EXT","_id","_nextId","_onDispose","h","k","q","u","A","B","C","R","Q","K","Y","E","Z","H","_","applicationCursorMode","modifiers","keyMapping","KEYCODE_KEY_MAPPINGS","keyString","toUpperCase","toLowerCase","_functionalKeyCodes","Escape","Enter","Tab","Backspace","CapsLock","ScrollLock","NumLock","PrintScreen","Pause","ContextMenu","F13","F14","F15","F16","F17","F18","F19","F20","F21","F22","F23","F24","F25","KP_0","KP_1","KP_2","KP_3","KP_4","KP_5","KP_6","KP_7","KP_8","KP_9","KP_Decimal","KP_Divide","KP_Multiply","KP_Subtract","KP_Add","KP_Enter","KP_Equal","ShiftLeft","ShiftRight","ControlLeft","ControlRight","AltLeft","AltRight","MetaLeft","MetaRight","MediaPlayPause","MediaStop","MediaTrackNext","MediaTrackPrevious","AudioVolumeDown","AudioVolumeUp","AudioVolumeMute","_csiTildeKeys","Insert","Delete","PageUp","PageDown","F5","F6","F7","F8","F9","F10","F11","F12","_csiLetterKeys","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Home","End","_ss3FunctionKeys","F1","F2","F3","F4","_getNumpadKeyCode","_getModifierKeyCode","_encodeModifiers","mods","_getKeyCode","macOptionAsAlt","numpadCode","modifierCode","funcCode","digit","_isModifierKey","_isLockKey","_buildCsiLetterSequence","letter","reportEventTypes","needsEventType","seq","_buildSs3Sequence","_buildCsiTildeSequence","number","_buildCsiUSequence","isFunc","isMod","shiftedKey","textCode","csiLetter","ss3Letter","tildeCode","specialKey","legacyByte","_interim","startPos","interim","Uint8Array","byte1","byte2","byte3","byte4","discardInterim","tmp","missing","fourStop","BMP_COMBINING","HIGH_COMBINING","table","version","wcwidth","num","ucs","bisearch","preceding","createPropertyValue","_codeToVk","KeyA","KeyB","KeyC","KeyD","KeyE","KeyF","KeyG","KeyH","KeyI","KeyJ","KeyK","KeyL","KeyM","KeyN","KeyO","KeyP","KeyQ","KeyR","KeyS","KeyT","KeyU","KeyV","KeyW","KeyX","KeyY","KeyZ","Digit0","Digit1","Digit2","Digit3","Digit4","Digit5","Digit6","Digit7","Digit8","Digit9","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","NumpadMultiply","NumpadAdd","NumpadSeparator","NumpadSubtract","NumpadDecimal","NumpadDivide","NumpadEnter","Space","Semicolon","Equal","Comma","Minus","Period","Slash","Backquote","BracketLeft","Backslash","BracketRight","Quote","IntlBackslash","_codeToScancode","_enhancedKeyCodes","_keyToControlChar","_getVirtualKeyCode","vk","_getScanCode","_getUnicodeChar","controlChar","_getControlKeyState","isKeyDown","_action","_callbacks","_pendingData","_bufferOffset","_isSyncWriting","_syncCalls","_didUserInput","_innerWriteTimer","didProcess","_innerWrite","_scheduleInnerWrite","lastTime","continuation","catch","low","RGB_REX","base","HASH_REX","adv","bits","pad","s2","EMPTY_HANDLERS","_handlers","create","_active","_ident","_handlerFb","_stack","loopPosition","fallThrough","registerHandler","handlerList","handlerIndex","clearHandler","setHandlerFallback","put","utf32ToString","success","handlerResult","LimitedStringBuilder","_payloadLimit","_hitLimit","ret","res","Params_1","unhook","hook","EMPTY_PARAMS","Params","addParam","_params","TransitionTable","Uint16Array","setDefault","addMany","codes","NON_ASCII_PRINTABLE","VT500_TRANSITION_TABLE","blueprint","unused","PRINTABLES","EXECUTABLES","states","_transitions","handlers","handlerPos","transition","chunkPos","initialState","currentState","_collect","_printHandlerFb","_executeHandlerFb","_csiHandlerFb","_escHandlerFb","_errorHandlerFb","_printHandler","_executeHandlers","_executeHandlersArr","_csiHandlers","_escHandlers","_oscParser","OscParser","_dcsParser","DcsParser","_apcParser","ApcParser","_errorHandler","_identifier","finalRange","intermediate","finalCode","reverse","clearPrintHandler","clearEscHandler","clearExecuteHandler","clearCsiHandler","clearDcsHandler","clearOscHandler","clearApcHandler","clearErrorHandler","resetZdm","csiDone","addDigit","addSubParam","l4","collect","abort","handlersEsc","jj","_put","fromArray","maxSubParamsLength","Int32Array","_subParams","_subParamsLength","_subParamsIdx","_rejectDigits","_rejectSubDigits","_digitIsSub","newParams","getSubParamsAll","cur","_addons","instance","loadedAddon","_wrappedAddonDispose","BufferLineApiView_1","init","baseY","getLine","BufferLineApiView","_line","getCell","startColumn","endColumn","BufferApiView_1","_onBufferChange","onBufferChange","BufferApiView","_alternate","alternate","addCsiHandler","addDcsHandler","addEscHandler","addOscHandler","provider","versions","activeVersion","BufferSet_1","isUserScrolling","colsChanged","_cachedBlankLine","topRow","bottomRow","willBufferBeTrimmed","oldYdisp","_charsets","DEFAULT_MODES","DEFAULT_DEC_PRIVATE_MODES","_onUserInput","_onRequestScrollToBottom","showCursorImmediately","structuredClone","SortedList_1","$xmin","$xmax","_decorations","_lineCache","DecorationLineCache","_onDecorationRegistered","_onDecorationRemoved","SortedList","attachToBufferLines","Decoration","markerDispose","getDecorationsAtCell","bucket","getDecorationsOnLine","_decorationsByLine","_bufferLineListeners","_lineIndexSyncTimer","MicrotaskTimer","_lineIndexSyncCallbacks","_addToLineBuckets","_removeFromLineBuckets","_handleBufferLinesTrim","_handleBufferLinesInsert","_handleBufferLinesDelete","_getDecorationHeight","_indexedStartLine","_reindexDecoration","_scheduleLineIndexSync","callbacks","newMap","_mergeLineBucket","_applyBufferLinesInsert","_applyBufferLinesDelete","existing","spanCrossers","deleteEnd","toReindex","_cachedBg","_cachedFg","foregroundColor","ServiceCollection","_entries","service","_services","getService","ctor","serviceDependencies","getServiceDependencies","serviceArgs","dependency","firstServiceArgPos","optionsKeyToLogLevel","info","INFO","ERROR","off","OFF","_logLevel","_updateLogLevel","_evalLazyOptionalParams","optionalParams","_log","message","logger","log","DEFAULT_PROTOCOLS","NONE","restrict","X10","VT200","DRAG","ANY","eventCode","isSGR","S","DEFAULT_ENCODINGS","DEFAULT","SGR","SGR_PIXELS","_protocols","_encodings","_activeProtocol","_activeEncoding","_onProtocolChange","addProtocol","addEncoding","encoding","_customWheelEventHandler","DEFAULT_OPTIONS","rescaleOverlappingGlyphs","FONT_WEIGHT_OPTIONS","_onOptionChange","defaultOptions","_sanitizeAndValidateOption","_setupOptions","eventKey","isCursorStyle","_entriesWithId","_dataByLinkId","_removeMarkerFromLink","castData","_getEntryIdKey","every","linkData","serviceRegistry","decorator","arguments","storeServiceDependency","_providers","_onChange","onChange","extractCharKind","_activeProvider","getStringCellWidth","precedingInfo","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__"],"sourceRoot":""} ++{"version":3,"file":"xterm.js","mappings":"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CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAAS,CAAC,KAAQ,MAC7C,CAAC,KAAQ,MAAS,CAAC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","sources":["webpack://@xterm/xterm/webpack/universalModuleDefinition","webpack://@xterm/xterm/./src/browser/AccessibilityManager.ts","webpack://@xterm/xterm/./src/browser/Clipboard.ts","webpack://@xterm/xterm/./src/browser/ColorContrastCache.ts","webpack://@xterm/xterm/./src/browser/CoreBrowserTerminal.ts","webpack://@xterm/xterm/./src/browser/Dom.ts","webpack://@xterm/xterm/./src/browser/Linkifier.ts","webpack://@xterm/xterm/./src/browser/LocalizableStrings.ts","webpack://@xterm/xterm/./src/browser/OscLinkProvider.ts","webpack://@xterm/xterm/./src/browser/RenderDebouncer.ts","webpack://@xterm/xterm/./src/browser/TimeBasedDebouncer.ts","webpack://@xterm/xterm/./src/browser/Types.ts","webpack://@xterm/xterm/./src/browser/Viewport.ts","webpack://@xterm/xterm/./src/browser/decorations/BufferDecorationRenderer.ts","webpack://@xterm/xterm/./src/browser/decorations/ColorZoneStore.ts","webpack://@xterm/xterm/./src/browser/decorations/OverviewRulerRenderer.ts","webpack://@xterm/xterm/./src/browser/input/CompositionHelper.ts","webpack://@xterm/xterm/./src/browser/input/Mouse.ts","webpack://@xterm/xterm/./src/browser/input/MoveToCell.ts","webpack://@xterm/xterm/./src/browser/public/Terminal.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRenderer.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/DomRendererRowFactory.ts","webpack://@xterm/xterm/./src/browser/renderer/dom/WidthCache.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/Constants.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/RendererUtils.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/SelectionRenderModel.ts","webpack://@xterm/xterm/./src/browser/renderer/shared/TextBlinkStateManager.ts","webpack://@xterm/xterm/./src/browser/scrollable/abstractScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/fastDomNode.ts","webpack://@xterm/xterm/./src/browser/scrollable/globalPointerMoveMonitor.ts","webpack://@xterm/xterm/./src/browser/scrollable/horizontalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/mouseEvent.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollable.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollableElement.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarArrow.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarState.ts","webpack://@xterm/xterm/./src/browser/scrollable/scrollbarVisibilityController.ts","webpack://@xterm/xterm/./src/browser/scrollable/touch.ts","webpack://@xterm/xterm/./src/browser/scrollable/verticalScrollbar.ts","webpack://@xterm/xterm/./src/browser/scrollable/widget.ts","webpack://@xterm/xterm/./src/browser/selection/SelectionModel.ts","webpack://@xterm/xterm/./src/browser/services/CharSizeService.ts","webpack://@xterm/xterm/./src/browser/services/CharacterJoinerService.ts","webpack://@xterm/xterm/./src/browser/services/CoreBrowserService.ts","webpack://@xterm/xterm/./src/browser/services/KeyboardService.ts","webpack://@xterm/xterm/./src/browser/services/LinkProviderService.ts","webpack://@xterm/xterm/./src/browser/services/MouseCoordsService.ts","webpack://@xterm/xterm/./src/browser/services/MouseService.ts","webpack://@xterm/xterm/./src/browser/services/RenderService.ts","webpack://@xterm/xterm/./src/browser/services/SelectionService.ts","webpack://@xterm/xterm/./src/browser/services/Services.ts","webpack://@xterm/xterm/./src/browser/services/ThemeService.ts","webpack://@xterm/xterm/./src/common/Async.ts","webpack://@xterm/xterm/./src/common/CircularList.ts","webpack://@xterm/xterm/./src/common/Color.ts","webpack://@xterm/xterm/./src/common/CoreTerminal.ts","webpack://@xterm/xterm/./src/common/Event.ts","webpack://@xterm/xterm/./src/common/InputHandler.ts","webpack://@xterm/xterm/./src/common/Lifecycle.ts","webpack://@xterm/xterm/./src/common/MultiKeyMap.ts","webpack://@xterm/xterm/./src/common/Platform.ts","webpack://@xterm/xterm/./src/common/SortedList.ts","webpack://@xterm/xterm/./src/common/StringBuilder.ts","webpack://@xterm/xterm/./src/common/TaskQueue.ts","webpack://@xterm/xterm/./src/common/Version.ts","webpack://@xterm/xterm/./src/common/WindowsMode.ts","webpack://@xterm/xterm/./src/common/buffer/AttributeData.ts","webpack://@xterm/xterm/./src/common/buffer/Buffer.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLine.ts","webpack://@xterm/xterm/./src/common/buffer/BufferLineStringCache.ts","webpack://@xterm/xterm/./src/common/buffer/BufferRange.ts","webpack://@xterm/xterm/./src/common/buffer/BufferReflow.ts","webpack://@xterm/xterm/./src/common/buffer/BufferSet.ts","webpack://@xterm/xterm/./src/common/buffer/CellData.ts","webpack://@xterm/xterm/./src/common/buffer/Constants.ts","webpack://@xterm/xterm/./src/common/buffer/Marker.ts","webpack://@xterm/xterm/./src/common/data/Charsets.ts","webpack://@xterm/xterm/./src/common/input/Keyboard.ts","webpack://@xterm/xterm/./src/common/input/KittyKeyboard.ts","webpack://@xterm/xterm/./src/common/input/TextDecoder.ts","webpack://@xterm/xterm/./src/common/input/UnicodeV6.ts","webpack://@xterm/xterm/./src/common/input/Win32InputMode.ts","webpack://@xterm/xterm/./src/common/input/WriteBuffer.ts","webpack://@xterm/xterm/./src/common/input/XParseColor.ts","webpack://@xterm/xterm/./src/common/parser/ApcParser.ts","webpack://@xterm/xterm/./src/common/parser/DcsParser.ts","webpack://@xterm/xterm/./src/common/parser/EscapeSequenceParser.ts","webpack://@xterm/xterm/./src/common/parser/OscParser.ts","webpack://@xterm/xterm/./src/common/parser/Params.ts","webpack://@xterm/xterm/./src/common/public/AddonManager.ts","webpack://@xterm/xterm/./src/common/public/BufferApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferLineApiView.ts","webpack://@xterm/xterm/./src/common/public/BufferNamespaceApi.ts","webpack://@xterm/xterm/./src/common/public/ParserApi.ts","webpack://@xterm/xterm/./src/common/public/UnicodeApi.ts","webpack://@xterm/xterm/./src/common/services/BufferService.ts","webpack://@xterm/xterm/./src/common/services/CharsetService.ts","webpack://@xterm/xterm/./src/common/services/CoreService.ts","webpack://@xterm/xterm/./src/common/services/DecorationService.ts","webpack://@xterm/xterm/./src/common/services/InstantiationService.ts","webpack://@xterm/xterm/./src/common/services/LogService.ts","webpack://@xterm/xterm/./src/common/services/MouseStateService.ts","webpack://@xterm/xterm/./src/common/services/OptionsService.ts","webpack://@xterm/xterm/./src/common/services/OscLinkService.ts","webpack://@xterm/xterm/./src/common/services/ServiceRegistry.ts","webpack://@xterm/xterm/./src/common/services/Services.ts","webpack://@xterm/xterm/./src/common/services/UnicodeService.ts","webpack://@xterm/xterm/webpack/bootstrap","webpack://@xterm/xterm/webpack/startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (␛).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.blur();\n }\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', (e: CompositionEvent) => {\n if (this._compositionHelper instanceof CompositionHelper) {\n if (this._compositionHelper.compositionend(e)) {\n this.textarea!.dispatchEvent(new CustomEvent(\n 'xterm-composition-transaction-accepted',\n { bubbles: true }\n ));\n }\n } else {\n this._compositionHelper!.compositionend();\n }\n }));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._register(toDisposable(() => {\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.dispose();\n }\n }));\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n if (!this._compositionHelper!.keypress?.(key)) {\n this.coreService.triggerDataEvent(key, true);\n }\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n if (\n ev.data &&\n ev.inputType === 'insertText' &&\n !this.optionsService.rawOptions.screenReaderMode &&\n this._compositionHelper instanceof CompositionHelper &&\n this._compositionHelper.input(ev.data)\n ) {\n return true;\n }\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): boolean | void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n keypress?(text: string): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\ninterface IPendingComposition {\n transactionId: number;\n finalizerTimer?: ReturnType;\n lifecycleSettled: boolean;\n sessionEnded: boolean;\n position: IPosition;\n suffix: string;\n dataAlreadySent: string;\n compositionData: string;\n endData: string;\n inputData: string;\n keypressData: string;\n keypressMayOverlapComposition: boolean;\n expectsPostCompositionInput: boolean;\n nextCompositionStart?: number;\n}\n\nconst XTERM_COMPOSITION_SESSION_START_EVENT = 'xterm-composition-session-start';\nconst XTERM_COMPOSITION_SESSION_END_EVENT = 'xterm-composition-session-end';\nconst XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT =\n 'xterm-composition-transaction-accepted';\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n public get hasPendingCompositionFinalization(): boolean {\n return this._pendingComposition !== undefined;\n }\n public get _isSendingComposition(): boolean {\n return this.hasPendingCompositionFinalization;\n }\n public get _pendingKeypressData(): string {\n return this._pendingComposition?.keypressData ?? '';\n }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n private _pendingComposition?: IPendingComposition;\n\n private _isAwaitingCompositionEnd: boolean;\n\n private _compositionInputData: string;\n\n private _lastCompositionData: string;\n\n private _compositionStartValue: string;\n\n private _compositionStartSelection: IPosition;\n\n private _compositionHasObservedProgress: boolean;\n\n private _canceledKey?: Pick;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n /**\n * Identifies the composition transaction that owns deferred work.\n */\n private _compositionTransactionId: number;\n\n /**\n * Timers that still own deferred composition state.\n */\n private _compositionTimers: Set>;\n\n private _compositionPositionTimer?: ReturnType;\n\n private _compositionViewTimer?: ReturnType;\n\n private _compositionEndTimer?: ReturnType;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isAwaitingCompositionEnd = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionStartValue = '';\n this._compositionStartSelection = { start: 0, end: 0 };\n this._compositionHasObservedProgress = false;\n this._compositionTransactionId = 0;\n this._compositionTimers = new Set();\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = undefined;\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = undefined;\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionStartValue = this._textarea.value;\n this._compositionStartSelection = { start, end };\n this._compositionHasObservedProgress = false;\n if (this._pendingComposition) {\n this._pendingComposition.nextCompositionStart = this._compositionPosition.start;\n }\n this._compositionTransactionId++;\n this._isComposing = true;\n this._isAwaitingCompositionEnd = true;\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionView.classList.add('active');\n this._dispatchCompositionSessionEvent(new CustomEvent(XTERM_COMPOSITION_SESSION_START_EVENT, {\n bubbles: true,\n detail: { id: this._compositionTransactionId }\n }));\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (ev.data?.length > 0) {\n this._lastCompositionData = ev.data;\n }\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data ?? ''}\\u200E`;\n this.updateCompositionElements();\n const transactionId = this._compositionTransactionId;\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = this._defer(() => {\n if (this._isComposing && this._compositionTransactionId === transactionId) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n });\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(ev?: Pick): boolean {\n if (!this._isAwaitingCompositionEnd) {\n return false;\n }\n if (!this._isComposing) {\n const pending = this._pendingComposition;\n if (pending?.transactionId === this._compositionTransactionId) {\n pending.endData = ev?.data ?? '';\n this._updatePostCompositionInputExpectation(pending);\n }\n return false;\n }\n const endData = ev?.data ?? '';\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (!this._compositionEndBelongsToCurrentTransaction(endData)) {\n const pending = this._pendingComposition;\n if (pending && pending.transactionId !== this._compositionTransactionId) {\n this._sendPendingComposition(pending);\n }\n this._deferCompositionEnd(endData);\n return false;\n }\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n return true;\n }\n\n public blur(): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._isComposing) {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n this._finalizeComposition(false);\n }\n }\n\n public dispose(): void {\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n for (const timer of this._compositionTimers) {\n clearTimeout(timer);\n }\n this._compositionTimers.clear();\n this._compositionPositionTimer = undefined;\n this._compositionViewTimer = undefined;\n this._compositionEndTimer = undefined;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionTransactionId++;\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._canceledKey?.code === ev.code && this._canceledKey.timeStamp === ev.timeStamp) {\n this._canceledKey = undefined;\n return false;\n }\n if (ev.key === 'Escape' && (this._isComposing || this.hasPendingCompositionFinalization)) {\n this._canceledKey = { code: ev.code, timeStamp: ev.timeStamp };\n this._cancelComposition();\n return false;\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Defers keypress text while a composition finalizer is pending so all input is emitted once\n * after reconciliation with the final textarea candidate.\n */\n public keypress(text: string): boolean {\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.keypressMayOverlapComposition) {\n pending.keypressData += text;\n return true;\n }\n if (pending.expectsPostCompositionInput && pending.keypressData.length === 0) {\n pending.keypressData = text;\n return true;\n }\n this._sendPendingComposition(pending);\n return false;\n }\n\n public input(text: string): boolean {\n if (this._isComposing) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n this._compositionInputData += text;\n return true;\n }\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.expectsPostCompositionInput) {\n pending.inputData += text;\n pending.expectsPostCompositionInput = false;\n this._sendPendingComposition(pending);\n return true;\n }\n const repeatsPendingTextareaInput =\n text.length > 0 &&\n this._getPendingTextareaInput(pending) === text &&\n this._getPendingTextareaInput(pending, true) === text;\n this._sendPendingComposition(pending);\n if (!repeatsPendingTextareaInput) {\n this._coreService.triggerDataEvent(text, true);\n }\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean, endData: string = ''): void {\n const wasComposing = this._isComposing;\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n if (waitForPropagation && !wasComposing) {\n return;\n }\n\n if (!waitForPropagation) {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition, true);\n }\n if (wasComposing) {\n const input = this._getCompositionInput(\n this._compositionPosition.start + this._dataAlreadySent.length,\n this._compositionSuffix\n );\n this._sendCompositionInput(this._compositionTransactionId, input);\n }\n } else {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition);\n }\n const pending: IPendingComposition = {\n transactionId: this._compositionTransactionId,\n lifecycleSettled: false,\n sessionEnded: false,\n position: {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n },\n suffix: this._compositionSuffix,\n dataAlreadySent: this._dataAlreadySent,\n compositionData: this._lastCompositionData,\n endData,\n inputData: this._compositionInputData,\n keypressData: '',\n keypressMayOverlapComposition:\n this._lastCompositionData.length === 0 && endData.length === 0,\n expectsPostCompositionInput: false\n };\n this._updatePostCompositionInputExpectation(pending);\n this._pendingComposition = pending;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n pending.finalizerTimer = this._defer(() => {\n pending.finalizerTimer = undefined;\n if (this._compositionTransactionId === pending.transactionId) {\n this._isAwaitingCompositionEnd = false;\n }\n if (this._pendingComposition === pending) {\n this._sendPendingComposition(pending, true);\n }\n });\n }\n }\n\n private _sendPendingComposition(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): void {\n this._cancelPendingFinalizer(pending);\n if (this._pendingComposition === pending) {\n this._pendingComposition = undefined;\n }\n const textareaInput = this._getPendingTextareaInput(pending, includeFollowingInput);\n const observedInput = this._removeAlreadySentData(\n pending.inputData || pending.keypressData,\n pending.dataAlreadySent\n );\n // Why: with no textarea, end, input, or keypress evidence the composition\n // was cancelled (e.g. Backspace over the whole preedit); stale\n // compositionupdate data must not be replayed as committed text.\n const input = this._mergeTextObservations(\n textareaInput || pending.endData || (observedInput ? pending.compositionData : ''),\n observedInput,\n pending.keypressMayOverlapComposition\n );\n this._sendCompositionInput(pending.transactionId, input, !pending.sessionEnded);\n this._settlePendingComposition(pending);\n }\n\n private _cancelPendingFinalizer(pending: IPendingComposition): void {\n if (pending.finalizerTimer === undefined) {\n return;\n }\n clearTimeout(pending.finalizerTimer);\n this._compositionTimers.delete(pending.finalizerTimer);\n pending.finalizerTimer = undefined;\n }\n\n private _settlePendingComposition(pending: IPendingComposition): void {\n if (pending.lifecycleSettled) {\n return;\n }\n pending.lifecycleSettled = true;\n this._dispatchCompositionTransactionSettled();\n }\n\n private _mergeTextObservations(\n candidate: string,\n observed: string,\n findShortestOrder: boolean\n ): string {\n if (!observed || candidate.includes(observed)) {\n return candidate;\n }\n if (!candidate || observed.includes(candidate)) {\n return observed;\n }\n if (findShortestOrder) {\n let candidateFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n candidateFirstOverlap > 0 &&\n !candidate.endsWith(observed.substring(0, candidateFirstOverlap))\n ) {\n candidateFirstOverlap--;\n }\n let observedFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n observedFirstOverlap > 0 &&\n !observed.endsWith(candidate.substring(0, observedFirstOverlap))\n ) {\n observedFirstOverlap--;\n }\n return candidateFirstOverlap > observedFirstOverlap\n ? candidate + observed.substring(candidateFirstOverlap)\n : observed + candidate.substring(observedFirstOverlap);\n }\n let overlap = Math.min(candidate.length, observed.length);\n while (overlap > 0 && !candidate.endsWith(observed.substring(0, overlap))) {\n overlap--;\n }\n return candidate + observed.substring(overlap);\n }\n\n private _updatePostCompositionInputExpectation(pending: IPendingComposition): void {\n pending.expectsPostCompositionInput =\n (pending.endData.length > 0 || pending.compositionData.length > 0) &&\n pending.inputData.length === 0 &&\n this._getPendingTextareaInput(pending).length === 0;\n }\n\n private _getPendingTextareaInput(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): string {\n const value = this._textarea.value;\n const start = pending.position.start + pending.dataAlreadySent.length;\n if (pending.nextCompositionStart !== undefined) {\n return value.substring(start, Math.max(start, pending.nextCompositionStart));\n }\n const suffixEnd =\n pending.suffix.length > 0 && value.endsWith(pending.suffix)\n ? value.length - pending.suffix.length\n : value.length;\n const compositionLength = (pending.endData || pending.compositionData).length;\n const observedEnd = includeFollowingInput\n ? suffixEnd\n : Math.max(pending.position.end, start + compositionLength);\n return value.substring(start, Math.max(start, Math.min(suffixEnd, observedEnd)));\n }\n\n private _getCompositionInput(start: number, suffix: string): string {\n const value = this._textarea.value;\n const valueEnd =\n suffix.length > 0 && value.endsWith(suffix) ? value.length - suffix.length : value.length;\n return value.substring(start, Math.max(start, valueEnd));\n }\n\n private _removeAlreadySentData(input: string, dataAlreadySent: string): string {\n if (dataAlreadySent.length === 0) {\n return input;\n }\n if (input.startsWith(dataAlreadySent)) {\n return input.substring(dataAlreadySent.length);\n }\n return dataAlreadySent.includes(input) ? '' : input;\n }\n\n private _cancelComposition(): void {\n const pending = this._pendingComposition;\n if (\n pending &&\n this._isComposing &&\n pending.transactionId !== this._compositionTransactionId\n ) {\n this._sendPendingComposition(pending);\n }\n const transactionId = this._isComposing\n ? this._compositionTransactionId\n : this._pendingComposition?.transactionId ?? 0;\n const settlesPending = pending !== undefined && this._pendingComposition === pending;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionView.classList.remove('active');\n this._textarea.value =\n this._textarea.value.substring(0, this._compositionPosition.start) + this._compositionSuffix;\n this._sendCompositionInput(transactionId, '');\n if (settlesPending && pending) {\n this._settlePendingComposition(pending);\n }\n }\n\n private _sendCompositionInput(\n transactionId: number,\n input: string,\n dispatchSessionEnd: boolean = true\n ): void {\n let prevented = false;\n if (dispatchSessionEnd) {\n const event = new CustomEvent(XTERM_COMPOSITION_SESSION_END_EVENT, {\n bubbles: true,\n cancelable: true,\n detail: { id: transactionId, data: input }\n });\n this._dispatchCompositionSessionEvent(event);\n prevented = event.defaultPrevented;\n }\n if (input.length > 0 && !prevented) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n\n private _endPendingCompositionSession(pending: IPendingComposition): void {\n if (pending.sessionEnded) {\n return;\n }\n pending.sessionEnded = true;\n const input =\n this._getPendingTextareaInput(pending) ||\n pending.endData ||\n pending.compositionData;\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_SESSION_END_EVENT,\n {\n bubbles: true,\n cancelable: true,\n detail: {\n id: pending.transactionId,\n data: input,\n dataPendingReconciliation: true\n }\n }\n ));\n }\n\n private _dispatchCompositionSessionEvent(event: CustomEvent): void {\n if (typeof this._textarea.dispatchEvent === 'function') {\n this._textarea.dispatchEvent(event);\n }\n }\n\n private _dispatchCompositionTransactionSettled(): void {\n this._dispatchCompositionSessionEvent(new CustomEvent(\n 'xterm-composition-transaction-settled',\n { bubbles: true }\n ));\n }\n\n private _deferCompositionEnd(endData: string): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n const transactionId = this._compositionTransactionId;\n const timer = this._defer(() => {\n if (\n this._compositionEndTimer !== timer ||\n !this._isComposing ||\n this._compositionTransactionId !== transactionId ||\n !this._compositionEndBelongsToCurrentTransaction(endData)\n ) {\n return;\n }\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT,\n { bubbles: true }\n ));\n const pending = this._pendingComposition;\n if (pending?.transactionId === transactionId) {\n this._sendPendingComposition(pending, true);\n }\n });\n this._compositionEndTimer = timer;\n }\n\n private _hasCompositionProgress(): boolean {\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n return this._compositionHasObservedProgress || (\n this._textarea.value !== this._compositionStartValue ||\n start !== this._compositionStartSelection.start ||\n end !== this._compositionStartSelection.end\n );\n }\n\n private _compositionEndBelongsToCurrentTransaction(endData: string): boolean {\n return (\n this._hasCompositionProgress() ||\n (endData.length > 0 && endData === this._lastCompositionData)\n );\n }\n\n private _defer(callback: () => void): ReturnType {\n const timer = setTimeout(() => {\n this._compositionTimers.delete(timer);\n callback();\n }, 0);\n this._compositionTimers.add(timer);\n return timer;\n }\n\n private _cancelDeferredTimer(timer?: ReturnType): void {\n if (timer === undefined) {\n return;\n }\n clearTimeout(timer);\n this._compositionTimers.delete(timer);\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = this._defer(() => this.updateCompositionElements(true));\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n","/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n","/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const INVERTED_DEFAULT_COLOR = 257;\n\nexport const enum RendererConstants {\n /**\n * The idle time after which cursor blinking stops.\n */\n CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n","import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n if (this._deleteAtKey(value, key)) {\n return true;\n }\n // A pending deletion whose key mutated after `delete()` (disposing a marker\n // resets `line` to -1, and `line` is the sort key) leaves `_array` out of\n // order, so the binary search above can miss a value that is present.\n // Compacting those entries out restores the order; retry before reporting\n // the value absent, else its `onDecorationRemoved` never fires and the\n // decoration paints forever. Miss path only, so the common bulk delete\n // keeps its O(log n) search and deferred-compaction batching.\n if (this._deletedIndices.length === 0) {\n return false;\n }\n this._flushCleanupDeleted();\n return this._deleteAtKey(value, key);\n }\n\n private _deleteAtKey(value: T, key: number): boolean {\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n²) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const DEFAULT_COLOR = 0;\nexport const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);\nexport const DEFAULT_EXT = 0;\n\nexport const CHAR_DATA_ATTR_INDEX = 0;\nexport const CHAR_DATA_CHAR_INDEX = 1;\nexport const CHAR_DATA_WIDTH_INDEX = 2;\nexport const CHAR_DATA_CODE_INDEX = 3;\n\n/**\n * Null cell - a real empty cell (containing nothing).\n * Note that code should always be 0 for a null cell as\n * several test condition of the buffer line rely on this.\n */\nexport const NULL_CELL_CHAR = '';\nexport const NULL_CELL_WIDTH = 1;\nexport const NULL_CELL_CODE = 0;\n\n/**\n * Whitespace cell.\n * This is meant as a replacement for empty cells when needed\n * during rendering lines to preserve correct alignment.\n */\nexport const WHITESPACE_CELL_CHAR = ' ';\nexport const WHITESPACE_CELL_WIDTH = 1;\nexport const WHITESPACE_CELL_CODE = 32;\n\n/**\n * Bitmasks for accessing data in `content`.\n */\nexport const enum Content {\n /**\n * bit 1..21 codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)\n * read: `codepoint = content & Content.CODEPOINT_MASK;`\n * write: `content |= codepoint & Content.CODEPOINT_MASK;`\n * shortcut if precondition `codepoint <= 0x10FFFF` is met:\n * `content |= codepoint;`\n */\n CODEPOINT_MASK = 0x1FFFFF,\n\n /**\n * bit 22 flag indicating whether a cell contains combined content\n * read: `isCombined = content & Content.IS_COMBINED_MASK;`\n * set: `content |= Content.IS_COMBINED_MASK;`\n * clear: `content &= ~Content.IS_COMBINED_MASK;`\n */\n IS_COMBINED_MASK = 0x200000, // 1 << 21\n\n /**\n * bit 1..22 mask to check whether a cell contains any string data\n * we need to check for codepoint and isCombined bits to see\n * whether a cell contains anything\n * read: `isEmpty = !(content & Content.HAS_CONTENT_MASK)`\n */\n HAS_CONTENT_MASK = 0x3FFFFF,\n\n /**\n * bit 23..24 wcwidth value of cell, takes 2 bits (ranges from 0..2)\n * read: `width = (content & Content.WIDTH_MASK) >> Content.WIDTH_SHIFT;`\n * `hasWidth = content & Content.WIDTH_MASK;`\n * as long as wcwidth is highest value in `content`:\n * `width = content >> Content.WIDTH_SHIFT;`\n * write: `content |= (width << Content.WIDTH_SHIFT) & Content.WIDTH_MASK;`\n * shortcut if precondition `0 <= width <= 3` is met:\n * `content |= width << Content.WIDTH_SHIFT;`\n */\n WIDTH_MASK = 0xC00000, // 3 << 22\n WIDTH_SHIFT = 22\n}\n\nexport const enum Attributes {\n /**\n * bit 1..8 blue in RGB, color in P256 and P16\n */\n BLUE_MASK = 0xFF,\n BLUE_SHIFT = 0,\n PCOLOR_MASK = 0xFF,\n PCOLOR_SHIFT = 0,\n\n /**\n * bit 9..16 green in RGB\n */\n GREEN_MASK = 0xFF00,\n GREEN_SHIFT = 8,\n\n /**\n * bit 17..24 red in RGB\n */\n RED_MASK = 0xFF0000,\n RED_SHIFT = 16,\n\n /**\n * bit 25..26 color mode: DEFAULT (0) | P16 (1) | P256 (2) | RGB (3)\n */\n CM_MASK = 0x3000000,\n CM_DEFAULT = 0,\n CM_P16 = 0x1000000,\n CM_P256 = 0x2000000,\n CM_RGB = 0x3000000,\n\n /**\n * bit 1..24 RGB room\n */\n RGB_MASK = 0xFFFFFF\n}\n\nexport const enum FgFlags {\n /**\n * bit 27..32\n */\n INVERSE = 0x4000000,\n BOLD = 0x8000000,\n UNDERLINE = 0x10000000,\n BLINK = 0x20000000,\n INVISIBLE = 0x40000000,\n STRIKETHROUGH = 0x80000000,\n}\n\nexport const enum BgFlags {\n /**\n * bit 27..32 (upper 2 unused)\n */\n ITALIC = 0x4000000,\n DIM = 0x8000000,\n HAS_EXTENDED = 0x10000000,\n PROTECTED = 0x20000000,\n OVERLINE = 0x40000000\n}\n\nexport const enum ExtFlags {\n /**\n * bit 27..29\n */\n UNDERLINE_STYLE = 0x1C000000,\n\n /**\n * bit 30..32\n *\n * An optional variant for the glyph, this can be used for example to offset underlines by a\n * number of pixels to create a perfect pattern.\n */\n VARIANT_OFFSET = 0xE0000000\n}\n\nexport const enum UnderlineStyle {\n NONE = 0,\n SINGLE = 1,\n DOUBLE = 2,\n CURLY = 3,\n DOTTED = 4,\n DASHED = 5\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u2409', // '␉' (HT)\n 'c': '\\u240c', // '␌' (FF)\n 'd': '\\u240d', // '␍' (CR)\n 'e': '\\u240a', // '␊' (LF)\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '␤' (NL)\n 'i': '\\u240b', // '␋' (VT)\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec § \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" — i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n","\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n","/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n","/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n","/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(6081);\n"],"names":["root","factory","exports","module","define","amd","a","i","globalThis","Strings","__importStar","__webpack_require__","TimeBasedDebouncer_1","Lifecycle_1","Services_1","Services_2","Dom_1","AccessibilityManager","Disposable","constructor","_terminal","instantiationService","_coreBrowserService","_renderService","super","this","_rowColumns","WeakMap","_liveRegionLineCount","_charsToConsume","_charsToAnnounce","doc","mainDocument","_accessibilityContainer","createElement","classList","add","_rowContainer","setAttribute","_rowElements","rows","_createAccessibilityTreeNode","appendChild","_topBoundaryFocusListener","e","_handleBoundaryFocus","_bottomBoundaryFocusListener","addEventListener","length","_liveRegion","_liveRegionDebouncer","_register","TimeBasedDebouncer","_renderRows","bind","element","Error","insertAdjacentElement","onResize","_handleResize","onRender","_refreshRows","start","end","onScroll","onA11yChar","char","_handleChar","onLineFeed","onA11yTab","spaceCount","_handleTab","onKey","_handleKey","key","onBlur","_clearLiveRegion","onDimensionsChange","_refreshRowsDimensions","addDisposableListener","_handleSelectionChange","onDprChange","toDisposable","remove","shift","textContent","tooMuchOutput","get","keyChar","test","push","refresh","buffer","setSize","lines","toString","line","ydisp","columns","lineData","translateToString","undefined","posInSet","set","_alignRowWidth","_announceCharacters","position","boundaryElement","target","beforeBoundaryElement","getAttribute","relatedTarget","topBoundaryElement","bottomBoundaryElement","pop","removeChild","removeEventListener","newElement","unshift","scrollLines","focus","preventDefault","stopImmediatePropagation","selection","getSelection","isCollapsed","contains","anchorNode","clearSelection","focusNode","console","error","begin","node","offset","anchorOffset","focusOffset","compareDocumentPosition","Node","DOCUMENT_POSITION_PRECEDING","DOCUMENT_POSITION_CONTAINED_BY","DOCUMENT_POSITION_FOLLOWING","childNodes","lastRowElement","slice","toRowColumn","rowElement","Text","parentNode","row","parseInt","isNaN","warn","column","cols","beginRowColumn","endRowColumn","select","children","tabIndex","_refreshRowDimensions","dimensions","css","cell","height","Object","assign","style","width","canvas","fontSize","options","transform","getBoundingClientRect","lastColumn","targetWidth","__decorate","__param","IInstantiationService","ICoreBrowserService","IRenderService","prepareTextForTerminal","text","replace","bracketTextForPaste","bracketedPasteMode","paste","textarea","coreService","optionsService","decPrivateModes","rawOptions","ignoreBracketedPasteMode","triggerDataEvent","value","moveTextAreaUnderMouseCursor","ev","screenElement","pos","left","clientX","top","clientY","zIndex","selectionService","clipboardData","setData","selectionText","stopPropagation","getData","shouldSelectWord","rightClickSelect","MultiKeyMap_1","_color","TwoKeyMap","_css","setCss","bg","fg","getCss","setColor","getColor","clear","Clipboard_1","OscLinkProvider_1","Viewport_1","BufferDecorationRenderer_1","OverviewRulerRenderer_1","CompositionHelper_1","DomRenderer_1","CharSizeService_1","CharacterJoinerService_1","CoreBrowserService_1","LinkProviderService_1","MouseCoordsService_1","MouseService_1","RenderService_1","SelectionService_1","ThemeService_1","KeyboardService_1","Color_1","CoreTerminal_1","Browser","BufferLine_1","XParseColor_1","DecorationService_1","InputHandler_1","AccessibilityManager_1","Linkifier_1","Event_1","CoreBrowserTerminal","CoreTerminal","linkifier","_linkifier","onFocus","_onFocus","event","_onBlur","_onA11yCharEmitter","_onA11yTabEmitter","onWillOpen","_onWillOpen","device","MutableDisposable","browser","_keyDownHandled","_keyDownSeen","_keyPressHandled","_unprocessedDeadKey","_accessibilityManager","_onCursorMove","Emitter","onCursorMove","_onKey","_onSelectionChange","onSelectionChange","_onTitleChange","onTitleChange","_onBell","onBell","_onDimensionsChange","_setup","_decorationService","_instantiationService","createInstance","DecorationService","setService","IDecorationService","_keyboardService","KeyboardService","IKeyboardService","_linkProviderService","LinkProviderService","ILinkProviderService","registerLinkProvider","OscLinkProvider","_inputHandler","onRequestBell","fire","onRequestRefreshRows","onRequestSendFocus","_reportFocus","onRequestReset","reset","onRequestWindowsOptionsReport","type","_reportWindowsOptions","onColor","_handleColorEvent","EventUtils","forward","_bufferService","_afterResize","_customKeyEventHandler","_themeService","req","acc","ident","index","colorRgb","color","toColorRGB","colors","ansi","toRgbString","modifyColors","channels","toColor","narrowedAcc","restoreColor","_reportColorScheme","colorSchemeMode","rgb","relativeLuminance","background","rgba","foreground","buffers","active","preventScroll","_handleScreenReaderModeOptionChange","_handleTextAreaFocus","sendFocus","_showCursor","blur","_handleTextAreaBlur","_compositionHelper","CompositionHelper","y","_syncTextArea","isCursorInViewport","isComposing","cursorY","ybase","bufferLine","cursorX","Math","min","x","cellHeight","getWidth","cellWidth","cursorTop","cursorLeft","lineHeight","_initGlobal","_bindKeys","hasSelection","copyHandler","_selectionService","pasteHandlerWrapper","handlePasteEvent","isFirefox","button","rightClickHandler","rightClickSelectsWord","isLinux","_keyUp","_keyDown","_keyPress","compositionstart","updateCompositionElements","compositionupdate","compositionend","dispatchEvent","CustomEvent","bubbles","_inputEvent","open","parent","isConnected","_logService","debug","ownerDocument","defaultView","window","_document","documentOverride","Document","dir","toggle","allowTransparency","onSpecificOptionChange","fragment","createDocumentFragment","_viewportElement","updateCursorStyle","_helperContainer","promptLabel","isChromeOS","readOnly","disableStdin","CoreBrowserService","document","_charSizeService","CharSizeService","ICharSizeService","ThemeService","IThemeService","onRequestColorSchemeQuery","onChangeColors","colorSchemeUpdates","_characterJoinerService","CharacterJoinerService","ICharacterJoinerService","RenderService","onRenderedViewportChange","_onRender","resize","_compositionView","dispose","_mouseCoordsService","MouseCoordsService","IMouseCoordsService","Linkifier","hasRenderer","setRenderer","_createRenderer","handleCursorMove","handleResize","handleBlur","handleFocus","_viewport","Viewport","onRequestScrollLines","SelectionService","ISelectionService","_mouseService","MouseService","IMouseService","amount","suppressScrollEvent","onRequestRedraw","handleSelectionChanged","columnSelectMode","onLinuxMouseSelection","any","_onScroll","queueSync","BufferDecorationRenderer","handleMouseDown","mouseStateService","areMouseEventsActive","mouseEventsRequireAlt","disable","enable","screenReaderMode","showScrollbar","scrollbar","overviewRulerWidth","_overviewRulerRenderer","OverviewRulerRenderer","shouldShow","measure","bindMouse","handleTouchScroll","disposable","DomRenderer","sync","refreshRows","shouldColumnSelect","isCursorInitialized","disp","scrollPages","pageCount","scrollToTop","scrollToBottom","disableSmoothScroll","scrollToLine","scrollAmount","data","attachCustomKeyEventHandler","customKeyEventHandler","attachCustomWheelEventHandler","customWheelEventHandler","setCustomWheelEventHandler","linkProvider","registerCharacterJoiner","handler","joinerId","register","deregisterCharacterJoiner","deregister","markers","registerMarker","cursorYOffset","addMarker","registerDecoration","decorationOptions","setSelection","getSelectionPosition","selectionStart","selectionEnd","selectAll","selectLines","shouldIgnoreComposition","isMac","macOptionIsMeta","altKey","keydown","scrollOnUserInput","result","evaluateKeyDown","scrollCount","_isThirdLevelShift","cancel","useKitty","useWin32InputMode","ctrlKey","metaKey","charCodeAt","wasModifierOnly","wasModifierKeyOnlyEvent","domEvent","thirdLevelKey","isWindows","getModifierState","keyCode","evaluateKeyUp","charCode","which","String","fromCharCode","keypress","inputType","input","composed","hasValidSize","clearAllMarkers","getBlankLine","DEFAULT_ATTR_DATA","clearTextureAtlas","WindowsOptionsReportType","GET_WIN_SIZE_PIXELS","canvasWidth","toFixed","canvasHeight","GET_CELL_SIZE_PIXELS","useCapture","domNode","bb","win","getWindow","scrollX","scrollY","targetWindow","runner","priority","state","getAnimationFrameState","item","AnimationFrameQueueItem","next","animFrameRequested","requestAnimationFrame","current","inAnimationFrameRunner","sort","execute","animationFrameRunner","Async_1","candidateNode","candidateEvent","view","DomListener","_node","_type","_handler","_options","useCaptureOrOptions","eventType","CLICK","MOUSE_DOWN","MOUSE_OVER","MOUSE_LEAVE","KEY_DOWN","KEY_UP","INPUT","BLUR","FOCUS","CHANGE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","MOUSE_WHEEL","WHEEL","_runner","_canceled","b","animationFrameState","Map","WindowIntervalTimer","IntervalTimer","_defaultTarget","cancelAndSet","interval","currentLink","_currentLink","_element","_linkCacheDisposables","_isMouseOut","_wasResized","_activeLine","_onShowLinkUnderline","onShowLinkUnderline","_onHideLinkUnderline","onHideLinkUnderline","_lastMouseEvent","_activeProviderReplies","_clearCurrentLink","_handleMouseMove","_handleMouseDown","_handleMouseUp","_positionFromMouseEvent","composedPath","_lastBufferCell","_handleHover","_askForLink","_linkAtPosition","link","useLineCache","forEach","reply","linkWithState","linkProvided","linkProviders","entries","existingReply","_checkLinkProviderResult","provideLinks","links","linksWithState","map","size","_removeIntersectingLinks","replies","occupiedCells","Set","providerReply","startX","range","endX","has","splice","hasLinkBefore","j","linkAtPosition","find","_handleNewLink","_mouseDownLink","activate","startRow","endRow","_linkLeave","decorations","underline","pointerCursor","isHovered","_linkHover","defineProperties","v","_fireUnderlineEvent","hover","showEvent","scrollOffset","_createLinkUnderlineEvent","leave","lower","upper","coords","getCoords","x1","y1","x2","y2","IBufferService","promptLabelInternal","tooMuchOutputInternal","CellData_1","_optionsService","_oscLinkService","_workCell","CellData","callback","linkHandler","lineLength","getTrimmedLength","currentLinkId","currentStart","finishLink","hasContent","loadCell","hasExtendedAttrs","extended","urlId","getLinkData","uri","_getRangeWithLineWrap","ignoreLink","allowNonHttpProtocols","parsed","URL","includes","protocol","defaultActivate","linkId","startY","finalStartX","endY","finalEndX","currentLine","isWrapped","previousLine","previousLineLength","_hasUrlId","previousStartX","nextLine","nextLineLength","nextEndX","confirm","newWindow","opener","location","href","IOptionsService","IOscLinkService","_renderCallback","_refreshCallbacks","_animationFrame","cancelAnimationFrame","addRefreshCallback","_innerRefresh","rowStart","rowEnd","rowCount","_rowCount","_rowStart","_rowEnd","max","_runRefreshCallbacks","_debounceThresholdMS","_lastRefreshMs","_additionalRefreshRequested","_refreshTimeoutID","clearTimeout","refreshRequestTime","performance","now","elapsed","waitPeriodBeforeTrailingRefresh","setTimeout","DEFAULT_ANSI_COLORS","freeze","r","g","toCss","toRgba","c","scrollableElement_1","scrollable_1","coreBrowserService","_coreService","themeService","_onRequestScrollLines","_isSyncing","_isHandlingScroll","_suppressOnScrollHandler","_needsSyncOnRender","scrollable","Scrollable","forceIntegerValues","smoothScrollDuration","scheduleAtNextAnimationFrame","cb","setSmoothScrollDuration","_scrollableElement","SmoothScrollableElement","vertical","horizontal","useShadows","mouseWheelSmoothScroll","verticalHasArrows","showArrows","_getChangeOptions","onMultipleOptionChange","updateOptions","onProtocolChange","handleMouseWheel","setScrollDimensions","scrollHeight","runAndSubscribe","backgroundColor","getDomNode","_styleElement","scrollbarSliderBackground","scrollbarSliderHoverBackground","scrollbarSliderActiveBackground","join","onBufferActivate","_latestYDisp","_sync","_handleScroll","getScrollPosition","setScrollPosition","reuseAnimation","scrollTop","verticalScrollbarSize","mouseWheelScrollSensitivity","scrollSensitivity","fastScrollSensitivity","_queuedAnimationFrame","synchronizedOutput","newRow","round","diff","translationY","ICoreService","IMouseStateService","_screenElement","_decorationElements","_altBufferIsActive","_dimensionsChanged","_container","_doRefreshDecorations","_queueRefresh","alt","onDecorationRegistered","onDecorationRemoved","decoration","_removeDecoration","_renderDecoration","_refreshStyle","_refreshXPosition","_createElement","layer","marker","display","onRenderEmitter","onDispose","delete","anchor","right","_zones","_zonePool","_zonePoolIndex","_linePadding","full","center","zones","addDecoration","overviewRulerOptions","z","_lineIntersectsZone","_lineAdjacentToZone","_addLineToZone","startBufferLine","endBufferLine","setPadding","padding","zone","ColorZoneStore_1","drawHeight","drawWidth","drawX","_width","_colorZoneStore","ColorZoneStore","_shouldUpdateDimensions","_shouldUpdateAnchor","_lastKnownBufferLength","_canvas","_refreshCanvasDimensions","parentElement","insertBefore","ctx","getContext","_ctx","normal","_refreshDrawHeightConstants","_refreshColorZonePadding","_refreshDrawConstants","outerWidth","floor","innerWidth","ceil","dpr","pixelsPerLine","nonFullHeight","_store","isDisposed","cssCanvasHeight","deviceCanvasHeight","_refreshDecorations","clearRect","lineWidth","_renderRulerOutline","_renderColorZone","fillStyle","overviewRulerBorder","fillRect","overviewRuler","showTopBorder","showBottomBorder","updateCanvasDimensions","updateAnchor","XTERM_COMPOSITION_SESSION_END_EVENT","_isComposing","hasPendingCompositionFinalization","_pendingComposition","_isSendingComposition","_pendingKeypressData","keypressData","_textarea","_isAwaitingCompositionEnd","_compositionPosition","_compositionSuffix","_dataAlreadySent","_compositionInputData","_lastCompositionData","_compositionStartValue","_compositionStartSelection","_compositionHasObservedProgress","_compositionTransactionId","_compositionTimers","_cancelDeferredTimer","_compositionPositionTimer","_compositionViewTimer","_compositionEndTimer","_textareaChangeTimer","nextCompositionStart","substring","_dispatchCompositionSessionEvent","detail","id","_hasCompositionProgress","transactionId","_defer","pending","endData","_updatePostCompositionInputExpectation","_compositionEndBelongsToCurrentTransaction","_sendPendingComposition","_deferCompositionEnd","_finalizeComposition","timer","_canceledKey","code","timeStamp","_cancelComposition","_handleAnyTextareaChanges","keypressMayOverlapComposition","expectsPostCompositionInput","inputData","repeatsPendingTextareaInput","_getPendingTextareaInput","waitForPropagation","wasComposing","lifecycleSettled","sessionEnded","suffix","dataAlreadySent","compositionData","finalizerTimer","_getCompositionInput","_sendCompositionInput","includeFollowingInput","_cancelPendingFinalizer","textareaInput","observedInput","_removeAlreadySentData","_mergeTextObservations","_settlePendingComposition","_dispatchCompositionTransactionSettled","candidate","observed","findShortestOrder","candidateFirstOverlap","endsWith","observedFirstOverlap","overlap","suffixEnd","compositionLength","observedEnd","valueEnd","startsWith","settlesPending","dispatchSessionEnd","prevented","cancelable","defaultPrevented","_endPendingCompositionSession","dataPendingReconciliation","oldValue","newValue","dontRecurse","fontFamily","maxWidth","overflow","direction","compositionViewBounds","getCoordsRelativeToElement","rect","elementStyle","getComputedStyle","leftPadding","getPropertyValue","topPadding","colCount","hasValidCharSize","cssCellWidth","cssCellHeight","isSelection","moveToRequestedRow","targetY","bufferService","applicationCursor","wrappedRowsForRow","rowsToMove","abs","wrappedRows","verticalDirection","wrappedRowsCount","repeat","sequence","currentRow","lineWraps","startCol","endCol","currentCol","bufferStr","translateBufferLineToString","count","str","rpt","targetX","hasScrollback","resetStartingRow","horizontalDirection","moveToRequestedCol","rowDifference","currX","colsFromRowEnd","CoreBrowserTerminal_1","AddonManager_1","BufferNamespaceApi_1","ParserApi_1","UnicodeApi_1","CONSTRUCTOR_ONLY_OPTIONS","$value","Terminal","_core","_addonManager","AddonManager","_publicOptions","getter","propName","setter","_checkReadonlyOptions","desc","defineProperty","_checkProposedApi","allowProposedApi","onBinary","onData","onWriteParsed","parser","_parser","ParserApi","unicode","UnicodeApi","_buffer","BufferNamespaceApi","modes","m","mouseTrackingMode","activeProtocol","applicationCursorKeysMode","applicationCursorKeys","applicationKeypadMode","applicationKeypad","insertMode","originMode","origin","reverseWraparoundMode","reverseWraparound","sendFocusMode","showCursor","isCursorHidden","synchronizedOutputMode","win32InputMode","wraparoundMode","wraparound","wasUserInput","_verifyIntegers","_verifyPositiveIntegers","write","writeln","loadAddon","addon","strings","values","Infinity","DomRendererRowFactory_1","WidthCache_1","Constants_1","RendererUtils_1","SelectionRenderModel_1","TextBlinkStateManager_1","nextTerminalId","_linkifier2","_terminalClass","_selectionRenderModel","createSelectionRenderModel","_lastSelectionColumnMode","_rowHasBlinkingCells","_rowHasBlinkingCellsCount","_onRequestRedraw","_refreshRowElements","_selectionContainer","createRenderDimensions","_updateDimensions","onOptionChange","_handleOptionsChanged","_injectCss","_rowFactory","DomRendererRowFactory","_handleLinkHover","_handleLinkLeave","_cursorBlinkStateManager","CursorBlinkStateManager","restartBlinkAnimation","_textBlinkStateManager","TextBlinkStateManager","_widthCache","_themeStyleElement","_dimensionsStyleElement","WidthCache","setFont","fontWeight","fontWeightBold","_setDefaultSpacing","letterSpacing","styles","_terminalSelector","multiplyOpacity","blinkAnimationUnderlineId","blinkAnimationBarId","blinkAnimationBlockId","cursor","cursorAccent","cursorWidth","selectionBackgroundOpaque","selectionInactiveBackgroundOpaque","INVERTED_DEFAULT_COLOR","opaque","spacing","defaultSpacing","handleDevicePixelRatioChange","handleCharSizeChanged","pause","renderRows","resume","handleViewportVisibilityChange","isVisible","setViewportVisible","replaceChildren","oldViewportStart","oldViewportEnd","_lastSelectionStart","_lastSelectionEnd","update","viewportCappedStartRow","viewportCappedEndRow","newViewportStart","newViewportEnd","viewportStartRow","viewportEndRow","documentFragment","isXFlipped","_createSelectionElement","middleRowsCount","finalEndCol","renderStartRow","renderEndRow","cursorViewportRow","colStart","colEnd","fill","setNeedsBlinkInViewport","cursorAbsoluteY","cursorBlink","cursorStyle","cursorInactiveStyle","rowInfo","hasBlinkingCells","createRow","isBlinkOn","_setRowBlinkState","_updateTextBlinkState","_setCellUnderline","enabled","maxY","bufferline","_isIdlePaused","isFocused","_resetIdleTimer","_clearIdleTimer","_idleTimeout","_stopBlinkingDueToIdle","Constants_2","AttributeData_1","_columnSelectMode","_selectionStart","_selectionEnd","isCursorRow","blinkOn","widthCache","linkStart","linkEnd","elements","joinedRanges","getJoinedCharacters","charElement","getNoBgTrimmedLength","cellAmount","oldBg","oldFg","oldExt","oldLinkHover","oldSpacing","oldIsInSelection","skipJoinedCheckUntilX","classes","hasHover","isJoined","isValidJoinRange","lastCharX","firstSelectionState","_isCellInSelection","JoinedCellData","isInSelection","isCursorCell","isLinkHover","isBlink","isDecorated","forEachDecorationAtCell","d","chars","getChars","WHITESPACE_CELL_CHAR","isUnderline","isOverline","isBold","isItalic","selectionForeground","ext","isInvisible","isDim","underlineStyle","isUnderlineColorDefault","isUnderlineColorRGB","textDecorationColor","AttributeData","getUnderlineColor","drawBoldTextInBrightColors","isStrikethrough","textDecoration","getFgColor","fgColorMode","getFgColorMode","getBgColor","bgColorMode","getBgColorMode","isInverse","temp","temp2","bgOverride","fgOverride","resolvedBg","isTop","backgroundColorRGB","foregroundColorRGB","_addStyle","padStart","_applyMinimumContrast","className","minimumContrastRatio","treatGlyphAsBackgroundColor","getCode","cache","_getContrastCache","adjustedColor","ratio","ensureContrastRatio","halfContrastCache","contrastCache","canvasFactory","WidthCacheFontVariantCanvas","_flat","Float32Array","_font","_fontSize","_weight","_weightBold","_canvasElements","_holey","font","weight","weightBold","bold","italic","cp","_measure","variant","OffscreenCanvas","throwIfFalsy","fontStyle","trim","measureText","isPowerlineGlyph","codepoint","isEmoji","glyphSizeX","deviceCellWidth","isNerdFontGlyph","isBoxOrBlockGlyph","currentOffset","SelectionRenderModel","terminal","viewportY","isCellSelected","_intervalDuration","_blinkOn","_needsBlinkInViewport","_isViewportVisible","duration","setIntervalDuration","blinkIntervalDuration","_clearInterval","isEnabled","needsBlinkInViewport","_updateIntervalState","_interval","wasBlinkOn","setInterval","clearInterval","dom","fastDomNode_1","globalPointerMoveMonitor_1","scrollbarArrow_1","scrollbarVisibilityController_1","widget_1","platform","AbstractScrollbar","Widget","opts","_lazyRender","lazyRender","_host","host","_scrollable","_scrollByPage","scrollByPage","_scrollbarState","scrollbarState","_visibilityController","ScrollbarVisibilityController","visibility","extraScrollbarClassName","setIsNeeded","isNeeded","_pointerMoveMonitor","GlobalPointerMoveMonitor","_shouldRender","FastDomNode","setDomNode","setPosition","_domNodePointerDown","_createArrow","arrow","ScrollbarArrow","bgDomNode","_createSlider","slider","setClassName","setTop","setLeft","setWidth","setHeight","setLayerHinting","setContain","_sliderPointerDown","_onclick","leftButton","_handleElementSize","visibleSize","setVisibleSize","render","_handleElementScrollSize","elementScrollSize","setScrollSize","_handleElementScrollPosition","elementScrollPosition","beginReveal","setShouldBeVisible","beginHide","_renderDomNode","getRectangleLargeSize","getRectangleSmallSize","_updateSlider","getSliderSize","getArrowSize","getSliderPosition","_handlePointerDown","delegatePointerDown","domTop","getClientRects","sliderStart","sliderStop","pointerPos","_sliderPointerPosition","offsetX","offsetY","domNodePosition","getDomNodePagePosition","pageX","pageY","_pointerDownRelativePosition","_setDesiredScrollPositionNow","getDesiredScrollPositionFromOffsetPaged","getDesiredScrollPositionFromOffset","Element","initialPointerPosition","initialPointerOrthogonalPosition","_sliderOrthogonalPointerPosition","initialScrollbarState","clone","toggleClassName","startMonitoring","pointerId","buttons","pointerMoveData","pointerOrthogonalPosition","pointerOrthogonalDelta","pointerDelta","getDesiredScrollPositionFromDelta","handleDragEnd","handleDragStart","_desiredScrollPosition","desiredScrollPosition","writeScrollPosition","setScrollPositionNow","updateScrollbarSize","scrollbarSize","_updateScrollbarSize","setScrollbarSize","numberAsPixels","_height","_top","_left","_bottom","_right","_className","_position","_layerHint","_contain","setBottom","bottom","setRight","shouldHaveIt","layerHint","contain","name","_hooks","DisposableStore","_pointerMoveCallback","_onStopCallback","stopMonitoring","invokeStopCallback","isMonitoring","onStopCallback","initialElement","initialButtons","pointerMoveCallback","eventSource","setPointerCapture","releasePointerCapture","abstractScrollbar_1","scrollbarState_1","HorizontalScrollbar","scrollDimensions","getScrollDimensions","scrollPosition","getCurrentScrollPosition","ScrollbarState","horizontalHasArrows","horizontalScrollbarSize","scrollWidth","scrollLeft","horizontalSliderSize","sliderSize","sliderPosition","largeSize","smallSize","handleScroll","setOppositeScrollbarSize","setVisibility","sameOriginWindowChainCache","getParentWindowIfSameOrigin","w","parentLocation","IframeUtils","_getSameOriginWindowChain","windowChainCache","WeakRef","iframeElement","frameElement","getPositionOfChildWindowRelativeToAncestorWindow","childWindow","ancestorWindow","windowChain","windowChainEl","windowInChain","deref","boundingRect","timestamp","Date","browserEvent","middleButton","rightButton","shiftKey","posx","posy","body","documentElement","iframeOffsets","deltaX","deltaY","targetNode","srcElement","shouldFactorDPR","isChrome","chromeVersionMatch","navigator","userAgent","match","e1","e2","devicePixelRatio","wheelDeltaY","VERTICAL_AXIS","axis","deltaMode","DOM_DELTA_LINE","wheelDeltaX","isSafari","HORIZONTAL_AXIS","wheelDelta","ScrollState","_forceIntegerValues","_scrollStateBrand","rawScrollLeft","rawScrollTop","equals","other","withScrollDimensions","useRawScrollPositions","withScrollPosition","createScrollEvent","previous","inSmoothScrolling","widthChanged","scrollWidthChanged","scrollLeftChanged","heightChanged","scrollHeightChanged","scrollTopChanged","oldWidth","oldScrollWidth","oldScrollLeft","oldHeight","oldScrollHeight","oldScrollTop","_scrollableBrand","_smoothScrollDuration","_scheduleAtNextAnimationFrame","_state","_smoothScrolling","validateScrollPosition","newState","_setState","Boolean","acceptScrollDimensions","getFutureScrollPosition","to","setScrollPositionSmooth","validTarget","newSmoothScrolling","SmoothScrollingOperation","from","startTime","animationFrameDisposable","_performSmoothScrolling","hasPendingScrollAnimation","tick","isDone","oldState","SmoothScrollingUpdate","createEaseOutCubic","delta","completion","t","pow","_initAnimations","_scrollLeft","_initAnimation","_scrollTop","viewportSize","stop1","stop2","cut","_tick","newScrollLeft","newScrollTop","mouseEvent_1","horizontalScrollbar_1","verticalScrollbar_1","MouseWheelClassifierItem","score","MouseWheelClassifier","_capacity","_memory","_front","_rear","isPhysicalMouseWheel","remainingInfluence","iteration","influence","acceptStandardWheelEvent","pageZoomFactor","getZoomFactor","accept","previousItem","_computeScore","_isAlmostInt","absDeltaX","absDeltaY","absPreviousDeltaX","absPreviousDeltaY","minDeltaX","minDeltaY","maxDeltaX","maxDeltaY","INSTANCE","resolvedScrollable","ownsScrollable","flipAxes","consumeMouseWheelIfScrollbarIsNeeded","alwaysConsumeMouseWheel","scrollYToX","scrollPredominantAxis","listenOnDomNode","verticalSliderSize","resolveOptions","scrollbarHost","mouseWheelEvent","_handleMouseWheel","_handleDragStart","_handleDragEnd","_verticalScrollbar","VerticalScrollbar","_horizontalScrollbar","_domNode","_leftShadowDomNode","_topShadowDomNode","_topLeftShadowDomNode","_listenOnDomNode","_mouseWheelToDispose","_setListeningToMouseWheel","_onmouseover","_handleMouseOver","_onmouseleave","_handleMouseLeave","_hideTimeout","TimeoutTimer","_isDragging","_mouseIsOver","_revealOnScroll","updateClassName","newClassName","newOptions","_render","delegateScrollFromMouseWheelEvent","StandardWheelEvent","shouldListen","onMouseWheel","passive","classifier","didScroll","shiftConvert","futureScrollPosition","deltaScrollTop","desiredScrollTop","deltaScrollLeft","desiredScrollLeft","consumeMouseWheel","_reveal","renderNow","scrollState","enableTop","enableLeft","leftClassName","topClassName","topLeftClassName","_hide","_scheduleHide","_handleActivate","handleActivate","bgWidth","bgHeight","arrowSize","addStandardDisposableListener","_arrowPointerDown","_pointerdownRepeatTimer","_pointerdownScheduleRepeatTimer","oppositeScrollbarSize","scrollSize","_scrollbarSize","_oppositeScrollbarSize","_arrowSize","_visibleSize","_scrollSize","_scrollPosition","_computedAvailableSize","_computedIsNeeded","_computedSliderSize","_computedSliderRatio","_computedSliderPosition","_refreshComputedValues","iVisibleSize","iScrollSize","iScrollPosition","setArrowSize","iArrowSize","_computeValues","computedAvailableSize","computedRepresentableSize","computedIsNeeded","computedSliderSize","computedSliderRatio","computedSliderPosition","desiredSliderPosition","correctedOffset","visibleClassName","invisibleClassName","_visibility","_visibleClassName","_invisibleClassName","_isVisible","_isNeeded","_rawShouldBeVisible","_shouldBeVisible","_revealTimer","_updateShouldBeVisible","rawShouldBeVisible","_applyVisibilitySetting","shouldBeVisible","ensureVisibility","setIfNotSet","withFadeAway","DomUtils","mainWindow","tail","array","n","LinkedListNode","Undefined","prev","LinkedList","_first","_last","_insert","atTheEnd","newNode","oldLast","oldFirst","didRemove","_remove","Symbol","iterator","EventType","TAP","START","END","CONTEXT_MENU","Gesture","_dispatched","_targets","_ignoreTargets","_activeTouches","_handle","_lastSetTapCountTime","_handleTouchStart","_handleTouchEnd","_handleTouchMove","addTarget","isTouchDevice","None","_instance","ignoreTarget","maxTouchPoints","len","targetTouches","touch","identifier","initialTarget","initialTimeStamp","initialPageX","initialPageY","rollingTimestamps","rollingPageX","rollingPageY","evt","_newGestureEvent","_dispatchEvent","activeTouchCount","keys","changedTouches","hasOwnProperty","holdTime","_holdDelay","finalX","finalY","deltaT","dispatchTo","filter","_inertia","createEvent","initEvent","tapCount","currentTime","getTime","setTapCount","_clearTapCountTime","targets","depth","t1","vX","dirX","vY","dirY","deltaPosX","deltaPosY","stopped","_scrollFriction","translationX","_target","descriptor","fnKey","fn","memoizeKey","args","configurable","enumerable","writable","apply","hasArrows","_arrowScrollDelta","_setArrows","_arrowScroll","currentPosition","_arrowUp","_arrowDown","arrowDelta","_updateArrowSize","listener","StandardMouseEvent","isSelectAllActive","selectionStartLength","finalSelectionStart","areSelectionValuesReversed","finalSelectionEnd","startPlusLength","handleTrim","_onCharSizeChange","onCharSizeChange","_measureStrategy","TextMetricsMeasureStrategy","DomMeasureStrategy","BaseMeasureStategy","_result","_validateAndSet","_parentElement","_measureElement","whiteSpace","fontKerning","Number","offsetWidth","offsetHeight","metrics","fontBoundingBoxAscent","fontBoundingBoxDescent","firstCell","content","combinedData","isCombined","setFromCharData","getAsCharData","_characterJoiners","_nextCharacterJoinerId","joiner","ranges","lineStr","trimmedLength","rangeStartColumn","currentStringIndex","rangeStartStringIndex","rangeAttrFG","getFg","rangeAttrBG","getBg","_getJoinedRanges","startIndex","endIndex","allJoinedRanges","joinerRanges","_mergeRanges","_stringRangesToCellRanges","currentRangeIndex","currentRangeStarted","currentRange","getString","newRange","inRange","_window","_isFocused","_cachedIsFocused","_onDprChange","_onWindowChange","onWindowChange","_screenDprMonitor","ScreenDprMonitor","setWindow","hasFocus","queueMicrotask","_parentWindow","_windowResizeListener","_outerListener","_setDprAndFireIfDiffers","_currentDevicePixelRatio","_updateDpr","_setWindowResizeListener","clearListener","parentWindow","_resolutionMediaMatchList","removeListener","matchMedia","addListener","Keyboard_1","KittyKeyboard_1","Win32InputMode_1","Platform_1","_getWin32InputMode","_win32InputMode","Win32InputMode","_getKittyKeyboard","_kittyKeyboard","KittyKeyboard","evaluateKeyboardEvent","kittyFlags","kittyKeyboard","flags","evaluate","vtExtensions","shouldUseProtocol","providerIndex","indexOf","Mouse_1","getMouseReportCoords","col","touch_1","_mouseStateService","_lastEvent","_wheelPartialScroll","_touchScrollAccumulator","requestedEvents","mouseup","wheel","mousedrag","mousemove","eventListeners","_handleWheel","_handleMouseDrag","_altMouseCursor","AltMouseCursorController","events","_handleProtocolChange","_syncMouseModeState","_handlePassiveWheel","_handleTouchChange","_sendEvent","but","action","overrideType","allowCustomWheelEvent","_consumeWheelEvent","stripAltFromReport","_triggerMouseEvent","ctrl","shouldForceSelection","_handleTouchScrollAsWheel","_handleTouchScrollAsKeys","trunc","resetClass","logLevel","_explainEvents","_applyScrollModifier","targetWheelEventPixels","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_PAGE","_equalEvents","isPixelEncoding","restrictMouseEvent","report","encodeMouseEvent","isDefaultEncoding","triggerBinaryEvent","down","up","drag","move","pixels","ILogService","_isActive","_listeners","store","syncFromModifier","_updateClass","altHeld","RenderDebouncer_1","TaskQueue_1","_renderer","decorationService","_observerDisposable","_isPaused","_needsFullRefresh","_isNextRenderRedrawOnly","_needsSelectionRefresh","_canvasWidth","_canvasHeight","_selectionState","_onRenderedViewportChange","_onRefreshRequest","onRefreshRequest","_pausedResizeTask","DebouncedIdleTask","_renderDebouncer","RenderDebouncer","_syncOutputHandler","SynchronizedOutputHandler","_fullRefresh","_registerIntersectionObserver","observer","IntersectionObserver","_handleIntersectionChange","threshold","_intersectionObserver","disconnect","observe","entry","isIntersecting","intersectionRatio","flush","isRedrawOnly","bufferRows","buffered","_fireOnCanvasResize","renderer","_onTimeout","_start","_end","_isBuffering","_timeout","MoveToCell_1","SelectionModel_1","BufferRange_1","NON_BREAKING_SPACE_CHAR","ALL_NON_BREAKING_SPACE_REGEX","RegExp","_dragScrollAmount","_enabled","_trimListener","_mouseDownTimeStamp","_oldHasSelection","_oldSelectionStart","_oldSelectionEnd","_onLinuxMouseSelection","_onRedrawRequest","_mouseMoveListener","_mouseUpListener","onUserInput","onTrim","_handleTrim","_handleBufferActivate","_model","SelectionModel","_activeSelectionMode","_removeMouseDownListeners","rowsChanged","lineText","startRowEndCol","isLinuxMouseSelection","_refreshAnimationFrame","_refresh","_isClickInSelection","_getMouseBufferCoords","_areCoordsInSelection","isCellInSelection","_selectWordAtCursor","allowWhitespaceOnlySelection","getRangeLength","_selectWordAt","_getMouseEventScrollAmount","terminalHeight","macOptionClickForcesSelection","_handleIncrementalClick","_handleSingleClick","_handleDoubleClick","_handleTripleClick","_addMouseDownListeners","_dragScrollIntervalTimer","_dragScroll","hadSelection","_fireOnSelectionChange","hasWidth","_selectLineAt","previousSelectionEnd","_selectToWordAt","timeElapsed","altClickMovesCursor","coordinates","moveToCellSequence","_fireEventIfSelectionChanged","activeBuffer","_convertViewportColToCharacterIndex","charIndex","_getWordAt","followWrappedLinesAbove","followWrappedLinesBelow","charOffset","leftWideCharCount","rightWideCharCount","leftLongCharOffset","rightLongCharOffset","charAt","_isCharWordSeparator","getCodePoint","previousBufferLine","previousLineWordPosition","nextBufferLine","nextLineWordPosition","wordPosition","wordSeparator","wrappedRange","getWrappedRangeForLine","first","last","ServiceRegistry_1","createDecorator","ColorContrastCache_1","Types_1","DEFAULT_FOREGROUND","DEFAULT_BACKGROUND","DEFAULT_CURSOR","DEFAULT_CURSOR_ACCENT","DEFAULT_SELECTION","DEFAULT_OVERVIEW_RULER_BORDER","_colors","_contrastCache","ColorContrastCache","_halfContrastCache","_onChangeColors","selectionBackgroundTransparent","blend","selectionInactiveBackgroundTransparent","opacity","_updateRestoreColors","_setTheme","theme","parseColor","selectionBackground","selectionInactiveBackground","NULL_COLOR","isOpaque","black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite","extendedAnsi","colorCount","slot","_restoreColor","_restoreColors","cssString","fallback","millis","Promise","resolve","timeout","_token","_isDisposed","_isScheduled","_disposable","context","handle","CircularList","_maxLength","onDeleteEmitter","onDelete","onInsertEmitter","onInsert","onTrimEmitter","_array","Array","_startIndex","_length","maxLength","newMaxLength","newArray","_getCyclicIndex","newLength","recycle","isFull","deleteCount","items","countToTrim","trimStart","shiftElements","expandListBy","$r","$g","$b","$a","toPaddedHex","s","contrastRatio","l1","l2","color_1","toChannels","fgR","fgG","fgB","bgR","bgG","bgB","rgbaColor","factor","css_1","$ctx","$litmusColor","willReadFrequently","globalCompositeOperation","createLinearGradient","rgbaMatch","parseFloat","getImageData","rgb_1","relativeLuminance2","rs","gs","bs","reduceLuminance","bgRgba","fgRgba","cr","increaseLuminance","bgL","fgL","resultA","resultARatio","resultB","InstantiationService_1","LogService_1","BufferService_1","OptionsService_1","CoreService_1","MouseStateService_1","UnicodeV6_1","UnicodeService_1","CharsetService_1","WindowsMode_1","WriteBuffer_1","OscLinkService_1","hasWriteSyncWarnHappened","_onScrollApi","_windowsWrappingHeuristics","_onBinary","_onData","_onLineFeed","_onResize","_onWriteParsed","InstantiationService","OptionsService","LogService","BufferService","CoreService","MouseStateService","unicodeService","UnicodeService","UnicodeV6","IUnicodeService","_charsetService","CharsetService","ICharsetService","OscLinkService","InputHandler","onRequestScrollToBottom","_writeBuffer","handleUserInput","_handleWindowsPtyOptionChange","markRangeDirty","scrollBottom","WriteBuffer","promiseResult","parse","writeSync","maxSubsequentCalls","LogLevelEnum","WARN","flushSync","scroll","eraseAttr","registerEscHandler","registerDcsHandler","registerCsiHandler","registerOscHandler","registerApcHandler","windowsPty","backend","buildNumber","_enableWindowsWrappingHeuristics","disposables","updateWindowsModeWrappedState","final","_disposed","_event","thisArgs","idx","isArray","call","listeners","initial","Charsets_1","EscapeSequenceParser_1","TextDecoder_1","OscParser_1","DcsParser_1","ApcParser_1","Version_1","GLEVEL","paramToWindowOption","setWinLines","restoreWin","minimizeWin","setWinPosition","setWinSizePixels","raiseWin","lowerWin","refreshWin","setWinSizeChars","maximizeWin","fullscreenWin","getWinState","getWinPosition","getWinSizePixels","getScreenSizePixels","getCellSizePixels","getWinSizeChars","getScreenSizeChars","getIconTitle","getWinTitle","pushTitle","popTitle","$temp","getAttrData","_curAttrData","_unicodeService","EscapeSequenceParser","_parseBuffer","Uint32Array","_stringDecoder","StringToUtf32","_utf8Decoder","Utf8ToUtf32","_windowTitle","_iconName","_windowTitleStack","_iconNameStack","_eraseAttrDataInternal","_onRequestBell","_onRequestRefreshRows","_onRequestReset","_onRequestSendFocus","_onRequestSyncScrollBar","onRequestSyncScrollBar","_onRequestWindowsOptionsReport","_onA11yChar","_onA11yTab","_onColor","_onRequestColorSchemeQuery","_parseStack","paused","cursorStartX","cursorStartY","decodedLength","_specialColors","_dirtyRowTracker","DirtyRowTracker","_activeBuffer","setCsiHandlerFallback","params","identToString","toArray","setEscHandlerFallback","setExecuteHandlerFallback","setOscHandlerFallback","setDcsHandlerFallback","payload","setApcHandlerFallback","setPrintHandler","print","insertChars","intermediates","cursorUp","scrollRight","cursorDown","cursorForward","cursorBackward","cursorNextLine","cursorPrecedingLine","cursorCharAbsolute","cursorPosition","cursorForwardTab","eraseInDisplay","prefix","eraseInLine","insertLines","deleteLines","deleteChars","scrollUp","scrollDown","eraseChars","cursorBackwardTab","charPosAbsolute","hPositionRelative","repeatPrecedingCharacter","sendDeviceAttributesPrimary","sendDeviceAttributesSecondary","linePosAbsolute","vPositionRelative","hVPosition","tabClear","setMode","setModePrivate","resetMode","resetModePrivate","charAttributes","deviceStatus","deviceStatusPrivate","softReset","sendXtVersion","setCursorStyle","setScrollRegion","saveCursor","windowOptions","restoreCursor","insertColumns","deleteColumns","selectProtected","requestMode","kittyKeyboardSet","kittyKeyboardQuery","kittyKeyboardPush","kittyKeyboardPop","setExecuteHandler","bell","lineFeed","carriageReturn","backspace","tab","shiftOut","shiftIn","tabSet","OscHandler","setTitle","setIconName","setOrReportIndexedColor","setHyperlink","setOrReportFgColor","setOrReportBgColor","setOrReportCursorColor","restoreIndexedColor","restoreFgColor","restoreBgColor","restoreCursorColor","reverseIndex","keypadApplicationMode","keypadNumericMode","fullReset","setgLevel","selectDefaultCharset","flag","CHARSETS","selectCharset","screenAlignmentPattern","setErrorHandler","DcsHandler","requestStatusString","_preserveStack","_logSlowResolvingAsync","p","slowTimeout","slowPromise","_res","rej","race","then","err","_getCurrentLinkId","wasPaused","DEBUG","prototype","TRACE","trace","split","clearRange","decode","subarray","viewportEnd","viewportStart","chWidth","charset","curAttr","bufferRow","markDirty","setCellFromCodepoint","precedingJoinState","ch","currentInfo","charProperties","extractWidth","shouldJoin","extractShouldJoin","stringFromCodePoint","addLineToLink","oldRow","oldCol","_eraseAttrData","BufferLine","copyCellsFrom","addCodepointToCell","insertCells","getNullCell","NULL_CELL_CODE","NULL_CELL_WIDTH","ApcHandler","convertEol","_restrictCursor","originalX","nextStop","maxCol","_setCursor","_moveCursor","diffToTop","diffToBottom","param","tabs","prevStop","_eraseInBufferLine","clearWrap","respectProtect","replaceCells","_resetBufferLine","clearMarkers","scrollOnEraseInDisplay","scrollBackSize","scrollBottomRowsOffset","scrollBottomAbsolute","deleteCells","joinState","idata","itext","codePointAt","tlength","copyWithin","_is","XTERM_VERSION","term","termName","setgCharset","DEFAULT_CHARSET","quirks","allowSetCursorBlink","activeEncoding","mainFlags","altFlags","activateAltBuffer","colorSchemeQuery","activateNormalBuffer","dm","mouseProtocol","mouseEncoding","cs","f","b2v","_updateAttrColor","mode","c1","c2","c3","fromColorRGB","_extractColor","attr","accu","cSpace","advance","hasSubParams","subparams","getSubParams","underlineColor","_processUnderline","updateExtended","_processSGR0","l","kittySgrBoldFaintControl","savedX","savedY","savedCurAttrData","savedCharset","isBlinking","second","savedCharsets","charsets","savedGlevel","glevel","savedOriginMode","savedWraparoundMode","slots","spec","exec","isValidColorIndex","_createHyperlink","_finishHyperlink","parsedParams","idParamIndex","findIndex","registerLink","_setOrReportSpecialColor","collectAndFlag","scrollRegionHeight","level","yOffset","markAllDirty","isProtected","block","bar","stack","altStack","mainStack","arg","_disposables","o","_value","_data","third","fourth","_targetWindow","majorVersion","isNode","process","isLegacyEdge","_getKey","logService","_insertedValues","_isFlushingInserted","_deletedIndices","_isFlushingDeleted","_flushInsertedTask","IdleTaskQueue","_flushDeletedTask","insert","_flushCleanupDeleted","enqueue","_flushInserted","sortedAddedValues","sortedAddedValuesIndex","arrayIndex","newArrayIndex","_flushCleanupInserted","_deleteAtKey","_search","_flushDeleted","sortedDeletedIndices","sortedDeletedIndicesIndex","getKeyIterator","forEachByKey","mid","midKey","StringBuilder","_chunks","append","chunk","_limit","_builder","limit","TaskQueue","_tasks","_i","task","_idleCallback","_cancelCallback","_requestCallback","_process","deadline","taskDuration","deadlineRemaining","longestTask","lastDeadlineRemaining","timeRemaining","PriorityTaskQueue","_createDeadline","requestIdleCallback","cancelIdleCallback","_queue","lastChar","CHAR_DATA_CODE_INDEX","WHITESPACE_CELL_CODE","ExtendedAttrs","newObj","isFgRGB","isBgRGB","isFgPalette","isBgPalette","isFgDefault","isBgDefault","isAttributeDefault","isEmpty","getUnderlineColorMode","isUnderlineColorPalette","getUnderlineStyle","getUnderlineVariantOffset","underlineVariantOffset","_urlId","_ext","val","CircularList_1","BufferLineStringCache_1","BufferReflow_1","Marker_1","MAX_BUFFER_SIZE","Buffer","_hasScrollback","_nullCell","fromCharData","NULL_CELL_CHAR","_whitespaceCell","WHITESPACE_CELL_WIDTH","_isClearing","_memoryCleanupPosition","_cols","_rows","_getCorrectBufferLength","setupTabStops","_memoryCleanupQueue","_stringCache","BufferLineStringCache","getWhitespaceCell","relativeY","correctBufferLength","scrollback","fillViewportRows","fillAttr","newCols","newRows","nullCell","dirtyMemoryLines","addToY","amountToTrim","_isReflowEnabled","_reflow","_batchedMemoryCleanup","normalRun","counted","cleanupMemory","_reflowLarger","_reflowSmaller","reflowCursorLine","toRemove","reflowLargerGetLinesToRemove","newLayoutResult","reflowLargerCreateNewLayout","reflowLargerApplyNewLayout","layout","_reflowLargerAdjustViewport","countRemoved","viewportAdjustments","toInsert","countToInsert","wrappedLines","absoluteY","lastLineLength","destLineLengths","reflowSmallerGetNewLineLengths","linesToAdd","trimmedLines","newLines","newLine","destLineIndex","destCol","srcLineIndex","srcCol","cellsToCopy","wrappedLinesIndex","getWrappedLineTrimmedLength","setCell","insertEvents","originalLines","originalLinesLength","originalLineIndex","nextToInsertIndex","nextToInsert","countInsertedSoFar","nextI","insertCountEmitted","lineIndex","trimRight","tabStopWidth","Marker","_removeMarker","StringBuilder_1","$startIndex","$workCell","$translateToStringBuilder","fillCellData","_combined","_extendedAttrs","_invalidateStringCache","CHAR_DATA_ATTR_INDEX","CHAR_DATA_CHAR_INDEX","CHAR_DATA_WIDTH_INDEX","codePoint","attrs","byteLength","uint32Cells","extKeys","copyFrom","_copySparseMapsFrom","src","applyInReverse","srcData","_copyCellMapsFrom","outColumns","isCanonicalRequest","stringCacheEntry","_getStringCacheEntry","isTrimmed","trimEnd","cacheEntry","createIfNeeded","cachedEntry","_stringCacheEntryRef","generation","allocateEntry","srcStart","_clearTimeout","_lastAccessTimestamp","_scheduleClear","_scheduleClearTimeout","timeoutMs","disposableTimeout","bufferCols","endsInNull","followingLineStartsWithWide","oldCols","bufferAbsoluteY","srcTrimmedTineLength","srcRemainingCells","destRemainingCells","countToRemove","nextToRemoveIndex","nextToRemoveStart","countRemovedSoFar","newLayout","newLayoutLines","newLineLengths","cellsNeeded","srcLine","cellsAvailable","oldTrimmedLength","endsWithWide","Buffer_1","BufferSet","_normalBuffer","_altBuffer","_onBufferActivate","_normal","_alt","inactiveBuffer","obj","combined","attributesEquals","thisDefault","otherDefault","DEFAULT_COLOR","DEFAULT_ATTR","DEFAULT_EXT","_id","_nextId","_onDispose","h","k","q","u","A","B","C","R","Q","K","Y","E","Z","H","_","applicationCursorMode","modifiers","keyMapping","KEYCODE_KEY_MAPPINGS","keyString","toUpperCase","toLowerCase","_functionalKeyCodes","Escape","Enter","Tab","Backspace","CapsLock","ScrollLock","NumLock","PrintScreen","Pause","ContextMenu","F13","F14","F15","F16","F17","F18","F19","F20","F21","F22","F23","F24","F25","KP_0","KP_1","KP_2","KP_3","KP_4","KP_5","KP_6","KP_7","KP_8","KP_9","KP_Decimal","KP_Divide","KP_Multiply","KP_Subtract","KP_Add","KP_Enter","KP_Equal","ShiftLeft","ShiftRight","ControlLeft","ControlRight","AltLeft","AltRight","MetaLeft","MetaRight","MediaPlayPause","MediaStop","MediaTrackNext","MediaTrackPrevious","AudioVolumeDown","AudioVolumeUp","AudioVolumeMute","_csiTildeKeys","Insert","Delete","PageUp","PageDown","F5","F6","F7","F8","F9","F10","F11","F12","_csiLetterKeys","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Home","End","_ss3FunctionKeys","F1","F2","F3","F4","_getNumpadKeyCode","_getModifierKeyCode","_encodeModifiers","mods","_getKeyCode","macOptionAsAlt","numpadCode","modifierCode","funcCode","digit","_isModifierKey","_isLockKey","_buildCsiLetterSequence","letter","reportEventTypes","needsEventType","seq","_buildSs3Sequence","_buildCsiTildeSequence","number","_buildCsiUSequence","isFunc","isMod","shiftedKey","textCode","csiLetter","ss3Letter","tildeCode","specialKey","legacyByte","_interim","startPos","interim","Uint8Array","byte1","byte2","byte3","byte4","discardInterim","tmp","missing","fourStop","BMP_COMBINING","HIGH_COMBINING","table","version","wcwidth","num","ucs","bisearch","preceding","createPropertyValue","_codeToVk","KeyA","KeyB","KeyC","KeyD","KeyE","KeyF","KeyG","KeyH","KeyI","KeyJ","KeyK","KeyL","KeyM","KeyN","KeyO","KeyP","KeyQ","KeyR","KeyS","KeyT","KeyU","KeyV","KeyW","KeyX","KeyY","KeyZ","Digit0","Digit1","Digit2","Digit3","Digit4","Digit5","Digit6","Digit7","Digit8","Digit9","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","NumpadMultiply","NumpadAdd","NumpadSeparator","NumpadSubtract","NumpadDecimal","NumpadDivide","NumpadEnter","Space","Semicolon","Equal","Comma","Minus","Period","Slash","Backquote","BracketLeft","Backslash","BracketRight","Quote","IntlBackslash","_codeToScancode","_enhancedKeyCodes","_keyToControlChar","_getVirtualKeyCode","vk","_getScanCode","_getUnicodeChar","controlChar","_getControlKeyState","isKeyDown","_action","_callbacks","_pendingData","_bufferOffset","_isSyncWriting","_syncCalls","_didUserInput","_innerWriteTimer","didProcess","_innerWrite","_scheduleInnerWrite","lastTime","continuation","catch","low","RGB_REX","base","HASH_REX","adv","bits","pad","s2","EMPTY_HANDLERS","_handlers","create","_active","_ident","_handlerFb","_stack","loopPosition","fallThrough","registerHandler","handlerList","handlerIndex","clearHandler","setHandlerFallback","put","utf32ToString","success","handlerResult","LimitedStringBuilder","_payloadLimit","_hitLimit","ret","res","Params_1","unhook","hook","EMPTY_PARAMS","Params","addParam","_params","TransitionTable","Uint16Array","setDefault","addMany","codes","NON_ASCII_PRINTABLE","VT500_TRANSITION_TABLE","blueprint","unused","PRINTABLES","EXECUTABLES","states","_transitions","handlers","handlerPos","transition","chunkPos","initialState","currentState","_collect","_printHandlerFb","_executeHandlerFb","_csiHandlerFb","_escHandlerFb","_errorHandlerFb","_printHandler","_executeHandlers","_executeHandlersArr","_csiHandlers","_escHandlers","_oscParser","OscParser","_dcsParser","DcsParser","_apcParser","ApcParser","_errorHandler","_identifier","finalRange","intermediate","finalCode","reverse","clearPrintHandler","clearEscHandler","clearExecuteHandler","clearCsiHandler","clearDcsHandler","clearOscHandler","clearApcHandler","clearErrorHandler","resetZdm","csiDone","addDigit","addSubParam","l4","collect","abort","handlersEsc","jj","_put","fromArray","maxSubParamsLength","Int32Array","_subParams","_subParamsLength","_subParamsIdx","_rejectDigits","_rejectSubDigits","_digitIsSub","newParams","getSubParamsAll","cur","_addons","instance","loadedAddon","_wrappedAddonDispose","BufferLineApiView_1","init","baseY","getLine","BufferLineApiView","_line","getCell","startColumn","endColumn","BufferApiView_1","_onBufferChange","onBufferChange","BufferApiView","_alternate","alternate","addCsiHandler","addDcsHandler","addEscHandler","addOscHandler","provider","versions","activeVersion","BufferSet_1","isUserScrolling","colsChanged","_cachedBlankLine","topRow","bottomRow","willBufferBeTrimmed","oldYdisp","_charsets","DEFAULT_MODES","DEFAULT_DEC_PRIVATE_MODES","_onUserInput","_onRequestScrollToBottom","showCursorImmediately","structuredClone","SortedList_1","$xmin","$xmax","_decorations","_lineCache","DecorationLineCache","_onDecorationRegistered","_onDecorationRemoved","SortedList","attachToBufferLines","Decoration","markerDispose","getDecorationsAtCell","bucket","getDecorationsOnLine","_decorationsByLine","_bufferLineListeners","_lineIndexSyncTimer","MicrotaskTimer","_lineIndexSyncCallbacks","_addToLineBuckets","_removeFromLineBuckets","_handleBufferLinesTrim","_handleBufferLinesInsert","_handleBufferLinesDelete","_getDecorationHeight","_indexedStartLine","_reindexDecoration","_scheduleLineIndexSync","callbacks","newMap","_mergeLineBucket","_applyBufferLinesInsert","_applyBufferLinesDelete","existing","spanCrossers","deleteEnd","toReindex","_cachedBg","_cachedFg","foregroundColor","ServiceCollection","_entries","service","_services","getService","ctor","serviceDependencies","getServiceDependencies","serviceArgs","dependency","firstServiceArgPos","optionsKeyToLogLevel","info","INFO","ERROR","off","OFF","_logLevel","_updateLogLevel","_evalLazyOptionalParams","optionalParams","_log","message","logger","log","DEFAULT_PROTOCOLS","NONE","restrict","X10","VT200","DRAG","ANY","eventCode","isSGR","S","DEFAULT_ENCODINGS","DEFAULT","SGR","SGR_PIXELS","_protocols","_encodings","_activeProtocol","_activeEncoding","_onProtocolChange","addProtocol","addEncoding","encoding","_customWheelEventHandler","DEFAULT_OPTIONS","rescaleOverlappingGlyphs","FONT_WEIGHT_OPTIONS","_onOptionChange","defaultOptions","_sanitizeAndValidateOption","_setupOptions","eventKey","isCursorStyle","_entriesWithId","_dataByLinkId","_removeMarkerFromLink","castData","_getEntryIdKey","every","linkData","serviceRegistry","decorator","arguments","storeServiceDependency","_providers","_onChange","onChange","extractCharKind","_activeProvider","getStringCellWidth","precedingInfo","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__"],"sourceRoot":""} \ No newline at end of file diff --git a/lib/xterm.mjs b/lib/xterm.mjs -index 9bc5087a0729e74e20b59eddf5d8259e056de338..e0b619f0c891730125cbb9625a6296bfb4a4c01a 100644 +index 9bc5087a0729e74e20b59eddf5d8259e056de338..539b96d6fc425c4a416dde129265488a35ef6b25 100644 --- a/lib/xterm.mjs +++ b/lib/xterm.mjs -@@ -11,17 +11,17 @@ - * Copyright (c) 2011 Fabrice Bellard - */ - /*--------------------------------------------------------------------------------------------- +@@ -14,14 +14,14 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -var Ms=Object.defineProperty;var kn=Object.getOwnPropertyDescriptor;var Mn=(n,i)=>{for(var e in i)Ms(n,e,{get:i[e],enumerable:!0})};var y=(n,i,e,t)=>{for(var r=t>1?void 0:t?kn(i,e):i,s=n.length-1,o;s>=0;s--)(o=n[s])&&(r=(t?o(i,e,r):o(r))||r);return t&&r&&Ms(i,e,r),r},m=(n,i)=>(e,t)=>i(e,t,n);var Bs="Terminal input",Ut={get:()=>Bs,set:n=>Bs=n},Ps="Too much output to announce, navigate to rows manually to read",Ze={get:()=>Ps,set:n=>Ps=n};function Bn(n){return n.replace(/\r?\n/g,"\r")}function Pn(n,i){return i?`\x1B[200~${n.replace(/\x1b/g,"\u241B")}\x1B[201~`:n}function Os(n,i){n.clipboardData&&n.clipboardData.setData("text/plain",i.selectionText),n.preventDefault()}function Ns(n,i,e,t){if(n.stopPropagation(),n.clipboardData){let r=n.clipboardData.getData("text/plain");Nr(r,i,e,t)}}function Nr(n,i,e,t){n=Bn(n),n=Pn(n,e.decPrivateModes.bracketedPasteMode&&t.rawOptions.ignoreBracketedPasteMode!==!0),e.triggerDataEvent(n,!0),i.value=""}function Fr(n,i,e){let t=e.getBoundingClientRect(),r=n.clientX-t.left-10,s=n.clientY-t.top-10;i.style.width="20px",i.style.height="20px",i.style.left=`${r}px`,i.style.top=`${s}px`,i.style.zIndex="1000",i.focus()}function Hr(n,i,e,t,r){Fr(n,i,e),r&&t.rightClickSelect(n),i.value=t.selectionText,i.select()}function be(n){return n>65535?(n-=65536,String.fromCharCode((n>>10)+55296)+String.fromCharCode(n%1024+56320)):String.fromCharCode(n)}function ye(n,i=0,e=n.length){let t="";for(let r=i;r65535?(s-=65536,t+=String.fromCharCode((s>>10)+55296)+String.fromCharCode(s%1024+56320)):t+=String.fromCharCode(s)}return t}var mi=class{constructor(){this._interim=0}clear(){this._interim=0}decode(i,e){let t=i.length;if(!t)return 0;let r=0,s=0;if(this._interim){let o=i.charCodeAt(s++);56320<=o&&o<=57343?e[r++]=(this._interim-55296)*1024+o-56320+65536:(e[r++]=this._interim,e[r++]=o),this._interim=0}for(let o=s;o=t)return this._interim=a,r;let l=i.charCodeAt(o);56320<=l&&l<=57343?e[r++]=(a-55296)*1024+l-56320+65536:(e[r++]=a,e[r++]=l);continue}a!==65279&&(e[r++]=a)}return r}},bi=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(i,e){let t=i.length;if(!t)return 0;let r=0,s,o,a,l,h,d=0;if(this.interim[0]){let _=!1,p=this.interim[0];p&=(p&224)===192?31:(p&240)===224?15:7;let v=0,f;for(;(f=this.interim[++v])&&v<4;)p<<=6,p|=f&63;let S=(this.interim[0]&224)===192?2:(this.interim[0]&240)===224?3:4,I=S-v;for(;d=t)return 0;if(f=i[d++],(f&192)!==128){d--,_=!0;break}else this.interim[v++]=f,p<<=6,p|=f&63}_||(S===2?p<128?d--:e[r++]=p:S===3?p<2048||p>=55296&&p<=57343||p===65279||(e[r++]=p):p<65536||p>1114111||(e[r++]=p)),this.interim.fill(0)}let c=t-4,u=d;for(;u=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(h=(s&31)<<6|o&63,h<128){u--;continue}e[r++]=h}else if((s&240)===224){if(u>=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,r;if(a=i[u++],(a&192)!==128){u--;continue}if(h=(s&15)<<12|(o&63)<<6|a&63,h<2048||h>=55296&&h<=57343||h===65279)continue;e[r++]=h}else if((s&248)===240){if(u>=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,r;if(a=i[u++],(a&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,this.interim[2]=a,r;if(l=i[u++],(l&192)!==128){u--;continue}if(h=(s&7)<<18|(o&63)<<12|(a&63)<<6|l&63,h<65536||h>1114111)continue;e[r++]=h}}return r}};var ue=class n{constructor(){this.fg=0;this.bg=0;this.extended=new ke}static toColorRGB(i){return[i>>>16&255,i>>>8&255,i&255]}static fromColorRGB(i){return(i[0]&255)<<16|(i[1]&255)<<8|i[2]&255}clone(){let i=new n;return i.fg=this.fg,i.bg=this.bg,i.extended=this.extended.clone(),i}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)===50331648}isBgRGB(){return(this.bg&50331648)===50331648}isFgPalette(){return(this.fg&50331648)===16777216||(this.fg&50331648)===33554432}isBgPalette(){return(this.bg&50331648)===16777216||(this.bg&50331648)===33554432}isFgDefault(){return(this.fg&50331648)===0}isBgDefault(){return(this.bg&50331648)===0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===16777216||(this.extended.underlineColor&50331648)===33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},ke=class n{constructor(i=0,e=0){this._ext=0;this._urlId=0;this._ext=i,this._urlId=e}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(i){this._ext=i}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(i){this._ext&=-469762049,this._ext|=i<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(i){this._ext&=-67108864,this._ext|=i&67108863}get urlId(){return this._urlId}set urlId(i){this._urlId=i}get underlineVariantOffset(){let i=(this._ext&3758096384)>>29;return i<0?i^4294967288:i}set underlineVariantOffset(i){this._ext&=536870911,this._ext|=i<<29&3758096384}clone(){return new n(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}};var F=class n extends ue{constructor(){super(...arguments);this.content=0;this.fg=0;this.bg=0;this.extended=new ke;this.combinedData=""}static fromCharData(e){let t=new n;return t.setFromCharData(e),t}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?be(this.content&2097151):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let r=e[1].charCodeAt(0);if(55296<=r&&r<=56319){let s=e[1].charCodeAt(1);56320<=s&&s<=57343?this.content=(r-55296)*1024+s-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}attributesEquals(e){if(this.getFgColorMode()!==e.getFgColorMode()||this.getFgColor()!==e.getFgColor()||this.getBgColorMode()!==e.getBgColorMode()||this.getBgColor()!==e.getBgColor()||this.isInverse()!==e.isInverse()||this.isBold()!==e.isBold()||this.isUnderline()!==e.isUnderline())return!1;if(this.isUnderline()){if(this.getUnderlineStyle()!==e.getUnderlineStyle())return!1;let t=this.isUnderlineColorDefault(),r=e.isUnderlineColorDefault();if(!(t&&r)&&(t!==r||this.getUnderlineColor()!==e.getUnderlineColor()||this.getUnderlineColorMode()!==e.getUnderlineColorMode()))return!1}return!(this.isOverline()!==e.isOverline()||this.isBlink()!==e.isBlink()||this.isInvisible()!==e.isInvisible()||this.isItalic()!==e.isItalic()||this.isDim()!==e.isDim()||this.isStrikethrough()!==e.isStrikethrough())}};var zr=new Map;function Hs(n){return n.di$dependencies||[]}function H(n){if(zr.has(n))return zr.get(n);let i=function(e,t,r){if(arguments.length!==3)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");Fn(i,e,r)};return i._id=n,zr.set(n,i),i}function Fn(n,i,e){i.di$target===i?i.di$dependencies.push({id:n,index:e}):(i.di$dependencies=[{id:n,index:e}],i.di$target=i)}var D=H("BufferService"),Me=H("MouseStateService"),Y=H("CoreService"),Ws=H("CharsetService"),Qe=H("InstantiationService");var fe=H("LogService"),R=H("OptionsService"),vi=H("OscLinkService"),Us=H("UnicodeService"),ge=H("DecorationService");var et=class{constructor(i,e,t){this._bufferService=i;this._optionsService=e;this._oscLinkService=t;this._workCell=new F}provideLinks(i,e){let t=this._bufferService.buffer.lines.get(i-1);if(!t){e(void 0);return}let r=[],s=this._optionsService.rawOptions.linkHandler,o=this._workCell,a=t.getTrimmedLength(),l=-1,h=-1,d=!1;for(let c=0;cs?s.activate(f,S,p):Hn(f,S),hover:(f,S)=>s?.hover?.(f,S,p),leave:(f,S)=>s?.leave?.(f,S,p)})}d=!1,o.hasExtendedAttrs()&&o.extended.urlId?(h=c,l=o.extended.urlId):(h=-1,l=-1)}}e(r)}_getRangeWithLineWrap(i,e,t,r){let s=i,o=e,a=i,l=t;for(;o===0&&this._bufferService.buffer.lines.get(s-1)?.isWrapped;){let d=this._bufferService.buffer.lines.get(s-2);if(!d)break;let c=d.getTrimmedLength();if(c===0||!this._hasUrlId(d,c-1,r))break;let u=c-1;for(;u>0&&this._hasUrlId(d,u-1,r);)u--;s--,o=u}for(;;){let h=this._bufferService.buffer.lines.get(a-1);if(!h)break;let d=h.getTrimmedLength();if(l!==d)break;let c=this._bufferService.buffer.lines.get(a);if(!c?.isWrapped)break;let u=c.getTrimmedLength();if(u===0||!this._hasUrlId(c,0,r))break;let _=1;for(;_{for(var e in i)Ps(n,e,{get:i[e],enumerable:!0})};var y=(n,i,e,t)=>{for(var r=t>1?void 0:t?Pn(i,e):i,s=n.length-1,o;s>=0;s--)(o=n[s])&&(r=(t?o(i,e,r):o(r))||r);return t&&r&&Ps(i,e,r),r},m=(n,i)=>(e,t)=>i(e,t,n);var Ms="Terminal input",Ut={get:()=>Ms,set:n=>Ms=n},Bs="Too much output to announce, navigate to rows manually to read",Je={get:()=>Bs,set:n=>Bs=n};function Bn(n){return n.replace(/\r?\n/g,"\r")}function On(n,i){return i?`\x1B[200~${n.replace(/\x1b/g,"\u241B")}\x1B[201~`:n}function Os(n,i){n.clipboardData&&n.clipboardData.setData("text/plain",i.selectionText),n.preventDefault()}function Ns(n,i,e,t){if(n.stopPropagation(),n.clipboardData){let r=n.clipboardData.getData("text/plain");Nr(r,i,e,t)}}function Nr(n,i,e,t){n=Bn(n),n=On(n,e.decPrivateModes.bracketedPasteMode&&t.rawOptions.ignoreBracketedPasteMode!==!0),e.triggerDataEvent(n,!0),i.value=""}function Fr(n,i,e){let t=e.getBoundingClientRect(),r=n.clientX-t.left-10,s=n.clientY-t.top-10;i.style.width="20px",i.style.height="20px",i.style.left=`${r}px`,i.style.top=`${s}px`,i.style.zIndex="1000",i.focus()}function Hr(n,i,e,t,r){Fr(n,i,e),r&&t.rightClickSelect(n),i.value=t.selectionText,i.select()}function be(n){return n>65535?(n-=65536,String.fromCharCode((n>>10)+55296)+String.fromCharCode(n%1024+56320)):String.fromCharCode(n)}function xe(n,i=0,e=n.length){let t="";for(let r=i;r65535?(s-=65536,t+=String.fromCharCode((s>>10)+55296)+String.fromCharCode(s%1024+56320)):t+=String.fromCharCode(s)}return t}var mi=class{constructor(){this._interim=0}clear(){this._interim=0}decode(i,e){let t=i.length;if(!t)return 0;let r=0,s=0;if(this._interim){let o=i.charCodeAt(s++);56320<=o&&o<=57343?e[r++]=(this._interim-55296)*1024+o-56320+65536:(e[r++]=this._interim,e[r++]=o),this._interim=0}for(let o=s;o=t)return this._interim=a,r;let l=i.charCodeAt(o);56320<=l&&l<=57343?e[r++]=(a-55296)*1024+l-56320+65536:(e[r++]=a,e[r++]=l);continue}a!==65279&&(e[r++]=a)}return r}},bi=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(i,e){let t=i.length;if(!t)return 0;let r=0,s,o,a,l,h,d=0;if(this.interim[0]){let _=!1,p=this.interim[0];p&=(p&224)===192?31:(p&240)===224?15:7;let v=0,f;for(;(f=this.interim[++v])&&v<4;)p<<=6,p|=f&63;let S=(this.interim[0]&224)===192?2:(this.interim[0]&240)===224?3:4,C=S-v;for(;d=t)return 0;if(f=i[d++],(f&192)!==128){d--,_=!0;break}else this.interim[v++]=f,p<<=6,p|=f&63}_||(S===2?p<128?d--:e[r++]=p:S===3?p<2048||p>=55296&&p<=57343||p===65279||(e[r++]=p):p<65536||p>1114111||(e[r++]=p)),this.interim.fill(0)}let c=t-4,u=d;for(;u=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(h=(s&31)<<6|o&63,h<128){u--;continue}e[r++]=h}else if((s&240)===224){if(u>=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,r;if(a=i[u++],(a&192)!==128){u--;continue}if(h=(s&15)<<12|(o&63)<<6|a&63,h<2048||h>=55296&&h<=57343||h===65279)continue;e[r++]=h}else if((s&248)===240){if(u>=t)return this.interim[0]=s,r;if(o=i[u++],(o&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,r;if(a=i[u++],(a&192)!==128){u--;continue}if(u>=t)return this.interim[0]=s,this.interim[1]=o,this.interim[2]=a,r;if(l=i[u++],(l&192)!==128){u--;continue}if(h=(s&7)<<18|(o&63)<<12|(a&63)<<6|l&63,h<65536||h>1114111)continue;e[r++]=h}}return r}};var ue=class n{constructor(){this.fg=0;this.bg=0;this.extended=new Pe}static toColorRGB(i){return[i>>>16&255,i>>>8&255,i&255]}static fromColorRGB(i){return(i[0]&255)<<16|(i[1]&255)<<8|i[2]&255}clone(){let i=new n;return i.fg=this.fg,i.bg=this.bg,i.extended=this.extended.clone(),i}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)===50331648}isBgRGB(){return(this.bg&50331648)===50331648}isFgPalette(){return(this.fg&50331648)===16777216||(this.fg&50331648)===33554432}isBgPalette(){return(this.bg&50331648)===16777216||(this.bg&50331648)===33554432}isFgDefault(){return(this.fg&50331648)===0}isBgDefault(){return(this.bg&50331648)===0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===16777216||(this.extended.underlineColor&50331648)===33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},Pe=class n{constructor(i=0,e=0){this._ext=0;this._urlId=0;this._ext=i,this._urlId=e}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(i){this._ext=i}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(i){this._ext&=-469762049,this._ext|=i<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(i){this._ext&=-67108864,this._ext|=i&67108863}get urlId(){return this._urlId}set urlId(i){this._urlId=i}get underlineVariantOffset(){let i=(this._ext&3758096384)>>29;return i<0?i^4294967288:i}set underlineVariantOffset(i){this._ext&=536870911,this._ext|=i<<29&3758096384}clone(){return new n(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}};var F=class n extends ue{constructor(){super(...arguments);this.content=0;this.fg=0;this.bg=0;this.extended=new Pe;this.combinedData=""}static fromCharData(e){let t=new n;return t.setFromCharData(e),t}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?be(this.content&2097151):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let r=e[1].charCodeAt(0);if(55296<=r&&r<=56319){let s=e[1].charCodeAt(1);56320<=s&&s<=57343?this.content=(r-55296)*1024+s-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}attributesEquals(e){if(this.getFgColorMode()!==e.getFgColorMode()||this.getFgColor()!==e.getFgColor()||this.getBgColorMode()!==e.getBgColorMode()||this.getBgColor()!==e.getBgColor()||this.isInverse()!==e.isInverse()||this.isBold()!==e.isBold()||this.isUnderline()!==e.isUnderline())return!1;if(this.isUnderline()){if(this.getUnderlineStyle()!==e.getUnderlineStyle())return!1;let t=this.isUnderlineColorDefault(),r=e.isUnderlineColorDefault();if(!(t&&r)&&(t!==r||this.getUnderlineColor()!==e.getUnderlineColor()||this.getUnderlineColorMode()!==e.getUnderlineColorMode()))return!1}return!(this.isOverline()!==e.isOverline()||this.isBlink()!==e.isBlink()||this.isInvisible()!==e.isInvisible()||this.isItalic()!==e.isItalic()||this.isDim()!==e.isDim()||this.isStrikethrough()!==e.isStrikethrough())}};var zr=new Map;function Hs(n){return n.di$dependencies||[]}function H(n){if(zr.has(n))return zr.get(n);let i=function(e,t,r){if(arguments.length!==3)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");Hn(i,e,r)};return i._id=n,zr.set(n,i),i}function Hn(n,i,e){i.di$target===i?i.di$dependencies.push({id:n,index:e}):(i.di$dependencies=[{id:n,index:e}],i.di$target=i)}var D=H("BufferService"),Me=H("MouseStateService"),Y=H("CoreService"),Ws=H("CharsetService"),et=H("InstantiationService");var fe=H("LogService"),R=H("OptionsService"),vi=H("OscLinkService"),Us=H("UnicodeService"),ge=H("DecorationService");var tt=class{constructor(i,e,t){this._bufferService=i;this._optionsService=e;this._oscLinkService=t;this._workCell=new F}provideLinks(i,e){let t=this._bufferService.buffer.lines.get(i-1);if(!t){e(void 0);return}let r=[],s=this._optionsService.rawOptions.linkHandler,o=this._workCell,a=t.getTrimmedLength(),l=-1,h=-1,d=!1;for(let c=0;cs?s.activate(f,S,p):Wn(f,S),hover:(f,S)=>s?.hover?.(f,S,p),leave:(f,S)=>s?.leave?.(f,S,p)})}d=!1,o.hasExtendedAttrs()&&o.extended.urlId?(h=c,l=o.extended.urlId):(h=-1,l=-1)}}e(r)}_getRangeWithLineWrap(i,e,t,r){let s=i,o=e,a=i,l=t;for(;o===0&&this._bufferService.buffer.lines.get(s-1)?.isWrapped;){let d=this._bufferService.buffer.lines.get(s-2);if(!d)break;let c=d.getTrimmedLength();if(c===0||!this._hasUrlId(d,c-1,r))break;let u=c-1;for(;u>0&&this._hasUrlId(d,u-1,r);)u--;s--,o=u}for(;;){let h=this._bufferService.buffer.lines.get(a-1);if(!h)break;let d=h.getTrimmedLength();if(l!==d)break;let c=this._bufferService.buffer.lines.get(a);if(!c?.isWrapped)break;let u=c.getTrimmedLength();if(u===0||!this._hasUrlId(c,0,r))break;let _=1;for(;_{n(),e&&r.dispose()},i),r=E(()=>{clearTimeout(t)});return e?.add(r),r}var Ie=class{constructor(){this._token=-1;this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._token!==-1&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(i,e){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,i()},e)}setIfNotSet(i,e){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");this._token===-1&&(this._token=setTimeout(()=>{this._token=-1,i()},e))}},Ci=class{constructor(){this._isScheduled=!1;this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(i){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,i())}))}},Ei=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(i,e,t=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();let r=t.setInterval(()=>{i()},e);this._disposable={dispose:()=>{t.clearInterval(r),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}};function se(n){let i=n;if(i?.ownerDocument?.defaultView)return i.ownerDocument.defaultView;let e=n;return e?.view?e.view:window}var Gr=class{constructor(i,e,t,r){this._node=i,this._type=e,this._handler=t,this._options=r,i.addEventListener(e,t,r)}dispose(){!this._node||!this._handler||(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}};function C(n,i,e,t){return new Gr(n,i,e,t)}function Vr(n,i,e,t){return C(n,i,e,t)}var le={CLICK:"click",MOUSE_DOWN:"mousedown",MOUSE_OVER:"mouseover",MOUSE_LEAVE:"mouseleave",KEY_DOWN:"keydown",KEY_UP:"keyup",INPUT:"input",BLUR:"blur",FOCUS:"focus",CHANGE:"change",POINTER_DOWN:"pointerdown",POINTER_MOVE:"pointermove",POINTER_UP:"pointerup",MOUSE_WHEEL:"wheel",WHEEL:"wheel"};function $s(n){let i=n.getBoundingClientRect(),e=se(n);return{left:i.left+e.scrollX,top:i.top+e.scrollY,width:i.width,height:i.height}}var yi=class{constructor(i,e){this._runner=i;this.priority=e;this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(i){console.error(i)}}static sort(i,e){return e.priority-i.priority}},Vs=new Map;function qs(n){let i=Vs.get(n);return i||(i={next:[],current:[],animFrameRequested:!1,inAnimationFrameRunner:!1},Vs.set(n,i)),i}function Wn(n){let i=qs(n);for(i.animFrameRequested=!1,i.current=i.next,i.next=[],i.inAnimationFrameRunner=!0;i.current.length>0;)i.current.sort(yi.sort),i.current.shift().execute();i.inAnimationFrameRunner=!1}function tt(n,i,e=0){let t=qs(n),r=new yi(i,e);return t.next.push(r),t.animFrameRequested||(t.animFrameRequested=!0,n.requestAnimationFrame(()=>Wn(n))),r}var xi=class extends Ei{constructor(i){super(),this._defaultTarget=i?se(i):void 0}cancelAndSet(i,e,t){super.cancelAndSet(i,e,t??this._defaultTarget??window)}};var we=class{constructor(i){this.domNode=i;this._width="";this._height="";this._top="";this._left="";this._bottom="";this._right="";this._className="";this._position="";this._layerHint=!1;this._contain="none"}setWidth(i){let e=rt(i);this._width!==e&&(this._width=e,this.domNode.style.width=this._width)}setHeight(i){let e=rt(i);this._height!==e&&(this._height=e,this.domNode.style.height=this._height)}setTop(i){let e=rt(i);this._top!==e&&(this._top=e,this.domNode.style.top=this._top)}setLeft(i){let e=rt(i);this._left!==e&&(this._left=e,this.domNode.style.left=this._left)}setBottom(i){let e=rt(i);this._bottom!==e&&(this._bottom=e,this.domNode.style.bottom=this._bottom)}setRight(i){let e=rt(i);this._right!==e&&(this._right=e,this.domNode.style.right=this._right)}setClassName(i){this._className!==i&&(this._className=i,this.domNode.className=this._className)}toggleClassName(i,e){this.domNode.classList.toggle(i,e),this._className=this.domNode.className}setPosition(i){this._position!==i&&(this._position=i,this.domNode.style.position=this._position)}setLayerHinting(i){this._layerHint!==i&&(this._layerHint=i,i?this.domNode.style.transform="translate3d(0px, 0px, 0px)":this.domNode.style.transform="")}setContain(i){this._contain!==i&&(this._contain=i,this.domNode.style.contain=this._contain)}setAttribute(i,e){this.domNode.setAttribute(i,e)}};function rt(n){return typeof n=="number"?`${n}px`:n}var Ke={};Mn(Ke,{getSafariVersion:()=>Kn,getZoomFactor:()=>Xr,isChrome:()=>Kt,isChromeOS:()=>Yr,isFirefox:()=>nt,isLegacyEdge:()=>Un,isLinux:()=>zt,isMac:()=>ie,isNode:()=>$r,isSafari:()=>wi,isWindows:()=>Ue});var $r=!!(typeof process<"u"&&"title"in process&&(typeof navigator>"u"||navigator.userAgent.startsWith("Node.js/"))),st=$r?"node":navigator.userAgent,qr=$r?"node":navigator.platform,nt=st.includes("Firefox"),Kt=st.includes("Chrome"),Un=st.includes("Edge"),wi=/^((?!chrome|android).)*safari/i.test(st);function Xr(n){return 1}function Kn(){if(!wi)return 0;let n=st.match(/Version\/(\d+)/);return n===null||n.length<2?0:parseInt(n[1],10)}var ie=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(qr),Ue=["Windows","Win16","Win32","WinCE"].includes(qr),zt=qr.indexOf("Linux")>=0,Yr=/\bCrOS\b/.test(st);var Xs=new WeakMap;function zn(n){if(!n.parent||n.parent===n)return null;try{let i=n.location,e=n.parent.location;if(i.origin!=="null"&&e.origin!=="null"&&i.origin!==e.origin)return null}catch{return null}return n.parent}var jr=class{static _getSameOriginWindowChain(i){let e=Xs.get(i);if(!e){e=[],Xs.set(i,e);let t=i,r;do r=zn(t),r?e.push({window:new WeakRef(t),iframeElement:t.frameElement??null}):e.push({window:new WeakRef(t),iframeElement:null}),t=r;while(t)}return e.slice(0)}static getPositionOfChildWindowRelativeToAncestorWindow(i,e){if(!e||i===e)return{top:0,left:0};let t=0,r=0,s=this._getSameOriginWindowChain(i);for(let o of s){let a=o.window.deref();if(t+=a?.scrollY??0,r+=a?.scrollX??0,a===e||!o.iframeElement)break;let l=o.iframeElement.getBoundingClientRect();t+=l.top,r+=l.left}return{top:t,left:r}}},ot=class{constructor(i,e){this.timestamp=Date.now(),this.browserEvent=e,this.leftButton=e.button===0,this.middleButton=e.button===1,this.rightButton=e.button===2,this.buttons=e.buttons,this.target=e.target,this.detail=e.detail??1,e.type==="dblclick"&&(this.detail=2),this.ctrlKey=e.ctrlKey,this.shiftKey=e.shiftKey,this.altKey=e.altKey,this.metaKey=e.metaKey,typeof e.pageX=="number"?(this.posx=e.pageX,this.posy=e.pageY):(this.posx=e.clientX+this.target.ownerDocument.body.scrollLeft+this.target.ownerDocument.documentElement.scrollLeft,this.posy=e.clientY+this.target.ownerDocument.body.scrollTop+this.target.ownerDocument.documentElement.scrollTop);let t=jr.getPositionOfChildWindowRelativeToAncestorWindow(i,e.view);this.posx-=t.left,this.posy-=t.top}preventDefault(){this.browserEvent.preventDefault()}stopPropagation(){this.browserEvent.stopPropagation()}},Gt=class{constructor(i,e=0,t=0){this.browserEvent=i??null,this.target=i?i.target??i.targetNode??i.srcElement??null:null,this.deltaY=t,this.deltaX=e;let r=!1;if(Kt){let s=navigator.userAgent.match(/Chrome\/(\d+)/);r=(s?parseInt(s[1],10):123)<=122}if(i){let s=i,o=i,a=i.view?.devicePixelRatio??1;if(typeof s.wheelDeltaY<"u")r?this.deltaY=s.wheelDeltaY/(120*a):this.deltaY=s.wheelDeltaY/120;else if(typeof o.VERTICAL_AXIS<"u"&&o.axis===o.VERTICAL_AXIS)this.deltaY=-o.detail/3;else if(i.type==="wheel"){let l=i;l.deltaMode===l.DOM_DELTA_LINE?nt&&!ie?this.deltaY=-i.deltaY/3:this.deltaY=-i.deltaY:this.deltaY=-i.deltaY/40}if(typeof s.wheelDeltaX<"u")wi&&Ue?this.deltaX=-(s.wheelDeltaX/120):r?this.deltaX=s.wheelDeltaX/(120*a):this.deltaX=s.wheelDeltaX/120;else if(typeof o.HORIZONTAL_AXIS<"u"&&o.axis===o.HORIZONTAL_AXIS)this.deltaX=-i.detail/3;else if(i.type==="wheel"){let l=i;l.deltaMode===l.DOM_DELTA_LINE?nt&&!ie?this.deltaX=-i.deltaX/3:this.deltaX=-i.deltaX:this.deltaX=-i.deltaX/40}this.deltaY===0&&this.deltaX===0&&i.wheelDelta&&(r?this.deltaY=i.wheelDelta/(120*a):this.deltaY=i.wheelDelta/120)}}preventDefault(){this.browserEvent?.preventDefault()}stopPropagation(){this.browserEvent?.stopPropagation()}};var at=class{constructor(){this._hooks=new pe;this._pointerMoveCallback=null;this._onStopCallback=null}dispose(){this.stopMonitoring(!1),this._hooks.dispose()}stopMonitoring(i){if(!this.isMonitoring())return;this._hooks.clear(),this._pointerMoveCallback=null;let e=this._onStopCallback;this._onStopCallback=null,i&&e&&e()}isMonitoring(){return!!this._pointerMoveCallback}startMonitoring(i,e,t,r,s){this.isMonitoring()&&this.stopMonitoring(!1),this._pointerMoveCallback=r,this._onStopCallback=s;let o=i;try{i.setPointerCapture(e),this._hooks.add(E(()=>{try{i.releasePointerCapture(e)}catch{}}))}catch{o=se(i)}this._hooks.add(C(o,le.POINTER_MOVE,a=>{if(a.buttons!==t){this.stopMonitoring(!0);return}a.preventDefault(),this._pointerMoveCallback(a)})),this._hooks.add(C(o,le.POINTER_UP,a=>this.stopMonitoring(!0)))}};var Ne=class extends g{_onclick(i,e){this._register(C(i,le.CLICK,t=>e(new ot(se(i),t))))}_onmouseover(i,e){this._register(C(i,le.MOUSE_OVER,t=>e(new ot(se(i),t))))}_onmouseleave(i,e){this._register(C(i,le.MOUSE_LEAVE,t=>e(new ot(se(i),t))))}};var Ti=class extends Ne{constructor(i){super(),this._handleActivate=i.handleActivate,this.bgDomNode=document.createElement("div"),this.bgDomNode.className="xterm-arrow-background",this.bgDomNode.style.position="absolute",this.bgDomNode.style.width=i.bgWidth+"px",this.bgDomNode.style.height=i.bgHeight+"px",typeof i.top<"u"&&(this.bgDomNode.style.top="0px"),typeof i.left<"u"&&(this.bgDomNode.style.left="0px"),typeof i.bottom<"u"&&(this.bgDomNode.style.bottom="0px"),typeof i.right<"u"&&(this.bgDomNode.style.right="0px"),this.domNode=document.createElement("div"),this.domNode.className=i.className,this.domNode.style.position="absolute";let e=Math.min(i.bgWidth,i.bgHeight);this.domNode.style.width=e+"px",this.domNode.style.height=e+"px",typeof i.top<"u"&&(this.domNode.style.top=i.top+"px"),typeof i.left<"u"&&(this.domNode.style.left=i.left+"px"),typeof i.bottom<"u"&&(this.domNode.style.bottom=i.bottom+"px"),typeof i.right<"u"&&(this.domNode.style.right=i.right+"px"),this._pointerMoveMonitor=this._register(new at),this._register(Vr(this.bgDomNode,le.POINTER_DOWN,t=>this._arrowPointerDown(t))),this._register(Vr(this.domNode,le.POINTER_DOWN,t=>this._arrowPointerDown(t))),this._pointerdownRepeatTimer=this._register(new xi),this._pointerdownScheduleRepeatTimer=this._register(new Ie)}_arrowPointerDown(i){if(!i.target||!(i.target instanceof Element))return;let e=()=>{this._pointerdownRepeatTimer.cancelAndSet(()=>this._handleActivate(),1e3/24,se(i))};this._handleActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet(e,200),this._pointerMoveMonitor.startMonitoring(i.target,i.pointerId,i.buttons,t=>{},()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()}),i.preventDefault()}};var b=class{constructor(){this._listeners=[];this._disposed=!1}get event(){return this._event?this._event:(this._event=(i,e,t)=>{if(this._disposed)return E(()=>{});let r={fn:i,thisArgs:e};this._listeners.push(r);let s=E(()=>{let o=this._listeners.indexOf(r);o!==-1&&this._listeners.splice(o,1)});return t&&(Array.isArray(t)?t.push(s):t.add(s)),s},this._event)}fire(i){if(!this._disposed)switch(this._listeners.length){case 0:return;case 1:{let{fn:e,thisArgs:t}=this._listeners[0];e.call(t,i);return}default:{let e=this._listeners.slice();for(let{fn:t,thisArgs:r}of e)t.call(r,i)}}}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},j;(r=>{function n(s,o){return s(a=>o.fire(a))}r.forward=n;function i(s,o){return(a,l,h)=>s(d=>a.call(l,o(d)),void 0,h)}r.map=i;function e(...s){return(o,a,l)=>{let h=new pe;for(let d of s)h.add(d(c=>o.call(a,c)));return l&&(Array.isArray(l)?l.push(h):l.add(h)),h}}r.any=e;function t(s,o,a){return o(a),s(l=>o(l))}r.runAndSubscribe=t})(j||={});var Jr=class n{constructor(i,e,t,r,s,o,a){this._forceIntegerValues=i;this._scrollStateBrand=void 0;this._forceIntegerValues&&(e=e|0,t=t|0,r=r|0,s=s|0,o=o|0,a=a|0),this.rawScrollLeft=r,this.rawScrollTop=a,e<0&&(e=0),r+e>t&&(r=t-e),r<0&&(r=0),s<0&&(s=0),a+s>o&&(a=o-s),a<0&&(a=0),this.width=e,this.scrollWidth=t,this.scrollLeft=r,this.height=s,this.scrollHeight=o,this.scrollTop=a}equals(i){return this.rawScrollLeft===i.rawScrollLeft&&this.rawScrollTop===i.rawScrollTop&&this.width===i.width&&this.scrollWidth===i.scrollWidth&&this.scrollLeft===i.scrollLeft&&this.height===i.height&&this.scrollHeight===i.scrollHeight&&this.scrollTop===i.scrollTop}withScrollDimensions(i,e){return new n(this._forceIntegerValues,typeof i.width<"u"?i.width:this.width,typeof i.scrollWidth<"u"?i.scrollWidth:this.scrollWidth,e?this.rawScrollLeft:this.scrollLeft,typeof i.height<"u"?i.height:this.height,typeof i.scrollHeight<"u"?i.scrollHeight:this.scrollHeight,e?this.rawScrollTop:this.scrollTop)}withScrollPosition(i){return new n(this._forceIntegerValues,this.width,this.scrollWidth,typeof i.scrollLeft<"u"?i.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,typeof i.scrollTop<"u"?i.scrollTop:this.rawScrollTop)}createScrollEvent(i,e){let t=this.width!==i.width,r=this.scrollWidth!==i.scrollWidth,s=this.scrollLeft!==i.scrollLeft,o=this.height!==i.height,a=this.scrollHeight!==i.scrollHeight,l=this.scrollTop!==i.scrollTop;return{inSmoothScrolling:e,oldWidth:i.width,oldScrollWidth:i.scrollWidth,oldScrollLeft:i.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:i.height,oldScrollHeight:i.scrollHeight,oldScrollTop:i.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:t,scrollWidthChanged:r,scrollLeftChanged:s,heightChanged:o,scrollHeightChanged:a,scrollTopChanged:l}}},lt=class extends g{constructor(e){super();this._scrollableBrand=void 0;this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new Jr(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){let r=this._state.withScrollDimensions(e,t);this._setState(r,!!this._smoothScrolling),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){let t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(this._smoothScrollDuration===0){this.setScrollPositionNow(e);return}if(this._smoothScrolling){e={scrollLeft:typeof e.scrollLeft>"u"?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:typeof e.scrollTop>"u"?this._smoothScrolling.to.scrollTop:e.scrollTop};let r=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===r.scrollLeft&&this._smoothScrolling.to.scrollTop===r.scrollTop)return;let s;t?s=new Vt(this._smoothScrolling.from,r,this._smoothScrolling.startTime,this._smoothScrolling.duration):s=Vt.start(this._state,r,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{let r=this._state.withScrollPosition(e);this._smoothScrolling=Vt.start(this._state,r,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}hasPendingScrollAnimation(){return!!this._smoothScrolling}_performSmoothScrolling(){if(!this._smoothScrolling)return;let e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);if(this._setState(t,!0),!!this._smoothScrolling){if(e.isDone){this._smoothScrolling.dispose(),this._smoothScrolling=null;return}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}}_setState(e,t){let r=this._state;r.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(r,t)))}},Di=class{constructor(i,e,t){this.scrollLeft=i,this.scrollTop=e,this.isDone=t}};function Zr(n,i){let e=i-n;return function(t){return n+e*$n(t)}}function Gn(n,i,e){return function(t){return t2.5*t){let s,o;return i{this._domNode?.setClassName(this._visibleClassName)},0))}_hide(i){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(i?" xterm-fade":"")))}};var qn=140,ct=class extends Ne{constructor(i){super(),this._lazyRender=i.lazyRender,this._host=i.host,this._scrollable=i.scrollable,this._scrollByPage=i.scrollByPage,this._scrollbarState=i.scrollbarState,this._visibilityController=this._register(new Ri(i.visibility,"xterm-visible xterm-scrollbar "+i.extraScrollbarClassName,"xterm-invisible xterm-scrollbar "+i.extraScrollbarClassName)),this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._pointerMoveMonitor=this._register(new at),this._shouldRender=!0,this.domNode=new we(document.createElement("div")),this.domNode.setAttribute("role","presentation"),this.domNode.setAttribute("aria-hidden","true"),this._visibilityController.setDomNode(this.domNode),this.domNode.setPosition("absolute"),this._register(C(this.domNode.domNode,le.POINTER_DOWN,e=>this._domNodePointerDown(e)))}_createArrow(i){let e=this._register(new Ti(i));return this.domNode.domNode.appendChild(e.bgDomNode),this.domNode.domNode.appendChild(e.domNode),e}_createSlider(i,e,t,r){this.slider=new we(document.createElement("div")),this.slider.setClassName("xterm-slider"),this.slider.setPosition("absolute"),this.slider.setTop(i),this.slider.setLeft(e),typeof t=="number"&&this.slider.setWidth(t),typeof r=="number"&&this.slider.setHeight(r),this.slider.setLayerHinting(!0),this.slider.setContain("strict"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(C(this.slider.domNode,le.POINTER_DOWN,s=>{s.button===0&&(s.preventDefault(),this._sliderPointerDown(s))})),this._onclick(this.slider.domNode,s=>{s.leftButton&&s.stopPropagation()})}_handleElementSize(i){return this._scrollbarState.setVisibleSize(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollSize(i){return this._scrollbarState.setScrollSize(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollPosition(i){return this._scrollbarState.setScrollPosition(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(i){i.target===this.domNode.domNode&&this._handlePointerDown(i)}delegatePointerDown(i){let e=this.domNode.domNode.getClientRects()[0].top,t=e+this._scrollbarState.getSliderPosition(),r=e+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),s=this._sliderPointerPosition(i);t<=s&&s<=r?i.button===0&&(i.preventDefault(),this._sliderPointerDown(i)):this._handlePointerDown(i)}_handlePointerDown(i){let e,t;if(i.target===this.domNode.domNode&&typeof i.offsetX=="number"&&typeof i.offsetY=="number")e=i.offsetX,t=i.offsetY;else{let s=$s(this.domNode.domNode);e=i.pageX-s.left,t=i.pageY-s.top}let r=this._pointerDownRelativePosition(e,t);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(r):this._scrollbarState.getDesiredScrollPositionFromOffset(r)),i.button===0&&(i.preventDefault(),this._sliderPointerDown(i))}_sliderPointerDown(i){if(!i.target||!(i.target instanceof Element))return;let e=this._sliderPointerPosition(i),t=this._sliderOrthogonalPointerPosition(i),r=this._scrollbarState.clone();this.slider.toggleClassName("xterm-active",!0),this._pointerMoveMonitor.startMonitoring(i.target,i.pointerId,i.buttons,s=>{let o=this._sliderOrthogonalPointerPosition(s),a=Math.abs(o-t);if(Ue&&a>qn){this._setDesiredScrollPositionNow(r.getScrollPosition());return}let h=this._sliderPointerPosition(s)-e;this._setDesiredScrollPositionNow(r.getDesiredScrollPositionFromDelta(h))},()=>{this.slider.toggleClassName("xterm-active",!1),this._host.handleDragEnd()}),this._host.handleDragStart()}_setDesiredScrollPositionNow(i){let e={};this.writeScrollPosition(e,i),this._scrollable.setScrollPositionNow(e)}updateScrollbarSize(i){this._updateScrollbarSize(i),this._scrollbarState.setScrollbarSize(i),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}};var ht=class n{constructor(i,e,t,r,s,o){this._scrollbarSize=Math.round(e),this._oppositeScrollbarSize=Math.round(t),this._arrowSize=Math.round(i),this._visibleSize=r,this._scrollSize=s,this._scrollPosition=o,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new n(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(i){let e=Math.round(i);return this._visibleSize!==e?(this._visibleSize=e,this._refreshComputedValues(),!0):!1}setScrollSize(i){let e=Math.round(i);return this._scrollSize!==e?(this._scrollSize=e,this._refreshComputedValues(),!0):!1}setScrollPosition(i){let e=Math.round(i);return this._scrollPosition!==e?(this._scrollPosition=e,this._refreshComputedValues(),!0):!1}setScrollbarSize(i){this._scrollbarSize=Math.round(i)}setArrowSize(i){let e=Math.round(i);this._arrowSize!==e&&(this._arrowSize=e,this._refreshComputedValues())}setOppositeScrollbarSize(i){this._oppositeScrollbarSize=Math.round(i)}static _computeValues(i,e,t,r,s){let o=Math.max(0,t-i),a=Math.max(0,o-2*e),l=r>0&&r>t;if(!l)return{computedAvailableSize:Math.round(o),computedIsNeeded:l,computedSliderSize:Math.round(a),computedSliderRatio:0,computedSliderPosition:0};let h=Math.round(Math.max(20,Math.floor(t*a/r))),d=(a-h)/(r-t),c=s*d;return{computedAvailableSize:Math.round(o),computedIsNeeded:l,computedSliderSize:Math.round(h),computedSliderRatio:d,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){let i=n._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=i.computedAvailableSize,this._computedIsNeeded=i.computedIsNeeded,this._computedSliderSize=i.computedSliderSize,this._computedSliderRatio=i.computedSliderRatio,this._computedSliderPosition=i.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(i){if(!this._computedIsNeeded)return 0;let e=i-this._arrowSize-this._computedSliderSize/2;return Math.round(e/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(i){if(!this._computedIsNeeded)return 0;let e=i-this._arrowSize,t=this._scrollPosition;return ethis._arrowScroll(-this._arrowScrollDelta)}),this._arrowDown=this._createArrow({className:"xterm-scra xterm-arrow-down",bottom:0,left:0,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(this._arrowScrollDelta)})),this._updateArrowSize(this._arrowUp,t),this._updateArrowSize(this._arrowDown,t),!this._arrowUp||!this._arrowDown)return;let r=e?"":"none";this._arrowUp.bgDomNode.style.display=r,this._arrowUp.domNode.style.display=r,this._arrowDown.bgDomNode.style.display=r,this._arrowDown.domNode.style.display=r}_updateArrowSize(e,t){e&&(e.bgDomNode.style.width=`${t}px`,e.bgDomNode.style.height=`${t}px`,e.domNode.style.width=`${t}px`,e.domNode.style.height=`${t}px`)}updateOptions(e){let t=e.verticalHasArrows?e.verticalScrollbarSize:0;this._scrollbarState.setArrowSize(t),this._setArrows(e.verticalHasArrows,e.verticalScrollbarSize),this.updateScrollbarSize(e.vertical===2?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}};var Qr=class{constructor(i,e,t){this.timestamp=i,this.deltaX=e,this.deltaY=t,this.score=0}},Bi=class Bi{constructor(){this._capacity=5,this._memory=[],this._front=-1,this._rear=-1}isPhysicalMouseWheel(){if(this._front===-1&&this._rear===-1)return!1;let i=1,e=0,t=1,r=this._rear;for(;r!==-1;){let s=r===this._front?i:Math.pow(2,-t);if(i-=s,e+=this._memory[r].score*s,r===this._front)break;r=(this._capacity+r-1)%this._capacity,t++}return e<=.5}acceptStandardWheelEvent(i){if(Kt){let e=se(i.browserEvent),t=Xr(e);this.accept(Date.now(),i.deltaX*t,i.deltaY*t)}else this.accept(Date.now(),i.deltaX,i.deltaY)}accept(i,e,t){let r=null,s=new Qr(i,e,t);this._front===-1&&this._rear===-1?(this._memory[0]=s,this._front=0,this._rear=0):(r=this._memory[this._rear],this._rear=(this._rear+1)%this._capacity,this._rear===this._front&&(this._front=(this._front+1)%this._capacity),this._memory[this._rear]=s),s.score=this._computeScore(s,r)}_computeScore(i,e){if(Math.abs(i.deltaX)>0&&Math.abs(i.deltaY)>0)return 1;let t=.5;if((!this._isAlmostInt(i.deltaX)||!this._isAlmostInt(i.deltaY))&&(t+=.25),e){let r=Math.abs(i.deltaX),s=Math.abs(i.deltaY),o=Math.abs(e.deltaX),a=Math.abs(e.deltaY),l=Math.max(Math.min(r,o),1),h=Math.max(Math.min(s,a),1),d=Math.max(r,o),c=Math.max(s,a);d%l===0&&c%h===0&&(t-=.5)}return Math.min(Math.max(t,0),1)}_isAlmostInt(i){return Math.abs(Math.round(i)-i)<.01}};Bi.INSTANCE=new Bi;var es=Bi,Mi=class extends Ne{constructor(e,t,r){super();this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;t=t??{};let s,o=!r;r?s=r:(t.mouseWheelSmoothScroll=!1,s=new lt({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:l=>tt(se(e),l)})),this._options=Xn(t),this._scrollable=s,this._register(this._scrollable.onScroll(l=>{this._handleScroll(l),this._onScroll.fire(l)})),o&&this._register(this._scrollable);let a={handleMouseWheel:l=>this._handleMouseWheel(l),handleDragStart:()=>this._handleDragStart(),handleDragEnd:()=>this._handleDragEnd()};this._verticalScrollbar=this._register(new ki(this._scrollable,this._options,a)),this._horizontalScrollbar=this._register(new Ai(this._scrollable,this._options,a)),this._domNode=document.createElement("div"),this._domNode.className="xterm-scrollable-element "+this._options.className,this._domNode.setAttribute("role","presentation"),this._domNode.style.position="relative",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=new we(document.createElement("div")),this._leftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=new we(document.createElement("div")),this._topShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=new we(document.createElement("div")),this._topLeftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode??this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this._onmouseover(this._listenOnDomNode,l=>this._handleMouseOver(l)),this._onmouseleave(this._listenOnDomNode,l=>this._handleMouseLeave(l)),this._hideTimeout=this._register(new Ie),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}get options(){return this._options}dispose(){this._mouseWheelToDispose=Oe(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}updateClassName(e){this._options.className=e,ie&&(this._options.className+=" xterm-mac"),this._domNode.className="xterm-scrollable-element "+this._options.className}updateOptions(e){typeof e.handleMouseWheel<"u"&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),typeof e.mouseWheelScrollSensitivity<"u"&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),typeof e.fastScrollSensitivity<"u"&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),typeof e.scrollPredominantAxis<"u"&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),typeof e.horizontal<"u"&&(this._options.horizontal=e.horizontal),typeof e.vertical<"u"&&(this._options.vertical=e.vertical),typeof e.horizontalHasArrows<"u"&&(this._options.horizontalHasArrows=e.horizontalHasArrows),typeof e.verticalHasArrows<"u"&&(this._options.verticalHasArrows=e.verticalHasArrows),typeof e.horizontalScrollbarSize<"u"&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),typeof e.verticalScrollbarSize<"u"&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),typeof e.scrollByPage<"u"&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}delegateScrollFromMouseWheelEvent(e){this._handleMouseWheel(new Gt(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=Oe(this._mouseWheelToDispose),e)){let r=s=>{this._handleMouseWheel(new Gt(s))};this._mouseWheelToDispose.push(C(this._listenOnDomNode,le.MOUSE_WHEEL,r,{passive:!1}))}}_handleMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;let t=es.INSTANCE;t.acceptStandardWheelEvent(e);let r=!1;if(e.deltaY||e.deltaX){let o=e.deltaY*this._options.mouseWheelScrollSensitivity,a=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&a+o===0?a=o=0:Math.abs(o)>=Math.abs(a)?a=0:o=0),this._options.flipAxes&&([o,a]=[a,o]);let l=!ie&&e.browserEvent&&e.browserEvent.shiftKey;(this._options.scrollYToX||l)&&!a&&(a=o,o=0),e.browserEvent&&e.browserEvent.altKey&&(a=a*this._options.fastScrollSensitivity,o=o*this._options.fastScrollSensitivity);let h=this._scrollable.getFutureScrollPosition(),d={};if(o){let c=50*o,u=h.scrollTop-(c<0?Math.floor(c):Math.ceil(c));this._verticalScrollbar.writeScrollPosition(d,u)}if(a){let c=50*a,u=h.scrollLeft-(c<0?Math.floor(c):Math.ceil(c));this._horizontalScrollbar.writeScrollPosition(d,u)}d=this._scrollable.validateScrollPosition(d),(h.scrollLeft!==d.scrollLeft||h.scrollTop!==d.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(d):this._scrollable.setScrollPositionNow(d),r=!0)}let s=r;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_handleScroll(e){this._shouldRender=this._horizontalScrollbar.handleScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.handleScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error("Please use `lazyRender` together with `renderNow`!");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){let e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,r=e.scrollLeft>0,s=r?" xterm-shadow-left":"",o=t?" xterm-shadow-top":"",a=r||t?" xterm-shadow-top-left-corner":"";this._leftShadowDomNode.setClassName(`xterm-shadow${s}`),this._topShadowDomNode.setClassName(`xterm-shadow${o}`),this._topLeftShadowDomNode.setClassName(`xterm-shadow${a}${o}${s}`)}}_handleDragStart(){this._isDragging=!0,this._reveal()}_handleDragEnd(){this._isDragging=!1,this._hide()}_handleMouseLeave(e){this._mouseIsOver=!1,this._hide()}_handleMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){!this._mouseIsOver&&!this._isDragging&&(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){!this._mouseIsOver&&!this._isDragging&&this._hideTimeout.cancelAndSet(()=>this._hide(),500)}};function Xn(n){let i={lazyRender:typeof n.lazyRender<"u"?n.lazyRender:!1,className:typeof n.className<"u"?n.className:"",useShadows:typeof n.useShadows<"u"?n.useShadows:!0,handleMouseWheel:typeof n.handleMouseWheel<"u"?n.handleMouseWheel:!0,flipAxes:typeof n.flipAxes<"u"?n.flipAxes:!1,consumeMouseWheelIfScrollbarIsNeeded:typeof n.consumeMouseWheelIfScrollbarIsNeeded<"u"?n.consumeMouseWheelIfScrollbarIsNeeded:!1,alwaysConsumeMouseWheel:typeof n.alwaysConsumeMouseWheel<"u"?n.alwaysConsumeMouseWheel:!1,scrollYToX:typeof n.scrollYToX<"u"?n.scrollYToX:!1,mouseWheelScrollSensitivity:typeof n.mouseWheelScrollSensitivity<"u"?n.mouseWheelScrollSensitivity:1,fastScrollSensitivity:typeof n.fastScrollSensitivity<"u"?n.fastScrollSensitivity:5,scrollPredominantAxis:typeof n.scrollPredominantAxis<"u"?n.scrollPredominantAxis:!0,mouseWheelSmoothScroll:typeof n.mouseWheelSmoothScroll<"u"?n.mouseWheelSmoothScroll:!0,listenOnDomNode:typeof n.listenOnDomNode<"u"?n.listenOnDomNode:null,horizontal:typeof n.horizontal<"u"?n.horizontal:1,horizontalScrollbarSize:typeof n.horizontalScrollbarSize<"u"?n.horizontalScrollbarSize:10,horizontalSliderSize:typeof n.horizontalSliderSize<"u"?n.horizontalSliderSize:0,horizontalHasArrows:typeof n.horizontalHasArrows<"u"?n.horizontalHasArrows:!1,vertical:typeof n.vertical<"u"?n.vertical:1,verticalScrollbarSize:typeof n.verticalScrollbarSize<"u"?n.verticalScrollbarSize:10,verticalHasArrows:typeof n.verticalHasArrows<"u"?n.verticalHasArrows:!1,verticalSliderSize:typeof n.verticalSliderSize<"u"?n.verticalSliderSize:0,scrollByPage:typeof n.scrollByPage<"u"?n.scrollByPage:!1};return i.horizontalSliderSize=typeof n.horizontalSliderSize<"u"?n.horizontalSliderSize:i.horizontalScrollbarSize,i.verticalSliderSize=typeof n.verticalSliderSize<"u"?n.verticalSliderSize:i.verticalScrollbarSize,ie&&(i.className+=" xterm-mac"),i}var dt=class extends g{constructor(e,t,r,s,o,a,l,h,d){super();this._bufferService=r;this._coreService=o;this._optionsService=h;this._renderService=d;this._onRequestScrollLines=this._register(new b);this.onRequestScrollLines=this._onRequestScrollLines.event;this._isSyncing=!1;this._isHandlingScroll=!1;this._suppressOnScrollHandler=!1;this._needsSyncOnRender=!1;let c=this._register(new lt({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:u=>tt(s.window,u)}));this._register(this._optionsService.onSpecificOptionChange("smoothScrollDuration",()=>{c.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)})),this._scrollableElement=this._register(new Mi(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,verticalHasArrows:this._optionsService.rawOptions.scrollbar?.showArrows??!1,...this._getChangeOptions()},c)),this._register(this._optionsService.onMultipleOptionChange(["scrollSensitivity","fastScrollSensitivity","scrollbar"],()=>this._scrollableElement.updateOptions(this._getChangeOptions()))),this._register(a.onProtocolChange(u=>{this._scrollableElement.updateOptions({handleMouseWheel:!(u&16)})})),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(j.runAndSubscribe(l.onChangeColors,()=>{e.style.backgroundColor=l.colors.background.css,this._scrollableElement.getDomNode().style.backgroundColor=l.colors.background.css})),e.appendChild(this._scrollableElement.getDomNode()),this._register(E(()=>this._scrollableElement.getDomNode().remove())),this._styleElement=s.mainDocument.createElement("style"),t.appendChild(this._styleElement),this._register(E(()=>this._styleElement.remove())),this._register(j.runAndSubscribe(l.onChangeColors,()=>{this._styleElement.textContent=[".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {",` background: ${l.colors.scrollbarSliderBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {",` background: ${l.colors.scrollbarSliderHoverBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {",` background: ${l.colors.scrollbarSliderActiveBackground.css};`,"}"].join(` -`)})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(u=>this._handleScroll(u)))}scrollLines(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){let e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,r=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:r,verticalHasArrows:t}}queueSync(e){e!==void 0&&(this._latestYDisp=e),this._queuedAnimationFrame===void 0&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){if(!(!this._renderService||this._isSyncing)){if(this._coreService.decPrivateModes.synchronizedOutput){this._needsSyncOnRender=!0;return}this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1}}_handleScroll(e){if(!this._renderService||this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;let t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),r=t-this._bufferService.buffer.ydisp;r!==0&&(this._latestYDisp=t,this._onRequestScrollLines.fire(r)),this._isHandlingScroll=!1}handleTouchScroll(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};dt=y([m(2,D),m(3,G),m(4,Y),m(5,Me),m(6,_e),m(7,R),m(8,V)],dt);var ut=class extends g{constructor(e,t,r,s,o){super();this._screenElement=e;this._bufferService=t;this._coreBrowserService=r;this._decorationService=s;this._renderService=o;this._decorationElements=new Map;this._altBufferIsActive=!1;this._dimensionsChanged=!1;this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(a=>this._removeDecoration(a))),this._register(E(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){this._animationFrame===void 0&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(let e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){let t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer",e?.options?.layer==="top"),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,t.style.top=`${(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height}px`,t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;let r=e.options.x??0;return r&&r>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){let t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let r=this._decorationElements.get(e);r||(r=this._createElement(e),e.element=r,this._decorationElements.set(e,r),this._container.appendChild(r),e.onDispose(()=>{this._decorationElements.delete(e),r.remove()})),r.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(r.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,r.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,r.style.top=`${t*this._renderService.dimensions.css.cell.height}px`,r.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(r)}}_refreshXPosition(e,t=e.element){if(!t)return;let r=e.options.x??0;(e.options.anchor||"left")==="right"?t.style.right=r?`${r*this._renderService.dimensions.css.cell.width}px`:"":t.style.left=r?`${r*this._renderService.dimensions.css.cell.width}px`:""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};ut=y([m(1,D),m(2,G),m(3,ge),m(4,V)],ut);var Pi=class{constructor(){this._zones=[];this._zonePool=[];this._zonePoolIndex=0;this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(i){if(i.options.overviewRulerOptions){for(let e of this._zones)if(e.color===i.options.overviewRulerOptions.color&&e.position===i.options.overviewRulerOptions.position){if(this._lineIntersectsZone(e,i.marker.line))return;if(this._lineAdjacentToZone(e,i.marker.line,i.options.overviewRulerOptions.position)){this._addLineToZone(e,i.marker.line);return}}if(this._zonePoolIndex=i.startBufferLine&&e<=i.endBufferLine}_lineAdjacentToZone(i,e,t){return e>=i.startBufferLine-this._linePadding[t||"full"]&&e<=i.endBufferLine+this._linePadding[t||"full"]}_addLineToZone(i,e){i.startBufferLine=Math.min(i.startBufferLine,e),i.endBufferLine=Math.max(i.endBufferLine,e)}};var Ce={full:0,left:0,center:0,right:0},Fe={full:0,left:0,center:0,right:0},$t={full:0,left:0,center:0,right:0},ze=class extends g{constructor(e,t,r,s,o,a,l,h){super();this._viewportElement=e;this._screenElement=t;this._bufferService=r;this._decorationService=s;this._renderService=o;this._optionsService=a;this._themeService=l;this._coreBrowserService=h;this._colorZoneStore=new Pi;this._shouldUpdateDimensions=!0;this._shouldUpdateAnchor=!0;this._lastKnownBufferLength=0;this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register(E(()=>this._canvas?.remove()));let d=this._canvas.getContext("2d");if(d)this._ctx=d;else throw new Error("Ctx cannot be null");this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register(E(()=>{this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}get _width(){let e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??!0?e?.width??0:0}_refreshDrawConstants(){let e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);Fe.full=this._canvas.width,Fe.left=e,Fe.center=t,Fe.right=e,this._refreshDrawHeightConstants(),$t.full=1,$t.left=1,$t.center=1+Fe.left,$t.right=1+Fe.left+Fe.center}_refreshDrawHeightConstants(){Ce.full=Math.round(2*this._coreBrowserService.dpr);let e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);Ce.left=t,Ce.center=t,Ce.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ce.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ce.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ce.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ce.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;let e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(let t of this._decorationService.decorations)this._colorZoneStore.addDecoration(t);this._ctx.lineWidth=1,this._renderRulerOutline();let e=this._colorZoneStore.zones;for(let t of e)t.position!=="full"&&this._renderColorZone(t);for(let t of e)t.position==="full"&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect($t[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-Ce[e.position||"full"]/2),Fe[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+Ce[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};ze=y([m(2,D),m(3,ge),m(4,V),m(5,R),m(6,_e),m(7,G)],ze);var ft=class{constructor(i,e,t,r,s,o){this._textarea=i;this._compositionView=e;this._bufferService=t;this._optionsService=r;this._coreService=s;this._renderService=o;this._isComposing=!1,this._isSendingComposition=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent=""}get isComposing(){return this._isComposing}compositionstart(){this._isComposing=!0;let i=this._textarea.selectionStart??this._textarea.value.length,e=this._textarea.selectionEnd??i;this._compositionPosition.start=Math.min(i,e),this._compositionPosition.end=Math.max(i,e),this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionView.classList.add("active")}compositionupdate(i){this._compositionView.textContent=`\u200E${i.data}\u200E`,this.updateCompositionElements(),setTimeout(()=>{let e=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,e)},0)}compositionend(){this._finalizeComposition(!0)}keydown(i){if(this._isComposing||this._isSendingComposition){if(i.keyCode===20||i.keyCode===229||i.keyCode===16||i.keyCode===17||i.keyCode===18)return!1;this._finalizeComposition(!1)}return i.keyCode===229?(this._handleAnyTextareaChanges(),!1):!0}_finalizeComposition(i){if(this._compositionView.classList.remove("active"),this._isComposing=!1,i){let e={start:this._compositionPosition.start,end:this._compositionPosition.end},t=this._compositionSuffix;this._isSendingComposition=!0,setTimeout(()=>{if(this._isSendingComposition){this._isSendingComposition=!1;let r;if(e.start+=this._dataAlreadySent.length,this._isComposing)r=this._textarea.value.substring(e.start,this._compositionPosition.start);else{let s=this._textarea.value,o=t.length>0&&s.endsWith(t)?s.length-t.length:s.length;r=s.substring(e.start,Math.max(e.start,o))}r.length>0&&this._coreService.triggerDataEvent(r,!0)}},0)}else{this._isSendingComposition=!1;let e=this._textarea.value.substring(this._compositionPosition.start,this._compositionPosition.end);this._coreService.triggerDataEvent(e,!0)}}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;let i=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){let e=this._textarea.value,t=e.replace(i,"");this._dataAlreadySent=t,e.length>i.length?this._coreService.triggerDataEvent(t,!0):e.lengththis.updateCompositionElements(!0),0)}}};ft=y([m(2,D),m(3,R),m(4,Y),m(5,V)],ft);var J=0,Q=0,ee=0,W=0,ts={css:"#00000000",rgba:0},O;(t=>{function n(r,s,o,a){return a!==void 0?`#${Ve(r)}${Ve(s)}${Ve(o)}${Ve(a)}`:`#${Ve(r)}${Ve(s)}${Ve(o)}`}t.toCss=n;function i(r,s,o,a=255){return(r<<24|s<<16|o<<8|a)>>>0}t.toRgba=i;function e(r,s,o,a){return{css:t.toCss(r,s,o,a),rgba:t.toRgba(r,s,o,a)}}t.toColor=e})(O||={});var k;(a=>{function n(l,h){if(W=(h.rgba&255)/255,W===1)return{css:h.css,rgba:h.rgba};let d=h.rgba>>24&255,c=h.rgba>>16&255,u=h.rgba>>8&255,_=l.rgba>>24&255,p=l.rgba>>16&255,v=l.rgba>>8&255;J=_+Math.round((d-_)*W),Q=p+Math.round((c-p)*W),ee=v+Math.round((u-v)*W);let f=O.toCss(J,Q,ee),S=O.toRgba(J,Q,ee);return{css:f,rgba:S}}a.blend=n;function i(l){return(l.rgba&255)===255}a.isOpaque=i;function e(l,h,d){let c=Oi.ensureContrastRatio(l.rgba,h.rgba,d);if(c)return O.toColor(c>>24&255,c>>16&255,c>>8&255)}a.ensureContrastRatio=e;function t(l){let h=(l.rgba|255)>>>0;return[J,Q,ee]=Oi.toChannels(h),{css:O.toCss(J,Q,ee),rgba:h}}a.opaque=t;function r(l,h){return W=Math.round(h*255),[J,Q,ee]=Oi.toChannels(l.rgba),{css:O.toCss(J,Q,ee,W),rgba:O.toRgba(J,Q,ee,W)}}a.opacity=r;function s(l,h){return W=l.rgba&255,r(l,W*h/255)}a.multiplyOpacity=s;function o(l){return[l.rgba>>24&255,l.rgba>>16&255,l.rgba>>8&255]}a.toColorRGB=o})(k||={});var B;(t=>{let n,i;try{let r=document.createElement("canvas");r.width=1,r.height=1;let s=r.getContext("2d",{willReadFrequently:!0});s&&(n=s,n.globalCompositeOperation="copy",i=n.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),O.toColor(J,Q,ee);case 5:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),W=parseInt(r.slice(4,5).repeat(2),16),O.toColor(J,Q,ee,W);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let s=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(s)return J=parseInt(s[1],10),Q=parseInt(s[2],10),ee=parseInt(s[3],10),W=Math.round((s[5]===void 0?1:parseFloat(s[5]))*255),O.toColor(J,Q,ee,W);if(r==="transparent")return{css:"transparent",rgba:0};if(!n||!i)throw new Error("css.toColor: Unsupported css format");if(n.fillStyle=i,n.fillStyle=r,typeof n.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(n.fillRect(0,0,1,1),[J,Q,ee,W]=n.getImageData(0,0,1,1).data,W!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:O.toRgba(J,Q,ee,W),css:r}}t.toColor=e})(B||={});var Z;(e=>{function n(t){return i(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=n;function i(t,r,s){let o=t/255,a=r/255,l=s/255,h=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4),d=a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4),c=l<=.03928?l/12.92:Math.pow((l+.055)/1.055,2.4);return h*.2126+d*.7152+c*.0722}e.relativeLuminance2=i})(Z||={});var Oi;(s=>{function n(o,a){if(W=(a&255)/255,W===1)return a;let l=a>>24&255,h=a>>16&255,d=a>>8&255,c=o>>24&255,u=o>>16&255,_=o>>8&255;return J=c+Math.round((l-c)*W),Q=u+Math.round((h-u)*W),ee=_+Math.round((d-_)*W),O.toRgba(J,Q,ee)}s.blend=n;function i(o,a,l){let h=Z.relativeLuminance(o>>8),d=Z.relativeLuminance(a>>8);if(Te(h,d)>8));if(v>8));return v>S?p:f}return p}let u=t(o,a,l),_=Te(h,Z.relativeLuminance(u>>8));if(_>8));return _>v?u:p}return u}}s.ensureContrastRatio=i;function e(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=Te(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v0||_>0||p>0);)u-=Math.max(0,Math.ceil(u*.1)),_-=Math.max(0,Math.ceil(_*.1)),p-=Math.max(0,Math.ceil(p*.1)),v=Te(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));return(u<<24|_<<16|p<<8|255)>>>0}s.reduceLuminance=e;function t(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=Te(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v>>0}s.increaseLuminance=t;function r(o){return[o>>24&255,o>>16&255,o>>8&255,o&255]}s.toChannels=r})(Oi||={});function Ve(n){let i=n.toString(16);return i.length<2?"0"+i:i}function Te(n,i){return n1){let u=this._getJoinedRanges(r,l,a,e,o);for(let _=0;_1){let c=this._getJoinedRanges(r,l,a,e,o);for(let u=0;u=ks,Lr=ae,x=this._workCell;if(v.length>0&&ae===v[0][0]&&je){let A=v.shift(),Pr=this._isCellInSelection(A[0],e);for(T=A[0]+1;T=A[1],je?(fi=!0,x=new Ni(this._workCell,i.translateToString(!0,A[0],A[1]),A[1]-A[0]),Lr=A[1]-1,Rr=x.getWidth()):ks=A[1]}let Nt=this._isCellInSelection(ae,e),Ar=t&&ae===o,kr=An&&ae>=c&&ae<=u;_&&x.isBlink()&&(_.hasBlinkingCells=!0),!l&&x.isBlink()&&N.push("xterm-blink-hidden");let Mr=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{Mr=!0});let _i=x.getChars()||" ";if(_i===" "&&(x.isUnderline()||x.isOverline())&&(_i="\xA0"),Ot=Rr*h-d.get(_i,x.isBold(),x.isItalic()),!I)I=this._document.createElement("span");else if(w&&(Nt&&ui||!Nt&&!ui&&x.bg===te)&&(Nt&&ui&&f.selectionForeground||x.fg===Ds)&&x.extended.ext===Rs&&kr===Ls&&Ot===As&&!Ar&&!fi&&!Mr&&je){x.isInvisible()?L+=" ":L+=_i,w++;continue}else w&&(I.textContent=L),I=this._document.createElement("span"),w=0,L="";if(te=x.bg,Ds=x.fg,Rs=x.extended.ext,Ls=kr,As=Ot,ui=Nt,fi&&o>=ae&&o<=Lr&&(o=ae),!this._coreService.isCursorHidden&&Ar&&this._coreService.isCursorInitialized){if(N.push("xterm-cursor"),this._coreBrowserService.isFocused)a&&N.push("xterm-cursor-blink"),N.push(r==="bar"?"xterm-cursor-bar":r==="underline"?"xterm-cursor-underline":"xterm-cursor-block");else if(s)switch(s){case"outline":N.push("xterm-cursor-outline");break;case"block":N.push("xterm-cursor-block");break;case"bar":N.push("xterm-cursor-bar");break;case"underline":N.push("xterm-cursor-underline");break;default:break}}if(x.isBold()&&N.push("xterm-bold"),x.isItalic()&&N.push("xterm-italic"),x.isDim()&&N.push("xterm-dim"),x.isInvisible()?L=" ":L=x.getChars()||" ",x.isUnderline()&&(N.push(`xterm-underline-${x.extended.underlineStyle}`),L===" "&&(L="\xA0"),!x.isUnderlineColorDefault()))if(x.isUnderlineColorRGB())I.style.textDecorationColor=`rgb(${ue.toColorRGB(x.getUnderlineColor()).join(",")})`;else{let A=x.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&x.isBold()&&A<8&&(A+=8),I.style.textDecorationColor=f.ansi[A].css}x.isOverline()&&(N.push("xterm-overline"),L===" "&&(L="\xA0")),x.isStrikethrough()&&N.push("xterm-strikethrough"),kr&&(I.style.textDecoration="underline");let de=x.getFgColor(),Ft=x.getFgColorMode(),Se=x.getBgColor(),Ht=x.getBgColorMode(),Br=!!x.isInverse();if(Br){let A=de;de=Se,Se=A;let Pr=Ft;Ft=Ht,Ht=Pr}let Le,pi,Wt=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{A.options.layer!=="top"&&Wt||(A.backgroundColorRGB&&(Ht=50331648,Se=A.backgroundColorRGB.rgba>>8&16777215,Le=A.backgroundColorRGB),A.foregroundColorRGB&&(Ft=50331648,de=A.foregroundColorRGB.rgba>>8&16777215,pi=A.foregroundColorRGB),Wt=A.options.layer==="top")}),!Wt&&Nt&&(Le=this._coreBrowserService.isFocused?f.selectionBackgroundOpaque:f.selectionInactiveBackgroundOpaque,Se=Le.rgba>>8&16777215,Ht=50331648,Wt=!0,f.selectionForeground&&(Ft=50331648,de=f.selectionForeground.rgba>>8&16777215,pi=f.selectionForeground)),Wt&&N.push("xterm-decoration-top");let Ae;switch(Ht){case 16777216:case 33554432:Ae=f.ansi[Se],N.push(`xterm-bg-${Se}`);break;case 50331648:Ae=O.toColor(Se>>16,Se>>8&255,Se&255),this._addStyle(I,`background-color:#${(Se>>>0).toString(16).padStart(6,"0")}`);break;case 0:default:Br?(Ae=f.foreground,N.push(`xterm-bg-${257}`)):Ae=f.background}switch(Le||x.isDim()&&(Le=k.multiplyOpacity(Ae,.5)),Ft){case 16777216:case 33554432:x.isBold()&&de<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(de+=8),this._applyMinimumContrast(I,Ae,f.ansi[de],x,Le,void 0)||N.push(`xterm-fg-${de}`);break;case 50331648:let A=O.toColor(de>>16&255,de>>8&255,de&255);this._applyMinimumContrast(I,Ae,A,x,Le,pi)||this._addStyle(I,`color:#${de.toString(16).padStart(6,"0")}`);break;case 0:default:this._applyMinimumContrast(I,Ae,f.foreground,x,Le,pi)||Br&&N.push(`xterm-fg-${257}`)}N.length&&(I.className=N.join(" "),N.length=0),!Ar&&!fi&&!Mr&&je?w++:I.textContent=L,Ot!==this.defaultSpacing&&(I.style.letterSpacing=`${Ot}px`),p.push(I),ae=Lr}return I&&w&&(I.textContent=L),p}_applyMinimumContrast(i,e,t,r,s,o){if(this._optionsService.rawOptions.minimumContrastRatio===1||js(r.getCode()))return!1;let a=this._getContrastCache(r),l;if(!s&&!o&&(l=a.getColor(e.rgba,t.rgba)),l===void 0){let h=this._optionsService.rawOptions.minimumContrastRatio/(r.isDim()?2:1);l=k.ensureContrastRatio(s??e,o??t,h),a.setColor((s??e).rgba,(o??t).rgba,l??null)}return l?(this._addStyle(i,`color:${l.css}`),!0):!1}_getContrastCache(i){return i.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(i,e){i.setAttribute("style",`${i.getAttribute("style")||""}${e};`)}_isCellInSelection(i,e){let t=this._selectionStart,r=this._selectionEnd;return!t||!r?!1:this._columnSelectMode?t[0]<=r[0]?i>=t[0]&&e>=t[1]&&i=t[1]&&i>=r[0]&&e<=r[1]:e>t[1]&&e=t[0]&&i=t[0]}};_t=y([m(1,gi),m(2,R),m(3,G),m(4,Y),m(5,ge),m(6,_e)],_t);var Hi=class{constructor(i=()=>new rs){this._flat=new Float32Array(256);this._font="";this._fontSize=0;this._weight="normal";this._weightBold="bold";this._canvasElements=[];this._canvasElements=[i(),i(),i(),i()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(i,e,t,r){i===this._font&&e===this._fontSize&&t===this._weight&&r===this._weightBold||(this._font=i,this._fontSize=e,this._weight=t,this._weightBold=r,this._canvasElements[0].setFont(i,e,t,!1),this._canvasElements[1].setFont(i,e,r,!1),this._canvasElements[2].setFont(i,e,t,!0),this._canvasElements[3].setFont(i,e,r,!0),this.clear())}get(i,e,t){let r;if(!e&&!t&&i.length===1&&(r=i.charCodeAt(0))<256){if(this._flat[r]!==-9999)return this._flat[r];let a=this._measure(i,0);return a>0&&(this._flat[r]=a),a}let s=i;e&&(s+="B"),t&&(s+="I");let o=this._holey.get(s);if(o===void 0){let a=0;e&&(a|=1),t&&(a|=2),o=this._measure(i,a),o>0&&this._holey.set(s,o)}return o}_measure(i,e){return this._canvasElements[e].measure(i)}},rs=class{constructor(){typeof OffscreenCanvas<"u"?(this._canvas=new OffscreenCanvas(1,1),this._ctx=is(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=is(this._canvas.getContext("2d")))}setFont(i,e,t,r){let s=r?"italic":"";this._ctx.font=`${s} ${t} ${e}px ${i}`.trim()}measure(i){return this._ctx.measureText(i).width}};var ss=class{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(i,e,t,r=!1){if(this.selectionStart=e,this.selectionEnd=t,!e||!t||e[0]===t[0]&&e[1]===t[1]){this.clear();return}let s=i.buffers.active.ydisp,o=e[1]-s,a=t[1]-s,l=Math.max(o,0),h=Math.min(a,i.rows-1);if(l>=i.rows||h<0){this.clear();return}this.hasSelection=!0,this.columnSelectMode=r,this.viewportStartRow=o,this.viewportEndRow=a,this.viewportCappedStartRow=l,this.viewportCappedEndRow=h,this.startCol=e[0],this.endCol=t[0]}isCellSelected(i,e,t){return this.hasSelection?(t-=i.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?e>=this.startCol&&t>=this.viewportCappedStartRow&&e=this.viewportCappedStartRow&&e>=this.endCol&&t<=this.viewportCappedEndRow:t>this.viewportStartRow&&t=this.startCol&&e=this.startCol):!1}};function Js(){return new ss}var Wi=class extends g{constructor(e,t,r){super();this._renderCallback=e;this._coreBrowserService=t;this._optionsService=r;this._intervalDuration=0;this._blinkOn=!0;this._needsBlinkInViewport=!1;this._isViewportVisible=!0;this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",s=>{this.setIntervalDuration(s)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register(E(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(this._interval!==void 0)return;let t=this._blinkOn;this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),t||this._renderCallback();return}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){this._interval!==void 0&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}};var Zn=1,mt=class extends g{constructor(e,t,r,s,o,a,l,h,d,c,u,_,p,v){super();this._terminal=e;this._document=t;this._element=r;this._screenElement=s;this._viewportElement=o;this._helperContainer=a;this._linkifier2=l;this._charSizeService=d;this._optionsService=c;this._bufferService=u;this._coreService=_;this._coreBrowserService=p;this._themeService=v;this._terminalClass=Zn++;this._rowElements=[];this._selectionRenderModel=Js();this._lastSelectionColumnMode=!1;this._rowHasBlinkingCells=[];this._rowHasBlinkingCellsCount=0;this._onRequestRedraw=this._register(new b);this.onRequestRedraw=this._onRequestRedraw.event;this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=Zs(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(f=>this._injectCss(f))),this._injectCss(this._themeService.colors),this._rowFactory=h.createInstance(_t,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(f=>this._handleLinkHover(f))),this._register(this._linkifier2.onHideLinkUnderline(f=>this._handleLinkLeave(f))),this._cursorBlinkStateManager=new ns(this._rowContainer,this._coreBrowserService),this._register(C(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register(E(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new Wi(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register(E(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new Hi,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){let e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(let r of this._rowElements)r.style.width=`${this.dimensions.css.canvas.width}px`,r.style.height=`${this.dimensions.css.cell.height}px`,r.style.lineHeight=`${this.dimensions.css.cell.height}px`,r.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));let t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${k.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;let r=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,o=`blink_block_${this._terminalClass}`;t+=`@keyframes ${r} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${o} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${o} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(let[a,l]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${a} { color: ${l.css}; }${this._terminalSelector} .xterm-fg-${a}.xterm-dim { color: ${k.multiplyOpacity(l,.5).css}; }${this._terminalSelector} .xterm-bg-${a} { background-color: ${l.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${257} { color: ${k.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${257}.xterm-dim { color: ${k.multiplyOpacity(k.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${257} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){let e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let r=this._rowElements.length;r<=t;r++){let s=this._document.createElement("div");this._rowContainer.appendChild(s),this._rowElements.push(s),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,r){let s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,r);let o=0,a=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(o=this._selectionRenderModel.viewportCappedStartRow,a=this._selectionRenderModel.viewportCappedEndRow));let l=0,h=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,r),this._selectionRenderModel.hasSelection){let u=this._selectionRenderModel.viewportStartRow,_=this._selectionRenderModel.viewportEndRow,p=this._selectionRenderModel.viewportCappedStartRow,v=this._selectionRenderModel.viewportCappedEndRow;l=p,h=v;let f=this._document.createDocumentFragment();if(r){let S=e[0]>t[0];f.appendChild(this._createSelectionElement(p,S?t[0]:e[0],S?e[0]:t[0],v-p+1))}else{let S=u===p?e[0]:0,I=p===_?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(p,S,I));let w=v-p-1;if(f.appendChild(this._createSelectionElement(p+1,0,this._bufferService.cols,w)),p!==v){let L=_===v?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(v,0,L))}}this._selectionContainer.appendChild(f)}let d=Math.min(o,l),c=Math.max(a,h);if(c>=0){d=Math.max(d,0),c=Math.min(c,s-1);let _=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&_>=0&&_this.dimensions.css.canvas.width&&(l=this.dimensions.css.canvas.width-a),o.style.height=`${s*this.dimensions.css.cell.height}px`,o.style.top=`${e*this.dimensions.css.cell.height}px`,o.style.left=`${a}px`,o.style.width=`${l}px`,o}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(let e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){let r=this._bufferService.buffer,s=r.ybase+r.y,o=Math.min(r.x,this._bufferService.cols-1),a=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,l=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,h=this._optionsService.rawOptions.cursorInactiveStyle,d={hasBlinkingCells:!1};for(let c=e;c<=t;c++){let u=c+r.ydisp,_=this._rowElements[c];if(!_)continue;let p=r.lines.get(u);if(!p){_.replaceChildren(),this._setRowBlinkState(c,!1);continue}_.replaceChildren(...this._rowFactory.createRow(p,u,u===s,l,h,o,a,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,d)),this._setRowBlinkState(c,d.hasBlinkingCells)}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,r,s,o,a){r<0&&(e=0),s<0&&(t=0);let l=this._bufferService.rows-1;r=Math.max(Math.min(r,l),0),s=Math.max(Math.min(s,l),0),o=Math.min(o,this._bufferService.cols);let h=this._bufferService.buffer,d=h.ybase+h.y,c=Math.min(h.x,o-1),u=this._optionsService.rawOptions.cursorBlink,_=this._optionsService.rawOptions.cursorStyle,p=this._optionsService.rawOptions.cursorInactiveStyle,v={hasBlinkingCells:!1};for(let f=r;f<=s;++f){let S=f+h.ydisp,I=this._rowElements[f];if(!I)continue;let w=h.lines.get(S);if(!w){I.replaceChildren(),this._setRowBlinkState(f,!1);continue}I.replaceChildren(...this._rowFactory.createRow(w,S,S===d,_,p,c,u,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,a?f===r?e:0:-1,a?(f===s?t:o)-1:-1,v)),this._setRowBlinkState(f,v.hasBlinkingCells)}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};mt=y([m(7,Qe),m(8,Be),m(9,R),m(10,D),m(11,Y),m(12,G),m(13,_e)],mt);var ns=class{constructor(i,e){this._rowContainer=i;this._coreBrowserService=e;this._isIdlePaused=!1;this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){this._idleTimeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}};var bt=class extends g{constructor(e,t,r){super();this._optionsService=r;this.width=0;this.height=0;this._onCharSizeChange=this._register(new b);this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new as(this._optionsService))}catch{this._measureStrategy=this._register(new os(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}get hasValidSize(){return this.width>0&&this.height>0}measure(){let e=this._measureStrategy.measure();(e.width!==this.width||e.height!==this.height)&&(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};bt=y([m(2,R)],bt);var Ui=class extends g{constructor(){super(...arguments);this._result={width:0,height:0}}_validateAndSet(e,t){e!==void 0&&e>0&&t!==void 0&&t>0&&(this._result.width=e,this._result.height=t)}},os=class extends Ui{constructor(e,t,r){super();this._document=e;this._parentElement=t;this._optionsService=r;this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}},as=class extends Ui{constructor(e){super();this._optionsService=e;this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");let t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;let e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}};var Ki=class extends g{constructor(e,t,r){super();this._textarea=e;this._window=t;this.mainDocument=r;this._isFocused=!1;this._cachedIsFocused=void 0;this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._onWindowChange=this._register(new b);this.onWindowChange=this._onWindowChange.event;this._screenDprMonitor=this._register(new ls(this._window)),this._register(this.onWindowChange(s=>this._screenDprMonitor.setWindow(s))),this._register(j.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register(C(this._textarea,"focus",()=>this._isFocused=!0)),this._register(C(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return this._cachedIsFocused===void 0&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}},ls=class extends g{constructor(e){super();this._parentWindow=e;this._windowResizeListener=this._register(new P);this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register(E(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=C(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){!this._resolutionMediaMatchList||!this._outerListener||(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}};var zi=class extends g{constructor(){super();this.linkProviders=[];this._register(E(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{let t=this.linkProviders.indexOf(e);t!==-1&&this.linkProviders.splice(t,1)}}}};function qt(n,i,e){let t=e.getBoundingClientRect(),r=n.getComputedStyle(e),s=parseInt(r.getPropertyValue("padding-left"),10),o=parseInt(r.getPropertyValue("padding-top"),10);return[i.clientX-t.left-s,i.clientY-t.top-o]}function Qs(n,i,e,t,r,s,o,a,l){if(!s)return;let h=qt(n,i,e);return h[0]=Math.ceil((h[0]+(l?o/2:0))/o),h[1]=Math.ceil(h[1]/a),h[0]=Math.min(Math.max(h[0],1),t+(l?1:0)),h[1]=Math.min(Math.max(h[1],1),r),h}var vt=class{constructor(i,e){this._charSizeService=i;this._renderService=e}getCoords(i,e,t,r,s){return Qs(se(e),i,e,t,r,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,s)}getMouseReportCoords(i,e){let t=qt(se(e),i,e);if(this._charSizeService.hasValidSize)return t[0]=Math.min(Math.max(t[0],0),this._renderService.dimensions.css.canvas.width-1),t[1]=Math.min(Math.max(t[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(t[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(t[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(t[0]),y:Math.floor(t[1])}}};vt=y([m(0,Be),m(1,V)],vt);var en=typeof window=="object"?window:globalThis;function ce(n,i=0){return n[n.length-(1+i)]}function Jn(n,i,e){let t=null,r=null;if(typeof e.value=="function"?(t="value",r=e.value,r.length!==0&&console.warn("Memoize should only be used in functions with zero parameters")):typeof e.get=="function"&&(t="get",r=e.get),!r||!t)throw new Error("not supported");let s=`$memoize$${i}`,o=e;o[t]=function(...a){return this.hasOwnProperty(s)||Object.defineProperty(this,s,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,a)}),this[s]}}var St=class St{constructor(i){this.element=i,this.next=St.Undefined,this.prev=St.Undefined}};St.Undefined=new St(void 0);var re=St,Gi=class{constructor(){this._first=re.Undefined;this._last=re.Undefined}push(i){return this._insert(i,!0)}_insert(i,e){let t=new re(i);if(this._first===re.Undefined)this._first=t,this._last=t;else if(e){let s=this._last;this._last=t,t.prev=s,s.next=t}else{let s=this._first;this._first=t,t.next=s,s.prev=t}let r=!1;return()=>{r||(r=!0,this._remove(t))}}_remove(i){if(i.prev!==re.Undefined&&i.next!==re.Undefined){let e=i.prev;e.next=i.next,i.next.prev=e}else i.prev===re.Undefined&&i.next===re.Undefined?(this._first=re.Undefined,this._last=re.Undefined):i.next===re.Undefined?(this._last=this._last.prev,this._last.next=re.Undefined):i.prev===re.Undefined&&(this._first=this._first.next,this._first.prev=re.Undefined)}*[Symbol.iterator](){let i=this._first;for(;i!==re.Undefined;)yield i.element,i=i.next}},he;(s=>(s.TAP="-xterm-gesturetap",s.CHANGE="-xterm-gesturechange",s.START="-xterm-gesturestart",s.END="-xterm-gesturesend",s.CONTEXT_MENU="-xterm-gesturecontextmenu"))(he||={});var K=class K extends g{constructor(){super();this._dispatched=!1;this._targets=new Gi;this._ignoreTargets=new Gi;this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;let e=en;this._register(C(e.document,"touchstart",t=>this._handleTouchStart(t),{passive:!1})),this._register(C(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(C(e.document,"touchmove",t=>this._handleTouchMove(t),{passive:!1}))}static addTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._targets.push(e);return E(t)}static ignoreTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._ignoreTargets.push(e);return E(t)}static isTouchDevice(){return"ontouchstart"in en||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){let t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let r=0,s=e.targetTouches.length;r=K._holdDelay&&Math.abs(h.initialPageX-ce(h.rollingPageX))<30&&Math.abs(h.initialPageY-ce(h.rollingPageY))<30){let c=this._newGestureEvent(he.CONTEXT_MENU,h.initialTarget);c.pageX=ce(h.rollingPageX),c.pageY=ce(h.rollingPageY),this._dispatchEvent(c)}else if(s===1){let c=ce(h.rollingPageX),u=ce(h.rollingPageY),_=ce(h.rollingTimestamps)-h.rollingTimestamps[0],p=c-h.rollingPageX[0],v=u-h.rollingPageY[0],f=[...this._targets].filter(S=>h.initialTarget instanceof Node&&S.contains(h.initialTarget));this._inertia(e,f,r,Math.abs(p)/_,p>0?1:-1,c,Math.abs(v)/_,v>0?1:-1,u)}this._dispatchEvent(this._newGestureEvent(he.END,h.initialTarget)),delete this._activeTouches[l.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){let r=document.createEvent("CustomEvent");return r.initEvent(e,!1,!0),r.initialTarget=t,r.tapCount=0,r}_dispatchEvent(e){if(e.type===he.TAP){let t=new Date().getTime(),r;t-this._lastSetTapCountTime>K._clearTapCountTime?r=1:r=2,this._lastSetTapCountTime=t,e.tapCount=r}else(e.type===he.CHANGE||e.type===he.CONTEXT_MENU)&&(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(let r of this._ignoreTargets)if(r.contains(e.initialTarget))return;let t=[];for(let r of this._targets)if(r.contains(e.initialTarget)){let s=0,o=e.initialTarget;for(;o&&o!==r;)s++,o=o.parentElement;t.push([s,r])}t.sort((r,s)=>r[0]-s[0]);for(let[,r]of t)r.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,r,s,o,a,l,h,d){this._handle=tt(e,()=>{let c=Date.now(),u=c-r,_=0,p=0,v=!0;s+=K._scrollFriction*u,l+=K._scrollFriction*u,s>0&&(v=!1,_=o*s*u),l>0&&(v=!1,p=h*l*u);let f=this._newGestureEvent(he.CHANGE);f.translationX=_,f.translationY=p,t.forEach(S=>S.dispatchEvent(f)),v||this._inertia(e,t,c,s,o,a+_,l,h,d+p)})}_handleTouchMove(e){let t=Date.now();for(let r=0,s=e.changedTouches.length;r3&&(a.rollingPageX.shift(),a.rollingPageY.shift(),a.rollingTimestamps.shift()),a.rollingPageX.push(o.pageX),a.rollingPageY.push(o.pageY),a.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}};K._scrollFriction=-.005,K._holdDelay=700,K._clearTapCountTime=400,y([Jn],K,"isTouchDevice",1);var Vi=K;var gt=class{constructor(i,e,t,r,s,o,a,l,h){this._renderService=i;this._mouseCoordsService=e;this._mouseStateService=t;this._coreService=r;this._bufferService=s;this._optionsService=o;this._selectionService=a;this._logService=l;this._coreBrowserService=h;this._lastEvent=null;this._wheelPartialScroll=0;this._touchScrollAccumulator=0}bindMouse(i,e,t){let{element:r,document:s}=i,o={mouseup:null,wheel:null,mousedrag:null,mousemove:null},a={target:i,focus:t,requestedEvents:o},l={mouseup:h=>this._handleMouseUp(a,h),wheel:h=>this._handleWheel(a,h),mousedrag:h=>this._handleMouseDrag(a,h),mousemove:h=>this._handleMouseMove(a,h)};this._altMouseCursor=new cs(r,s,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),e(this._altMouseCursor),e(this._mouseStateService.onProtocolChange(h=>{this._handleProtocolChange(a,l,h)})),e(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(r),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,e(E(()=>{o.mouseup&&s.removeEventListener("mouseup",o.mouseup),o.mousedrag&&s.removeEventListener("mousemove",o.mousedrag)})),e(C(r,"mousedown",h=>this._handleMouseDown(a,h))),e(C(r,"wheel",h=>this._handlePassiveWheel(a,h),{passive:!1})),e(Vi.addTarget(i.screenElement)),e(C(i.screenElement,he.START,()=>this._handleTouchStart())),e(C(i.screenElement,he.CHANGE,h=>this._handleTouchChange(a,h)))}_sendEvent(i,e){let t=this._mouseCoordsService.getMouseReportCoords(e,i.target.screenElement);if(!t)return!1;let r,s;switch(e.overrideType||e.type){case"mousemove":s=32,e.buttons===void 0?(r=3,e.button!==void 0&&(r=e.button<3?e.button:3)):r=e.buttons&1?0:e.buttons&4?1:e.buttons&2?2:3;break;case"mouseup":s=0,r=e.button<3?e.button:3;break;case"mousedown":s=1,r=e.button<3?e.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;let a=e.deltaY;if(a===0||this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return!1;s=a<0?0:1,r=4;break;default:return!1}if(s===void 0||r===void 0||r>4||r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!e.altKey)return!1;let o=r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:t.col,row:t.row,x:t.x,y:t.y,button:r,action:s,ctrl:e.ctrlKey,alt:o?!1:e.altKey,shift:e.shiftKey})}_handleMouseUp(i,e){this._sendEvent(i,e),e.buttons||(i.requestedEvents.mouseup&&i.target.document.removeEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.removeEventListener("mousemove",i.requestedEvents.mousedrag))}_handleWheel(i,e){return this._sendEvent(i,e),e.preventDefault(),e.stopPropagation(),!1}_handleMouseDrag(i,e){e.buttons&&this._sendEvent(i,e)}_handleMouseMove(i,e){e.buttons||this._sendEvent(i,e)}_handleMouseDown(i,e){e.preventDefault(),i.focus(),!(!this._mouseStateService.areMouseEventsActive||this._selectionService.shouldForceSelection(e))&&(this._sendEvent(i,e),i.requestedEvents.mouseup&&i.target.document.addEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.addEventListener("mousemove",i.requestedEvents.mousedrag))}_handlePassiveWheel(i,e){if(!i.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;if(!this._bufferService.buffer.hasScrollback){if(e.deltaY===0)return!1;if(this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return e.preventDefault(),e.stopPropagation(),!1;let s="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(e.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(s,!0),e.preventDefault(),e.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(i,e){if(e.preventDefault(),e.stopPropagation(),i.requestedEvents.wheel){this._handleTouchScrollAsWheel(i,e);return}if(!this._bufferService.buffer.hasScrollback){this._handleTouchScrollAsKeys(e);return}i.target.handleTouchScroll?.(e.translationY)}_handleTouchScrollAsKeys(i){let e=this._renderService?.dimensions.css.cell.height;if(!e)return;this._touchScrollAccumulator-=i.translationY;let t=Math.trunc(this._touchScrollAccumulator/e);if(t===0)return;this._touchScrollAccumulator-=t*e;let r="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t<0?"A":"B");for(let s=0;s0?1:-1),this._wheelPartialScroll%=1):i.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(s*=this._bufferService.rows),s}_triggerMouseEvent(i){if(i.col<0||i.col>=this._bufferService.cols||i.row<0||i.row>=this._bufferService.rows||i.button===4&&i.action===32||i.button===3&&i.action!==32||i.button!==4&&(i.action===2||i.action===3)||(i.col++,i.row++,i.action===32&&this._lastEvent&&this._equalEvents(this._lastEvent,i,this._mouseStateService.isPixelEncoding))||!this._mouseStateService.restrictMouseEvent(i))return!1;let e=this._mouseStateService.encodeMouseEvent(i);return e&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(e):this._coreService.triggerDataEvent(e,!0)),this._lastEvent=i,!0}_explainEvents(i){return{down:!!(i&1),up:!!(i&2),drag:!!(i&4),move:!!(i&8),wheel:!!(i&16)}}_equalEvents(i,e,t){if(t){if(i.x!==e.x||i.y!==e.y)return!1}else if(i.col!==e.col||i.row!==e.row)return!1;return!(i.button!==e.button||i.action!==e.action||i.ctrl!==e.ctrl||i.alt!==e.alt||i.shift!==e.shift)}};gt=y([m(0,V),m(1,Pe),m(2,Me),m(3,Y),m(4,D),m(5,R),m(6,Si),m(7,fe),m(8,G)],gt);var cs=class{constructor(i,e,t){this._element=i;this._document=e;this._isActive=t;this._listeners=new P}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;let i=new pe,e=r=>this.syncFromModifier(r);i.add(C(this._document,"keydown",e)),i.add(C(this._document,"keyup",e)),i.add(C(this._element,"mousemove",e));let t=this._element.ownerDocument?.defaultView;t&&i.add(C(t,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=i}resetClass(){this._updateClass(!1)}syncFromModifier(i){this._isActive()&&this._updateClass(i.getModifierState("Alt"))}_updateClass(i){i?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}};var $i=class{constructor(i,e){this._renderCallback=i;this._coreBrowserService=e;this._refreshCallbacks=[]}dispose(){this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)}addRefreshCallback(i){return this._refreshCallbacks.push(i),this._animationFrame??=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()),this._animationFrame}refresh(i,e,t){this._rowCount=t,i=i??0,e=e??this._rowCount-1,this._rowStart=this._rowStart!==void 0?Math.min(this._rowStart,i):i,this._rowEnd=this._rowEnd!==void 0?Math.max(this._rowEnd,e):e,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,this._rowStart===void 0||this._rowEnd===void 0||this._rowCount===void 0){this._runRefreshCallbacks();return}let i=Math.max(this._rowStart,0),e=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(i,e),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(let i of this._refreshCallbacks)i(0);this._refreshCallbacks=[]}};var qi=class{constructor(i){this._tasks=[];this._i=0;this._logService=i}enqueue(i){this._tasks.push(i),this._start()}flush(){for(;this._is){r-e<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-e))}ms`),this._start();return}r=s}this.clear()}},hs=class extends qi{_requestCallback(i){return setTimeout(()=>i(this._createDeadline(16)))}_cancelCallback(i){clearTimeout(i)}_createDeadline(i){let e=performance.now()+i;return{timeRemaining:()=>Math.max(0,e-performance.now())}}},ds=class extends qi{_requestCallback(i){return requestIdleCallback(i)}_cancelCallback(i){cancelIdleCallback(i)}},It="requestIdleCallback"in globalThis?ds:hs,Xi=class{constructor(i){this._queue=new It(i)}set(i){this._queue.clear(),this._queue.enqueue(i)}flush(){this._queue.flush()}dispose(){this._queue.clear()}};var Ct=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._rowCount=e;this._optionsService=r;this._logService=s;this._charSizeService=o;this._coreService=a;this._coreBrowserService=d;this._renderer=this._register(new P);this._observerDisposable=this._register(new P);this._isPaused=!1;this._needsFullRefresh=!1;this._isNextRenderRedrawOnly=!0;this._needsSelectionRefresh=!1;this._canvasWidth=0;this._canvasHeight=0;this._selectionState={start:void 0,end:void 0,columnSelectMode:!1};this._onDimensionsChange=this._register(new b);this.onDimensionsChange=this._onDimensionsChange.event;this._onRenderedViewportChange=this._register(new b);this.onRenderedViewportChange=this._onRenderedViewportChange.event;this._onRender=this._register(new b);this.onRender=this._onRender.event;this._onRefreshRequest=this._register(new b);this.onRefreshRequest=this._onRefreshRequest.event;this._pausedResizeTask=this._register(new Xi(this._logService)),this._renderDebouncer=new $i((u,_)=>this._renderRows(u,_),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new us(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register(E(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(h.onResize(()=>this._fullRefresh())),this._register(h.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(h.cols,h.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(h.buffer.y,h.buffer.y,void 0,!0))),this._register(c.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(u=>this._registerIntersectionObserver(u,t)))}get dimensions(){return this._renderer.value.dimensions}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){let r=new e.IntersectionObserver(s=>this._handleIntersectionChange(s[s.length-1]),{threshold:0});this._observerDisposable.value=E(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=r,r.observe(t)}}_handleIntersectionChange(e){this._isPaused=e.isIntersecting===void 0?e.intersectionRatio===0:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),!this._isPaused&&!this._charSizeService.hasValidSize&&this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,r=!1,s=!1){if(this._isPaused){this._needsFullRefresh=!0;return}if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}let o=this._syncOutputHandler.flush();o&&(e=Math.min(e,o.start),t=Math.max(t,o.end)),s||(this._isNextRenderRedrawOnly=!1),r?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){if(this._renderer.value){if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0}}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(t=>this.refreshRows(t.start,t.end,t.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,r){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=r,this._renderer.value?.handleSelectionChanged(e,t,r)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};Ct=y([m(2,R),m(3,fe),m(4,Be),m(5,Y),m(6,ge),m(7,D),m(8,G),m(9,_e)],Ct);var us=class{constructor(i,e,t){this._coreBrowserService=i;this._coreService=e;this._onTimeout=t;this._start=0;this._end=0;this._isBuffering=!1}bufferRows(i,e){this._isBuffering?(this._start=Math.min(this._start,i),this._end=Math.max(this._end,e)):(this._start=i,this._end=e,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;let i={start:this._start,end:this._end};return this._isBuffering=!1,i}dispose(){this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}};function tn(n,i,e,t){let r=e.buffer.x,s=e.buffer.y;if(!e.buffer.hasScrollback)return ro(r,s,n,i,e,t)+Yi(s,i,e,t)+so(r,s,n,i,e,t);let o;if(s===i)return o=r>n?"D":"C",Yt(Math.abs(r-n),Xt(o,t));o=s>i?"D":"C";let a=Math.abs(s-i),l=io(s>i?n:r,e)+(a-1)*e.cols+1+to(s>i?r:n,e);return Yt(l,Xt(o,t))}function to(n,i){return n-1}function io(n,i){return i.cols-n}function ro(n,i,e,t,r,s){return Yi(i,t,r,s).length===0?"":Yt(sn(n,i,n,i-$e(i,r),!1,r).length,Xt("D",s))}function Yi(n,i,e,t){let r=n-$e(n,e),s=i-$e(i,e),o=Math.abs(r-s)-no(n,i,e);return Yt(o,Xt(rn(n,i),t))}function so(n,i,e,t,r,s){let o;Yi(i,t,r,s).length>0?o=t-$e(t,r):o=i;let a=t,l=oo(n,i,e,t,r,s);return Yt(sn(n,o,e,a,l==="C",r).length,Xt(l,s))}function no(n,i,e){let t=0,r=n-$e(n,e),s=i-$e(i,e);for(let o=0;o=0&&n0?o=t-$e(t,r):o=i,n=e&&oi?"A":"B"}function sn(n,i,e,t,r,s){let o=n,a=i,l="";for(;(o!==e||a!==t)&&a>=0&&as.cols-1?(l+=s.buffer.translateBufferLineToString(a,!1,n,o),o=0,n=0,a++):!r&&o<0&&(l+=s.buffer.translateBufferLineToString(a,!1,0,n+1),o=s.cols-1,n=o,a--);return l+s.buffer.translateBufferLineToString(a,!1,n,o)}function Xt(n,i){let e=i?"O":"[";return"\x1B"+e+n}function Yt(n,i){n=Math.floor(n);let e="";for(let t=0;tthis._bufferService.cols?i%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)-1]:[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[i,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){let i=this.selectionStart[0]+this.selectionStartLength;return i>this._bufferService.cols?[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[Math.max(i,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){let i=this.selectionStart,e=this.selectionEnd;return!i||!e?!1:i[1]>e[1]||i[1]===e[1]&&i[0]>e[0]}handleTrim(i){return this.selectionStart&&(this.selectionStart[1]-=i),this.selectionEnd&&(this.selectionEnd[1]-=i),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):this.selectionStart&&this.selectionStart[1]<0?(this.selectionStart=[0,0],!0):!1}};function fs(n,i){if(n.start.y>n.end.y)throw new Error(`Buffer range end (${n.end.x}, ${n.end.y}) cannot be before start (${n.start.x}, ${n.start.y})`);return i*(n.end.y-n.start.y)+(n.end.x-n.start.x+1)}var ao="\xA0",lo=new RegExp(ao,"g");var Et=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._element=e;this._screenElement=t;this._linkifier=r;this._bufferService=s;this._coreService=o;this._mouseCoordsService=a;this._optionsService=l;this._mouseStateService=h;this._renderService=d;this._coreBrowserService=c;this._dragScrollAmount=0;this._enabled=!0;this._trimListener=this._register(new P);this._workCell=new F;this._mouseDownTimeStamp=0;this._oldHasSelection=!1;this._oldSelectionStart=void 0;this._oldSelectionEnd=void 0;this._onLinuxMouseSelection=this._register(new b);this.onLinuxMouseSelection=this._onLinuxMouseSelection.event;this._onRedrawRequest=this._register(new b);this.onRequestRedraw=this._onRedrawRequest.event;this._onSelectionChange=this._register(new b);this.onSelectionChange=this._onSelectionChange.event;this._onRequestScrollLines=this._register(new b);this.onRequestScrollLines=this._onRequestScrollLines.event;this._mouseMoveListener=u=>this._handleMouseMove(u),this._mouseUpListener=u=>this._handleMouseUp(u),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(u=>this._handleTrim(u)),this._register(this._bufferService.buffers.onBufferActivate(u=>this._handleBufferActivate(u))),this.enable(),this._model=new ji(this._bufferService),this._activeSelectionMode=0,this._register(E(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(u=>{u.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!e||!t?!1:e[0]!==t[0]||e[1]!==t[1]}get selectionText(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";let r=this._bufferService.buffer,s=[];if(this._activeSelectionMode===3){if(e[0]===t[0])return"";let a=e[0]a.replace(lo," ")).join(Ue?`\r +WARNING: This link could potentially be dangerous`)){let t=window.open();if(t){try{t.opener=null}catch{}t.location.href=i}else console.warn("Opening link blocked as opener could not be cleared")}}var Be=H("CharSizeService"),G=H("CoreBrowserService"),Oe=H("MouseCoordsService"),Ks=H("MouseService"),V=H("RenderService"),Si=H("SelectionService"),gi=H("CharacterJoinerService"),_e=H("ThemeService"),Ci=H("LinkProviderService"),zs=H("KeyboardService");function E(n){return{dispose:n}}function Ne(n){if(!n)return n;if(Array.isArray(n)){for(let i of n)i.dispose();return[]}return n.dispose(),n}var pe=class{constructor(){this._disposables=new Set;this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(i){return this._isDisposed?i.dispose():this._disposables.add(i),i}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(let i of this._disposables)i.dispose();this._disposables.clear()}}clear(){for(let i of this._disposables)i.dispose();this._disposables.clear()}},g=class{constructor(){this._store=new pe}dispose(){this._store.dispose()}_register(i){return this._store.add(i)}};g.None=Object.freeze({dispose(){}});var B=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(i){this._isDisposed||i===this._value||(this._value?.dispose(),this._value=i)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}};function Gs(n,i=0,e){let t=setTimeout(()=>{n(),e&&r.dispose()},i),r=E(()=>{clearTimeout(t)});return e?.add(r),r}var Ce=class{constructor(){this._token=-1;this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._token!==-1&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(i,e){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,i()},e)}setIfNotSet(i,e){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");this._token===-1&&(this._token=setTimeout(()=>{this._token=-1,i()},e))}},Ii=class{constructor(){this._isScheduled=!1;this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(i){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,i())}))}},Ei=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(i,e,t=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();let r=t.setInterval(()=>{i()},e);this._disposable={dispose:()=>{t.clearInterval(r),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}};function se(n){let i=n;if(i?.ownerDocument?.defaultView)return i.ownerDocument.defaultView;let e=n;return e?.view?e.view:window}var Gr=class{constructor(i,e,t,r){this._node=i,this._type=e,this._handler=t,this._options=r,i.addEventListener(e,t,r)}dispose(){!this._node||!this._handler||(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}};function I(n,i,e,t){return new Gr(n,i,e,t)}function Vr(n,i,e,t){return I(n,i,e,t)}var le={CLICK:"click",MOUSE_DOWN:"mousedown",MOUSE_OVER:"mouseover",MOUSE_LEAVE:"mouseleave",KEY_DOWN:"keydown",KEY_UP:"keyup",INPUT:"input",BLUR:"blur",FOCUS:"focus",CHANGE:"change",POINTER_DOWN:"pointerdown",POINTER_MOVE:"pointermove",POINTER_UP:"pointerup",MOUSE_WHEEL:"wheel",WHEEL:"wheel"};function $s(n){let i=n.getBoundingClientRect(),e=se(n);return{left:i.left+e.scrollX,top:i.top+e.scrollY,width:i.width,height:i.height}}var yi=class{constructor(i,e){this._runner=i;this.priority=e;this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(i){console.error(i)}}static sort(i,e){return e.priority-i.priority}},Vs=new Map;function qs(n){let i=Vs.get(n);return i||(i={next:[],current:[],animFrameRequested:!1,inAnimationFrameRunner:!1},Vs.set(n,i)),i}function Un(n){let i=qs(n);for(i.animFrameRequested=!1,i.current=i.next,i.next=[],i.inAnimationFrameRunner=!0;i.current.length>0;)i.current.sort(yi.sort),i.current.shift().execute();i.inAnimationFrameRunner=!1}function it(n,i,e=0){let t=qs(n),r=new yi(i,e);return t.next.push(r),t.animFrameRequested||(t.animFrameRequested=!0,n.requestAnimationFrame(()=>Un(n))),r}var xi=class extends Ei{constructor(i){super(),this._defaultTarget=i?se(i):void 0}cancelAndSet(i,e,t){super.cancelAndSet(i,e,t??this._defaultTarget??window)}};var Te=class{constructor(i){this.domNode=i;this._width="";this._height="";this._top="";this._left="";this._bottom="";this._right="";this._className="";this._position="";this._layerHint=!1;this._contain="none"}setWidth(i){let e=st(i);this._width!==e&&(this._width=e,this.domNode.style.width=this._width)}setHeight(i){let e=st(i);this._height!==e&&(this._height=e,this.domNode.style.height=this._height)}setTop(i){let e=st(i);this._top!==e&&(this._top=e,this.domNode.style.top=this._top)}setLeft(i){let e=st(i);this._left!==e&&(this._left=e,this.domNode.style.left=this._left)}setBottom(i){let e=st(i);this._bottom!==e&&(this._bottom=e,this.domNode.style.bottom=this._bottom)}setRight(i){let e=st(i);this._right!==e&&(this._right=e,this.domNode.style.right=this._right)}setClassName(i){this._className!==i&&(this._className=i,this.domNode.className=this._className)}toggleClassName(i,e){this.domNode.classList.toggle(i,e),this._className=this.domNode.className}setPosition(i){this._position!==i&&(this._position=i,this.domNode.style.position=this._position)}setLayerHinting(i){this._layerHint!==i&&(this._layerHint=i,i?this.domNode.style.transform="translate3d(0px, 0px, 0px)":this.domNode.style.transform="")}setContain(i){this._contain!==i&&(this._contain=i,this.domNode.style.contain=this._contain)}setAttribute(i,e){this.domNode.setAttribute(i,e)}};function st(n){return typeof n=="number"?`${n}px`:n}var ze={};Mn(ze,{getSafariVersion:()=>zn,getZoomFactor:()=>Xr,isChrome:()=>Kt,isChromeOS:()=>Yr,isFirefox:()=>ot,isLegacyEdge:()=>Kn,isLinux:()=>zt,isMac:()=>ie,isNode:()=>$r,isSafari:()=>wi,isWindows:()=>Ke});var $r=!!(typeof process<"u"&&"title"in process&&(typeof navigator>"u"||navigator.userAgent.startsWith("Node.js/"))),nt=$r?"node":navigator.userAgent,qr=$r?"node":navigator.platform,ot=nt.includes("Firefox"),Kt=nt.includes("Chrome"),Kn=nt.includes("Edge"),wi=/^((?!chrome|android).)*safari/i.test(nt);function Xr(n){return 1}function zn(){if(!wi)return 0;let n=nt.match(/Version\/(\d+)/);return n===null||n.length<2?0:parseInt(n[1],10)}var ie=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(qr),Ke=["Windows","Win16","Win32","WinCE"].includes(qr),zt=qr.indexOf("Linux")>=0,Yr=/\bCrOS\b/.test(nt);var Xs=new WeakMap;function Gn(n){if(!n.parent||n.parent===n)return null;try{let i=n.location,e=n.parent.location;if(i.origin!=="null"&&e.origin!=="null"&&i.origin!==e.origin)return null}catch{return null}return n.parent}var jr=class{static _getSameOriginWindowChain(i){let e=Xs.get(i);if(!e){e=[],Xs.set(i,e);let t=i,r;do r=Gn(t),r?e.push({window:new WeakRef(t),iframeElement:t.frameElement??null}):e.push({window:new WeakRef(t),iframeElement:null}),t=r;while(t)}return e.slice(0)}static getPositionOfChildWindowRelativeToAncestorWindow(i,e){if(!e||i===e)return{top:0,left:0};let t=0,r=0,s=this._getSameOriginWindowChain(i);for(let o of s){let a=o.window.deref();if(t+=a?.scrollY??0,r+=a?.scrollX??0,a===e||!o.iframeElement)break;let l=o.iframeElement.getBoundingClientRect();t+=l.top,r+=l.left}return{top:t,left:r}}},at=class{constructor(i,e){this.timestamp=Date.now(),this.browserEvent=e,this.leftButton=e.button===0,this.middleButton=e.button===1,this.rightButton=e.button===2,this.buttons=e.buttons,this.target=e.target,this.detail=e.detail??1,e.type==="dblclick"&&(this.detail=2),this.ctrlKey=e.ctrlKey,this.shiftKey=e.shiftKey,this.altKey=e.altKey,this.metaKey=e.metaKey,typeof e.pageX=="number"?(this.posx=e.pageX,this.posy=e.pageY):(this.posx=e.clientX+this.target.ownerDocument.body.scrollLeft+this.target.ownerDocument.documentElement.scrollLeft,this.posy=e.clientY+this.target.ownerDocument.body.scrollTop+this.target.ownerDocument.documentElement.scrollTop);let t=jr.getPositionOfChildWindowRelativeToAncestorWindow(i,e.view);this.posx-=t.left,this.posy-=t.top}preventDefault(){this.browserEvent.preventDefault()}stopPropagation(){this.browserEvent.stopPropagation()}},Gt=class{constructor(i,e=0,t=0){this.browserEvent=i??null,this.target=i?i.target??i.targetNode??i.srcElement??null:null,this.deltaY=t,this.deltaX=e;let r=!1;if(Kt){let s=navigator.userAgent.match(/Chrome\/(\d+)/);r=(s?parseInt(s[1],10):123)<=122}if(i){let s=i,o=i,a=i.view?.devicePixelRatio??1;if(typeof s.wheelDeltaY<"u")r?this.deltaY=s.wheelDeltaY/(120*a):this.deltaY=s.wheelDeltaY/120;else if(typeof o.VERTICAL_AXIS<"u"&&o.axis===o.VERTICAL_AXIS)this.deltaY=-o.detail/3;else if(i.type==="wheel"){let l=i;l.deltaMode===l.DOM_DELTA_LINE?ot&&!ie?this.deltaY=-i.deltaY/3:this.deltaY=-i.deltaY:this.deltaY=-i.deltaY/40}if(typeof s.wheelDeltaX<"u")wi&&Ke?this.deltaX=-(s.wheelDeltaX/120):r?this.deltaX=s.wheelDeltaX/(120*a):this.deltaX=s.wheelDeltaX/120;else if(typeof o.HORIZONTAL_AXIS<"u"&&o.axis===o.HORIZONTAL_AXIS)this.deltaX=-i.detail/3;else if(i.type==="wheel"){let l=i;l.deltaMode===l.DOM_DELTA_LINE?ot&&!ie?this.deltaX=-i.deltaX/3:this.deltaX=-i.deltaX:this.deltaX=-i.deltaX/40}this.deltaY===0&&this.deltaX===0&&i.wheelDelta&&(r?this.deltaY=i.wheelDelta/(120*a):this.deltaY=i.wheelDelta/120)}}preventDefault(){this.browserEvent?.preventDefault()}stopPropagation(){this.browserEvent?.stopPropagation()}};var lt=class{constructor(){this._hooks=new pe;this._pointerMoveCallback=null;this._onStopCallback=null}dispose(){this.stopMonitoring(!1),this._hooks.dispose()}stopMonitoring(i){if(!this.isMonitoring())return;this._hooks.clear(),this._pointerMoveCallback=null;let e=this._onStopCallback;this._onStopCallback=null,i&&e&&e()}isMonitoring(){return!!this._pointerMoveCallback}startMonitoring(i,e,t,r,s){this.isMonitoring()&&this.stopMonitoring(!1),this._pointerMoveCallback=r,this._onStopCallback=s;let o=i;try{i.setPointerCapture(e),this._hooks.add(E(()=>{try{i.releasePointerCapture(e)}catch{}}))}catch{o=se(i)}this._hooks.add(I(o,le.POINTER_MOVE,a=>{if(a.buttons!==t){this.stopMonitoring(!0);return}a.preventDefault(),this._pointerMoveCallback(a)})),this._hooks.add(I(o,le.POINTER_UP,a=>this.stopMonitoring(!0)))}};var Fe=class extends g{_onclick(i,e){this._register(I(i,le.CLICK,t=>e(new at(se(i),t))))}_onmouseover(i,e){this._register(I(i,le.MOUSE_OVER,t=>e(new at(se(i),t))))}_onmouseleave(i,e){this._register(I(i,le.MOUSE_LEAVE,t=>e(new at(se(i),t))))}};var Ti=class extends Fe{constructor(i){super(),this._handleActivate=i.handleActivate,this.bgDomNode=document.createElement("div"),this.bgDomNode.className="xterm-arrow-background",this.bgDomNode.style.position="absolute",this.bgDomNode.style.width=i.bgWidth+"px",this.bgDomNode.style.height=i.bgHeight+"px",typeof i.top<"u"&&(this.bgDomNode.style.top="0px"),typeof i.left<"u"&&(this.bgDomNode.style.left="0px"),typeof i.bottom<"u"&&(this.bgDomNode.style.bottom="0px"),typeof i.right<"u"&&(this.bgDomNode.style.right="0px"),this.domNode=document.createElement("div"),this.domNode.className=i.className,this.domNode.style.position="absolute";let e=Math.min(i.bgWidth,i.bgHeight);this.domNode.style.width=e+"px",this.domNode.style.height=e+"px",typeof i.top<"u"&&(this.domNode.style.top=i.top+"px"),typeof i.left<"u"&&(this.domNode.style.left=i.left+"px"),typeof i.bottom<"u"&&(this.domNode.style.bottom=i.bottom+"px"),typeof i.right<"u"&&(this.domNode.style.right=i.right+"px"),this._pointerMoveMonitor=this._register(new lt),this._register(Vr(this.bgDomNode,le.POINTER_DOWN,t=>this._arrowPointerDown(t))),this._register(Vr(this.domNode,le.POINTER_DOWN,t=>this._arrowPointerDown(t))),this._pointerdownRepeatTimer=this._register(new xi),this._pointerdownScheduleRepeatTimer=this._register(new Ce)}_arrowPointerDown(i){if(!i.target||!(i.target instanceof Element))return;let e=()=>{this._pointerdownRepeatTimer.cancelAndSet(()=>this._handleActivate(),1e3/24,se(i))};this._handleActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet(e,200),this._pointerMoveMonitor.startMonitoring(i.target,i.pointerId,i.buttons,t=>{},()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()}),i.preventDefault()}};var b=class{constructor(){this._listeners=[];this._disposed=!1}get event(){return this._event?this._event:(this._event=(i,e,t)=>{if(this._disposed)return E(()=>{});let r={fn:i,thisArgs:e};this._listeners.push(r);let s=E(()=>{let o=this._listeners.indexOf(r);o!==-1&&this._listeners.splice(o,1)});return t&&(Array.isArray(t)?t.push(s):t.add(s)),s},this._event)}fire(i){if(!this._disposed)switch(this._listeners.length){case 0:return;case 1:{let{fn:e,thisArgs:t}=this._listeners[0];e.call(t,i);return}default:{let e=this._listeners.slice();for(let{fn:t,thisArgs:r}of e)t.call(r,i)}}}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},j;(r=>{function n(s,o){return s(a=>o.fire(a))}r.forward=n;function i(s,o){return(a,l,h)=>s(d=>a.call(l,o(d)),void 0,h)}r.map=i;function e(...s){return(o,a,l)=>{let h=new pe;for(let d of s)h.add(d(c=>o.call(a,c)));return l&&(Array.isArray(l)?l.push(h):l.add(h)),h}}r.any=e;function t(s,o,a){return o(a),s(l=>o(l))}r.runAndSubscribe=t})(j||={});var Jr=class n{constructor(i,e,t,r,s,o,a){this._forceIntegerValues=i;this._scrollStateBrand=void 0;this._forceIntegerValues&&(e=e|0,t=t|0,r=r|0,s=s|0,o=o|0,a=a|0),this.rawScrollLeft=r,this.rawScrollTop=a,e<0&&(e=0),r+e>t&&(r=t-e),r<0&&(r=0),s<0&&(s=0),a+s>o&&(a=o-s),a<0&&(a=0),this.width=e,this.scrollWidth=t,this.scrollLeft=r,this.height=s,this.scrollHeight=o,this.scrollTop=a}equals(i){return this.rawScrollLeft===i.rawScrollLeft&&this.rawScrollTop===i.rawScrollTop&&this.width===i.width&&this.scrollWidth===i.scrollWidth&&this.scrollLeft===i.scrollLeft&&this.height===i.height&&this.scrollHeight===i.scrollHeight&&this.scrollTop===i.scrollTop}withScrollDimensions(i,e){return new n(this._forceIntegerValues,typeof i.width<"u"?i.width:this.width,typeof i.scrollWidth<"u"?i.scrollWidth:this.scrollWidth,e?this.rawScrollLeft:this.scrollLeft,typeof i.height<"u"?i.height:this.height,typeof i.scrollHeight<"u"?i.scrollHeight:this.scrollHeight,e?this.rawScrollTop:this.scrollTop)}withScrollPosition(i){return new n(this._forceIntegerValues,this.width,this.scrollWidth,typeof i.scrollLeft<"u"?i.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,typeof i.scrollTop<"u"?i.scrollTop:this.rawScrollTop)}createScrollEvent(i,e){let t=this.width!==i.width,r=this.scrollWidth!==i.scrollWidth,s=this.scrollLeft!==i.scrollLeft,o=this.height!==i.height,a=this.scrollHeight!==i.scrollHeight,l=this.scrollTop!==i.scrollTop;return{inSmoothScrolling:e,oldWidth:i.width,oldScrollWidth:i.scrollWidth,oldScrollLeft:i.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:i.height,oldScrollHeight:i.scrollHeight,oldScrollTop:i.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:t,scrollWidthChanged:r,scrollLeftChanged:s,heightChanged:o,scrollHeightChanged:a,scrollTopChanged:l}}},ct=class extends g{constructor(e){super();this._scrollableBrand=void 0;this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new Jr(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){let r=this._state.withScrollDimensions(e,t);this._setState(r,!!this._smoothScrolling),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){let t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(this._smoothScrollDuration===0){this.setScrollPositionNow(e);return}if(this._smoothScrolling){e={scrollLeft:typeof e.scrollLeft>"u"?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:typeof e.scrollTop>"u"?this._smoothScrolling.to.scrollTop:e.scrollTop};let r=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===r.scrollLeft&&this._smoothScrolling.to.scrollTop===r.scrollTop)return;let s;t?s=new Vt(this._smoothScrolling.from,r,this._smoothScrolling.startTime,this._smoothScrolling.duration):s=Vt.start(this._state,r,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{let r=this._state.withScrollPosition(e);this._smoothScrolling=Vt.start(this._state,r,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}hasPendingScrollAnimation(){return!!this._smoothScrolling}_performSmoothScrolling(){if(!this._smoothScrolling)return;let e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);if(this._setState(t,!0),!!this._smoothScrolling){if(e.isDone){this._smoothScrolling.dispose(),this._smoothScrolling=null;return}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame(()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())})}}_setState(e,t){let r=this._state;r.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(r,t)))}},Di=class{constructor(i,e,t){this.scrollLeft=i,this.scrollTop=e,this.isDone=t}};function Zr(n,i){let e=i-n;return function(t){return n+e*qn(t)}}function Vn(n,i,e){return function(t){return t2.5*t){let s,o;return i{this._domNode?.setClassName(this._visibleClassName)},0))}_hide(i){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(i?" xterm-fade":"")))}};var Xn=140,ht=class extends Fe{constructor(i){super(),this._lazyRender=i.lazyRender,this._host=i.host,this._scrollable=i.scrollable,this._scrollByPage=i.scrollByPage,this._scrollbarState=i.scrollbarState,this._visibilityController=this._register(new Ri(i.visibility,"xterm-visible xterm-scrollbar "+i.extraScrollbarClassName,"xterm-invisible xterm-scrollbar "+i.extraScrollbarClassName)),this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._pointerMoveMonitor=this._register(new lt),this._shouldRender=!0,this.domNode=new Te(document.createElement("div")),this.domNode.setAttribute("role","presentation"),this.domNode.setAttribute("aria-hidden","true"),this._visibilityController.setDomNode(this.domNode),this.domNode.setPosition("absolute"),this._register(I(this.domNode.domNode,le.POINTER_DOWN,e=>this._domNodePointerDown(e)))}_createArrow(i){let e=this._register(new Ti(i));return this.domNode.domNode.appendChild(e.bgDomNode),this.domNode.domNode.appendChild(e.domNode),e}_createSlider(i,e,t,r){this.slider=new Te(document.createElement("div")),this.slider.setClassName("xterm-slider"),this.slider.setPosition("absolute"),this.slider.setTop(i),this.slider.setLeft(e),typeof t=="number"&&this.slider.setWidth(t),typeof r=="number"&&this.slider.setHeight(r),this.slider.setLayerHinting(!0),this.slider.setContain("strict"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(I(this.slider.domNode,le.POINTER_DOWN,s=>{s.button===0&&(s.preventDefault(),this._sliderPointerDown(s))})),this._onclick(this.slider.domNode,s=>{s.leftButton&&s.stopPropagation()})}_handleElementSize(i){return this._scrollbarState.setVisibleSize(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollSize(i){return this._scrollbarState.setScrollSize(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_handleElementScrollPosition(i){return this._scrollbarState.setScrollPosition(i)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(i){i.target===this.domNode.domNode&&this._handlePointerDown(i)}delegatePointerDown(i){let e=this.domNode.domNode.getClientRects()[0].top,t=e+this._scrollbarState.getSliderPosition(),r=e+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),s=this._sliderPointerPosition(i);t<=s&&s<=r?i.button===0&&(i.preventDefault(),this._sliderPointerDown(i)):this._handlePointerDown(i)}_handlePointerDown(i){let e,t;if(i.target===this.domNode.domNode&&typeof i.offsetX=="number"&&typeof i.offsetY=="number")e=i.offsetX,t=i.offsetY;else{let s=$s(this.domNode.domNode);e=i.pageX-s.left,t=i.pageY-s.top}let r=this._pointerDownRelativePosition(e,t);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(r):this._scrollbarState.getDesiredScrollPositionFromOffset(r)),i.button===0&&(i.preventDefault(),this._sliderPointerDown(i))}_sliderPointerDown(i){if(!i.target||!(i.target instanceof Element))return;let e=this._sliderPointerPosition(i),t=this._sliderOrthogonalPointerPosition(i),r=this._scrollbarState.clone();this.slider.toggleClassName("xterm-active",!0),this._pointerMoveMonitor.startMonitoring(i.target,i.pointerId,i.buttons,s=>{let o=this._sliderOrthogonalPointerPosition(s),a=Math.abs(o-t);if(Ke&&a>Xn){this._setDesiredScrollPositionNow(r.getScrollPosition());return}let h=this._sliderPointerPosition(s)-e;this._setDesiredScrollPositionNow(r.getDesiredScrollPositionFromDelta(h))},()=>{this.slider.toggleClassName("xterm-active",!1),this._host.handleDragEnd()}),this._host.handleDragStart()}_setDesiredScrollPositionNow(i){let e={};this.writeScrollPosition(e,i),this._scrollable.setScrollPositionNow(e)}updateScrollbarSize(i){this._updateScrollbarSize(i),this._scrollbarState.setScrollbarSize(i),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}};var dt=class n{constructor(i,e,t,r,s,o){this._scrollbarSize=Math.round(e),this._oppositeScrollbarSize=Math.round(t),this._arrowSize=Math.round(i),this._visibleSize=r,this._scrollSize=s,this._scrollPosition=o,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new n(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(i){let e=Math.round(i);return this._visibleSize!==e?(this._visibleSize=e,this._refreshComputedValues(),!0):!1}setScrollSize(i){let e=Math.round(i);return this._scrollSize!==e?(this._scrollSize=e,this._refreshComputedValues(),!0):!1}setScrollPosition(i){let e=Math.round(i);return this._scrollPosition!==e?(this._scrollPosition=e,this._refreshComputedValues(),!0):!1}setScrollbarSize(i){this._scrollbarSize=Math.round(i)}setArrowSize(i){let e=Math.round(i);this._arrowSize!==e&&(this._arrowSize=e,this._refreshComputedValues())}setOppositeScrollbarSize(i){this._oppositeScrollbarSize=Math.round(i)}static _computeValues(i,e,t,r,s){let o=Math.max(0,t-i),a=Math.max(0,o-2*e),l=r>0&&r>t;if(!l)return{computedAvailableSize:Math.round(o),computedIsNeeded:l,computedSliderSize:Math.round(a),computedSliderRatio:0,computedSliderPosition:0};let h=Math.round(Math.max(20,Math.floor(t*a/r))),d=(a-h)/(r-t),c=s*d;return{computedAvailableSize:Math.round(o),computedIsNeeded:l,computedSliderSize:Math.round(h),computedSliderRatio:d,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){let i=n._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=i.computedAvailableSize,this._computedIsNeeded=i.computedIsNeeded,this._computedSliderSize=i.computedSliderSize,this._computedSliderRatio=i.computedSliderRatio,this._computedSliderPosition=i.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(i){if(!this._computedIsNeeded)return 0;let e=i-this._arrowSize-this._computedSliderSize/2;return Math.round(e/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(i){if(!this._computedIsNeeded)return 0;let e=i-this._arrowSize,t=this._scrollPosition;return ethis._arrowScroll(-this._arrowScrollDelta)}),this._arrowDown=this._createArrow({className:"xterm-scra xterm-arrow-down",bottom:0,left:0,bgWidth:t,bgHeight:t,handleActivate:()=>this._arrowScroll(this._arrowScrollDelta)})),this._updateArrowSize(this._arrowUp,t),this._updateArrowSize(this._arrowDown,t),!this._arrowUp||!this._arrowDown)return;let r=e?"":"none";this._arrowUp.bgDomNode.style.display=r,this._arrowUp.domNode.style.display=r,this._arrowDown.bgDomNode.style.display=r,this._arrowDown.domNode.style.display=r}_updateArrowSize(e,t){e&&(e.bgDomNode.style.width=`${t}px`,e.bgDomNode.style.height=`${t}px`,e.domNode.style.width=`${t}px`,e.domNode.style.height=`${t}px`)}updateOptions(e){let t=e.verticalHasArrows?e.verticalScrollbarSize:0;this._scrollbarState.setArrowSize(t),this._setArrows(e.verticalHasArrows,e.verticalScrollbarSize),this.updateScrollbarSize(e.vertical===2?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}};var Qr=class{constructor(i,e,t){this.timestamp=i,this.deltaX=e,this.deltaY=t,this.score=0}},Mi=class Mi{constructor(){this._capacity=5,this._memory=[],this._front=-1,this._rear=-1}isPhysicalMouseWheel(){if(this._front===-1&&this._rear===-1)return!1;let i=1,e=0,t=1,r=this._rear;for(;r!==-1;){let s=r===this._front?i:Math.pow(2,-t);if(i-=s,e+=this._memory[r].score*s,r===this._front)break;r=(this._capacity+r-1)%this._capacity,t++}return e<=.5}acceptStandardWheelEvent(i){if(Kt){let e=se(i.browserEvent),t=Xr(e);this.accept(Date.now(),i.deltaX*t,i.deltaY*t)}else this.accept(Date.now(),i.deltaX,i.deltaY)}accept(i,e,t){let r=null,s=new Qr(i,e,t);this._front===-1&&this._rear===-1?(this._memory[0]=s,this._front=0,this._rear=0):(r=this._memory[this._rear],this._rear=(this._rear+1)%this._capacity,this._rear===this._front&&(this._front=(this._front+1)%this._capacity),this._memory[this._rear]=s),s.score=this._computeScore(s,r)}_computeScore(i,e){if(Math.abs(i.deltaX)>0&&Math.abs(i.deltaY)>0)return 1;let t=.5;if((!this._isAlmostInt(i.deltaX)||!this._isAlmostInt(i.deltaY))&&(t+=.25),e){let r=Math.abs(i.deltaX),s=Math.abs(i.deltaY),o=Math.abs(e.deltaX),a=Math.abs(e.deltaY),l=Math.max(Math.min(r,o),1),h=Math.max(Math.min(s,a),1),d=Math.max(r,o),c=Math.max(s,a);d%l===0&&c%h===0&&(t-=.5)}return Math.min(Math.max(t,0),1)}_isAlmostInt(i){return Math.abs(Math.round(i)-i)<.01}};Mi.INSTANCE=new Mi;var es=Mi,Pi=class extends Fe{constructor(e,t,r){super();this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;t=t??{};let s,o=!r;r?s=r:(t.mouseWheelSmoothScroll=!1,s=new ct({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:l=>it(se(e),l)})),this._options=Yn(t),this._scrollable=s,this._register(this._scrollable.onScroll(l=>{this._handleScroll(l),this._onScroll.fire(l)})),o&&this._register(this._scrollable);let a={handleMouseWheel:l=>this._handleMouseWheel(l),handleDragStart:()=>this._handleDragStart(),handleDragEnd:()=>this._handleDragEnd()};this._verticalScrollbar=this._register(new ki(this._scrollable,this._options,a)),this._horizontalScrollbar=this._register(new Ai(this._scrollable,this._options,a)),this._domNode=document.createElement("div"),this._domNode.className="xterm-scrollable-element "+this._options.className,this._domNode.setAttribute("role","presentation"),this._domNode.style.position="relative",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=new Te(document.createElement("div")),this._leftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=new Te(document.createElement("div")),this._topShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=new Te(document.createElement("div")),this._topLeftShadowDomNode.setClassName("xterm-shadow"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode??this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this._onmouseover(this._listenOnDomNode,l=>this._handleMouseOver(l)),this._onmouseleave(this._listenOnDomNode,l=>this._handleMouseLeave(l)),this._hideTimeout=this._register(new Ce),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}get options(){return this._options}dispose(){this._mouseWheelToDispose=Ne(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}updateClassName(e){this._options.className=e,ie&&(this._options.className+=" xterm-mac"),this._domNode.className="xterm-scrollable-element "+this._options.className}updateOptions(e){typeof e.handleMouseWheel<"u"&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),typeof e.mouseWheelScrollSensitivity<"u"&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),typeof e.fastScrollSensitivity<"u"&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),typeof e.scrollPredominantAxis<"u"&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),typeof e.horizontal<"u"&&(this._options.horizontal=e.horizontal),typeof e.vertical<"u"&&(this._options.vertical=e.vertical),typeof e.horizontalHasArrows<"u"&&(this._options.horizontalHasArrows=e.horizontalHasArrows),typeof e.verticalHasArrows<"u"&&(this._options.verticalHasArrows=e.verticalHasArrows),typeof e.horizontalScrollbarSize<"u"&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),typeof e.verticalScrollbarSize<"u"&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),typeof e.scrollByPage<"u"&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}delegateScrollFromMouseWheelEvent(e){this._handleMouseWheel(new Gt(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=Ne(this._mouseWheelToDispose),e)){let r=s=>{this._handleMouseWheel(new Gt(s))};this._mouseWheelToDispose.push(I(this._listenOnDomNode,le.MOUSE_WHEEL,r,{passive:!1}))}}_handleMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;let t=es.INSTANCE;t.acceptStandardWheelEvent(e);let r=!1;if(e.deltaY||e.deltaX){let o=e.deltaY*this._options.mouseWheelScrollSensitivity,a=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&a+o===0?a=o=0:Math.abs(o)>=Math.abs(a)?a=0:o=0),this._options.flipAxes&&([o,a]=[a,o]);let l=!ie&&e.browserEvent&&e.browserEvent.shiftKey;(this._options.scrollYToX||l)&&!a&&(a=o,o=0),e.browserEvent&&e.browserEvent.altKey&&(a=a*this._options.fastScrollSensitivity,o=o*this._options.fastScrollSensitivity);let h=this._scrollable.getFutureScrollPosition(),d={};if(o){let c=50*o,u=h.scrollTop-(c<0?Math.floor(c):Math.ceil(c));this._verticalScrollbar.writeScrollPosition(d,u)}if(a){let c=50*a,u=h.scrollLeft-(c<0?Math.floor(c):Math.ceil(c));this._horizontalScrollbar.writeScrollPosition(d,u)}d=this._scrollable.validateScrollPosition(d),(h.scrollLeft!==d.scrollLeft||h.scrollTop!==d.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(d):this._scrollable.setScrollPositionNow(d),r=!0)}let s=r;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_handleScroll(e){this._shouldRender=this._horizontalScrollbar.handleScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.handleScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error("Please use `lazyRender` together with `renderNow`!");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){let e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,r=e.scrollLeft>0,s=r?" xterm-shadow-left":"",o=t?" xterm-shadow-top":"",a=r||t?" xterm-shadow-top-left-corner":"";this._leftShadowDomNode.setClassName(`xterm-shadow${s}`),this._topShadowDomNode.setClassName(`xterm-shadow${o}`),this._topLeftShadowDomNode.setClassName(`xterm-shadow${a}${o}${s}`)}}_handleDragStart(){this._isDragging=!0,this._reveal()}_handleDragEnd(){this._isDragging=!1,this._hide()}_handleMouseLeave(e){this._mouseIsOver=!1,this._hide()}_handleMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){!this._mouseIsOver&&!this._isDragging&&(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){!this._mouseIsOver&&!this._isDragging&&this._hideTimeout.cancelAndSet(()=>this._hide(),500)}};function Yn(n){let i={lazyRender:typeof n.lazyRender<"u"?n.lazyRender:!1,className:typeof n.className<"u"?n.className:"",useShadows:typeof n.useShadows<"u"?n.useShadows:!0,handleMouseWheel:typeof n.handleMouseWheel<"u"?n.handleMouseWheel:!0,flipAxes:typeof n.flipAxes<"u"?n.flipAxes:!1,consumeMouseWheelIfScrollbarIsNeeded:typeof n.consumeMouseWheelIfScrollbarIsNeeded<"u"?n.consumeMouseWheelIfScrollbarIsNeeded:!1,alwaysConsumeMouseWheel:typeof n.alwaysConsumeMouseWheel<"u"?n.alwaysConsumeMouseWheel:!1,scrollYToX:typeof n.scrollYToX<"u"?n.scrollYToX:!1,mouseWheelScrollSensitivity:typeof n.mouseWheelScrollSensitivity<"u"?n.mouseWheelScrollSensitivity:1,fastScrollSensitivity:typeof n.fastScrollSensitivity<"u"?n.fastScrollSensitivity:5,scrollPredominantAxis:typeof n.scrollPredominantAxis<"u"?n.scrollPredominantAxis:!0,mouseWheelSmoothScroll:typeof n.mouseWheelSmoothScroll<"u"?n.mouseWheelSmoothScroll:!0,listenOnDomNode:typeof n.listenOnDomNode<"u"?n.listenOnDomNode:null,horizontal:typeof n.horizontal<"u"?n.horizontal:1,horizontalScrollbarSize:typeof n.horizontalScrollbarSize<"u"?n.horizontalScrollbarSize:10,horizontalSliderSize:typeof n.horizontalSliderSize<"u"?n.horizontalSliderSize:0,horizontalHasArrows:typeof n.horizontalHasArrows<"u"?n.horizontalHasArrows:!1,vertical:typeof n.vertical<"u"?n.vertical:1,verticalScrollbarSize:typeof n.verticalScrollbarSize<"u"?n.verticalScrollbarSize:10,verticalHasArrows:typeof n.verticalHasArrows<"u"?n.verticalHasArrows:!1,verticalSliderSize:typeof n.verticalSliderSize<"u"?n.verticalSliderSize:0,scrollByPage:typeof n.scrollByPage<"u"?n.scrollByPage:!1};return i.horizontalSliderSize=typeof n.horizontalSliderSize<"u"?n.horizontalSliderSize:i.horizontalScrollbarSize,i.verticalSliderSize=typeof n.verticalSliderSize<"u"?n.verticalSliderSize:i.verticalScrollbarSize,ie&&(i.className+=" xterm-mac"),i}var ut=class extends g{constructor(e,t,r,s,o,a,l,h,d){super();this._bufferService=r;this._coreService=o;this._optionsService=h;this._renderService=d;this._onRequestScrollLines=this._register(new b);this.onRequestScrollLines=this._onRequestScrollLines.event;this._isSyncing=!1;this._isHandlingScroll=!1;this._suppressOnScrollHandler=!1;this._needsSyncOnRender=!1;let c=this._register(new ct({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:u=>it(s.window,u)}));this._register(this._optionsService.onSpecificOptionChange("smoothScrollDuration",()=>{c.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)})),this._scrollableElement=this._register(new Pi(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,verticalHasArrows:this._optionsService.rawOptions.scrollbar?.showArrows??!1,...this._getChangeOptions()},c)),this._register(this._optionsService.onMultipleOptionChange(["scrollSensitivity","fastScrollSensitivity","scrollbar"],()=>this._scrollableElement.updateOptions(this._getChangeOptions()))),this._register(a.onProtocolChange(u=>{this._scrollableElement.updateOptions({handleMouseWheel:!(u&16)})})),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(j.runAndSubscribe(l.onChangeColors,()=>{e.style.backgroundColor=l.colors.background.css,this._scrollableElement.getDomNode().style.backgroundColor=l.colors.background.css})),e.appendChild(this._scrollableElement.getDomNode()),this._register(E(()=>this._scrollableElement.getDomNode().remove())),this._styleElement=s.mainDocument.createElement("style"),t.appendChild(this._styleElement),this._register(E(()=>this._styleElement.remove())),this._register(j.runAndSubscribe(l.onChangeColors,()=>{this._styleElement.textContent=[".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {",` background: ${l.colors.scrollbarSliderBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {",` background: ${l.colors.scrollbarSliderHoverBackground.css};`,"}",".xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {",` background: ${l.colors.scrollbarSliderActiveBackground.css};`,"}"].join(` -+`)})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(u=>this._handleScroll(u)))}scrollLines(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){let e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,r=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:r,verticalHasArrows:t}}queueSync(e){e!==void 0&&(this._latestYDisp=e),this._queuedAnimationFrame===void 0&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){if(!(!this._renderService||this._isSyncing)){if(this._coreService.decPrivateModes.synchronizedOutput){this._needsSyncOnRender=!0;return}this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1}}_handleScroll(e){if(!this._renderService||this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;let t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),r=t-this._bufferService.buffer.ydisp;r!==0&&(this._latestYDisp=t,this._onRequestScrollLines.fire(r)),this._isHandlingScroll=!1}handleTouchScroll(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};ut=y([m(2,D),m(3,G),m(4,Y),m(5,Me),m(6,_e),m(7,R),m(8,V)],ut);var ft=class extends g{constructor(e,t,r,s,o){super();this._screenElement=e;this._bufferService=t;this._coreBrowserService=r;this._decorationService=s;this._renderService=o;this._decorationElements=new Map;this._altBufferIsActive=!1;this._dimensionsChanged=!1;this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(a=>this._removeDecoration(a))),this._register(E(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){this._animationFrame===void 0&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(let e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){let t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer",e?.options?.layer==="top"),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,t.style.top=`${(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height}px`,t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;let r=e.options.x??0;return r&&r>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){let t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let r=this._decorationElements.get(e);r||(r=this._createElement(e),e.element=r,this._decorationElements.set(e,r),this._container.appendChild(r),e.onDispose(()=>{this._decorationElements.delete(e),r.remove()})),r.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(r.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,r.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,r.style.top=`${t*this._renderService.dimensions.css.cell.height}px`,r.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(r)}}_refreshXPosition(e,t=e.element){if(!t)return;let r=e.options.x??0;(e.options.anchor||"left")==="right"?t.style.right=r?`${r*this._renderService.dimensions.css.cell.width}px`:"":t.style.left=r?`${r*this._renderService.dimensions.css.cell.width}px`:""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};ft=y([m(1,D),m(2,G),m(3,ge),m(4,V)],ft);var Bi=class{constructor(){this._zones=[];this._zonePool=[];this._zonePoolIndex=0;this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(i){if(i.options.overviewRulerOptions){for(let e of this._zones)if(e.color===i.options.overviewRulerOptions.color&&e.position===i.options.overviewRulerOptions.position){if(this._lineIntersectsZone(e,i.marker.line))return;if(this._lineAdjacentToZone(e,i.marker.line,i.options.overviewRulerOptions.position)){this._addLineToZone(e,i.marker.line);return}}if(this._zonePoolIndex=i.startBufferLine&&e<=i.endBufferLine}_lineAdjacentToZone(i,e,t){return e>=i.startBufferLine-this._linePadding[t||"full"]&&e<=i.endBufferLine+this._linePadding[t||"full"]}_addLineToZone(i,e){i.startBufferLine=Math.min(i.startBufferLine,e),i.endBufferLine=Math.max(i.endBufferLine,e)}};var Ie={full:0,left:0,center:0,right:0},He={full:0,left:0,center:0,right:0},$t={full:0,left:0,center:0,right:0},Ge=class extends g{constructor(e,t,r,s,o,a,l,h){super();this._viewportElement=e;this._screenElement=t;this._bufferService=r;this._decorationService=s;this._renderService=o;this._optionsService=a;this._themeService=l;this._coreBrowserService=h;this._colorZoneStore=new Bi;this._shouldUpdateDimensions=!0;this._shouldUpdateAnchor=!0;this._lastKnownBufferLength=0;this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register(E(()=>this._canvas?.remove()));let d=this._canvas.getContext("2d");if(d)this._ctx=d;else throw new Error("Ctx cannot be null");this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register(E(()=>{this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}get _width(){let e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??!0?e?.width??0:0}_refreshDrawConstants(){let e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);He.full=this._canvas.width,He.left=e,He.center=t,He.right=e,this._refreshDrawHeightConstants(),$t.full=1,$t.left=1,$t.center=1+He.left,$t.right=1+He.left+He.center}_refreshDrawHeightConstants(){Ie.full=Math.round(2*this._coreBrowserService.dpr);let e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);Ie.left=t,Ie.center=t,Ie.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;let e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(let t of this._decorationService.decorations)this._colorZoneStore.addDecoration(t);this._ctx.lineWidth=1,this._renderRulerOutline();let e=this._colorZoneStore.zones;for(let t of e)t.position!=="full"&&this._renderColorZone(t);for(let t of e)t.position==="full"&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect($t[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-Ie[e.position||"full"]/2),He[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+Ie[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};Ge=y([m(2,D),m(3,ge),m(4,V),m(5,R),m(6,_e),m(7,G)],Ge);var jn="xterm-composition-session-start",js="xterm-composition-session-end",Zn="xterm-composition-transaction-accepted",Ee=class{constructor(i,e,t,r,s,o){this._textarea=i;this._compositionView=e;this._bufferService=t;this._optionsService=r;this._coreService=s;this._renderService=o;this._isComposing=!1,this._isAwaitingCompositionEnd=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionStartValue="",this._compositionStartSelection={start:0,end:0},this._compositionHasObservedProgress=!1,this._compositionTransactionId=0,this._compositionTimers=new Set}get isComposing(){return this._isComposing}get hasPendingCompositionFinalization(){return this._pendingComposition!==void 0}get _isSendingComposition(){return this.hasPendingCompositionFinalization}get _pendingKeypressData(){return this._pendingComposition?.keypressData??""}compositionstart(){this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=void 0,this._cancelDeferredTimer(this._compositionViewTimer),this._compositionViewTimer=void 0,this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._pendingComposition&&(this._cancelPendingFinalizer(this._pendingComposition),this._endPendingCompositionSession(this._pendingComposition),this._settlePendingComposition(this._pendingComposition)),this._textareaChangeTimer!==void 0&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);let i=this._textarea.selectionStart??this._textarea.value.length,e=this._textarea.selectionEnd??i;this._compositionPosition.start=Math.min(i,e),this._compositionPosition.end=Math.max(i,e),this._compositionStartValue=this._textarea.value,this._compositionStartSelection={start:i,end:e},this._compositionHasObservedProgress=!1,this._pendingComposition&&(this._pendingComposition.nextCompositionStart=this._compositionPosition.start),this._compositionTransactionId++,this._isComposing=!0,this._isAwaitingCompositionEnd=!0,this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionView.classList.add("active"),this._dispatchCompositionSessionEvent(new CustomEvent(jn,{bubbles:!0,detail:{id:this._compositionTransactionId}}))}compositionupdate(i){this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._compositionHasObservedProgress||=this._hasCompositionProgress(),i.data?.length>0&&(this._lastCompositionData=i.data),this._compositionView.textContent=`\u200E${i.data??""}\u200E`,this.updateCompositionElements();let e=this._compositionTransactionId;this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=this._defer(()=>{if(this._isComposing&&this._compositionTransactionId===e){this._compositionHasObservedProgress||=this._hasCompositionProgress();let t=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,t)}})}compositionend(i){if(!this._isAwaitingCompositionEnd)return!1;if(!this._isComposing){let t=this._pendingComposition;return t?.transactionId===this._compositionTransactionId&&(t.endData=i?.data??"",this._updatePostCompositionInputExpectation(t)),!1}let e=i?.data??"";if(this._compositionHasObservedProgress||=this._hasCompositionProgress(),!this._compositionEndBelongsToCurrentTransaction(e)){let t=this._pendingComposition;return t&&t.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(t),this._deferCompositionEnd(e),!1}return this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._finalizeComposition(!0,e),!0}blur(){if(this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._isComposing){let i=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,i)}(this._isComposing||this.hasPendingCompositionFinalization)&&this._finalizeComposition(!1)}dispose(){this._textareaChangeTimer!==void 0&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);for(let i of this._compositionTimers)clearTimeout(i);this._compositionTimers.clear(),this._compositionPositionTimer=void 0,this._compositionViewTimer=void 0,this._compositionEndTimer=void 0,this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionTransactionId++}keydown(i){if(this._canceledKey?.code===i.code&&this._canceledKey.timeStamp===i.timeStamp)return this._canceledKey=void 0,!1;if(i.key==="Escape"&&(this._isComposing||this.hasPendingCompositionFinalization))return this._canceledKey={code:i.code,timeStamp:i.timeStamp},this._cancelComposition(),!1;if(this._isComposing||this.hasPendingCompositionFinalization){if(i.keyCode===20||i.keyCode===229||i.keyCode===16||i.keyCode===17||i.keyCode===18)return!1;this._finalizeComposition(!1)}return i.keyCode===229?(this._handleAnyTextareaChanges(),!1):!0}keypress(i){let e=this._pendingComposition;return e?e.keypressMayOverlapComposition?(e.keypressData+=i,!0):e.expectsPostCompositionInput&&e.keypressData.length===0?(e.keypressData=i,!0):(this._sendPendingComposition(e),!1):!1}input(i){if(this._isComposing)return this._compositionHasObservedProgress||=this._hasCompositionProgress(),this._compositionInputData+=i,!0;let e=this._pendingComposition;if(!e)return!1;if(e.expectsPostCompositionInput)return e.inputData+=i,e.expectsPostCompositionInput=!1,this._sendPendingComposition(e),!0;let t=i.length>0&&this._getPendingTextareaInput(e)===i&&this._getPendingTextareaInput(e,!0)===i;return this._sendPendingComposition(e),t||this._coreService.triggerDataEvent(i,!0),!0}_finalizeComposition(i,e=""){let t=this._isComposing;if(this._compositionView.classList.remove("active"),this._isComposing=!1,!(i&&!t)){if(i){this._pendingComposition&&this._sendPendingComposition(this._pendingComposition);let r={transactionId:this._compositionTransactionId,lifecycleSettled:!1,sessionEnded:!1,position:{start:this._compositionPosition.start,end:this._compositionPosition.end},suffix:this._compositionSuffix,dataAlreadySent:this._dataAlreadySent,compositionData:this._lastCompositionData,endData:e,inputData:this._compositionInputData,keypressData:"",keypressMayOverlapComposition:this._lastCompositionData.length===0&&e.length===0,expectsPostCompositionInput:!1};this._updatePostCompositionInputExpectation(r),this._pendingComposition=r,r.finalizerTimer=this._defer(()=>{r.finalizerTimer=void 0,this._compositionTransactionId===r.transactionId&&(this._isAwaitingCompositionEnd=!1),this._pendingComposition===r&&this._sendPendingComposition(r,!0)})}else if(this._pendingComposition&&this._sendPendingComposition(this._pendingComposition,!0),t){let r=this._getCompositionInput(this._compositionPosition.start+this._dataAlreadySent.length,this._compositionSuffix);this._sendCompositionInput(this._compositionTransactionId,r)}}}_sendPendingComposition(i,e=!1){this._cancelPendingFinalizer(i),this._pendingComposition===i&&(this._pendingComposition=void 0);let t=this._getPendingTextareaInput(i,e),r=this._removeAlreadySentData(i.inputData||i.keypressData,i.dataAlreadySent),s=this._mergeTextObservations(t||i.endData||i.compositionData,r,i.keypressMayOverlapComposition);this._sendCompositionInput(i.transactionId,s,!i.sessionEnded),this._settlePendingComposition(i)}_cancelPendingFinalizer(i){i.finalizerTimer!==void 0&&(clearTimeout(i.finalizerTimer),this._compositionTimers.delete(i.finalizerTimer),i.finalizerTimer=void 0)}_settlePendingComposition(i){i.lifecycleSettled||(i.lifecycleSettled=!0,this._dispatchCompositionTransactionSettled())}_mergeTextObservations(i,e,t){if(!e||i.includes(e))return i;if(!i||e.includes(i))return e;if(t){let s=Math.min(i.length,e.length);for(;s>0&&!i.endsWith(e.substring(0,s));)s--;let o=Math.min(i.length,e.length);for(;o>0&&!e.endsWith(i.substring(0,o));)o--;return s>o?i+e.substring(s):e+i.substring(o)}let r=Math.min(i.length,e.length);for(;r>0&&!i.endsWith(e.substring(0,r));)r--;return i+e.substring(r)}_updatePostCompositionInputExpectation(i){i.expectsPostCompositionInput=(i.endData.length>0||i.compositionData.length>0)&&i.inputData.length===0&&this._getPendingTextareaInput(i).length===0}_getPendingTextareaInput(i,e=!1){let t=this._textarea.value,r=i.position.start+i.dataAlreadySent.length;if(i.nextCompositionStart!==void 0)return t.substring(r,Math.max(r,i.nextCompositionStart));let s=i.suffix.length>0&&t.endsWith(i.suffix)?t.length-i.suffix.length:t.length,o=(i.endData||i.compositionData).length,a=e?s:Math.max(i.position.end,r+o);return t.substring(r,Math.max(r,Math.min(s,a)))}_getCompositionInput(i,e){let t=this._textarea.value,r=e.length>0&&t.endsWith(e)?t.length-e.length:t.length;return t.substring(i,Math.max(i,r))}_removeAlreadySentData(i,e){return e.length===0?i:i.startsWith(e)?i.substring(e.length):e.includes(i)?"":i}_cancelComposition(){let i=this._pendingComposition;i&&this._isComposing&&i.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(i);let e=this._isComposing?this._compositionTransactionId:this._pendingComposition?.transactionId??0,t=i!==void 0&&this._pendingComposition===i;this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionView.classList.remove("active"),this._textarea.value=this._textarea.value.substring(0,this._compositionPosition.start)+this._compositionSuffix,this._sendCompositionInput(e,""),t&&i&&this._settlePendingComposition(i)}_sendCompositionInput(i,e,t=!0){let r=!1;if(t){let s=new CustomEvent(js,{bubbles:!0,cancelable:!0,detail:{id:i,data:e}});this._dispatchCompositionSessionEvent(s),r=s.defaultPrevented}e.length>0&&!r&&this._coreService.triggerDataEvent(e,!0)}_endPendingCompositionSession(i){if(i.sessionEnded)return;i.sessionEnded=!0;let e=this._getPendingTextareaInput(i)||i.endData||i.compositionData;this._dispatchCompositionSessionEvent(new CustomEvent(js,{bubbles:!0,cancelable:!0,detail:{id:i.transactionId,data:e,dataPendingReconciliation:!0}}))}_dispatchCompositionSessionEvent(i){typeof this._textarea.dispatchEvent=="function"&&this._textarea.dispatchEvent(i)}_dispatchCompositionTransactionSettled(){this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-settled",{bubbles:!0}))}_deferCompositionEnd(i){this._cancelDeferredTimer(this._compositionEndTimer);let e=this._compositionTransactionId,t=this._defer(()=>{if(this._compositionEndTimer!==t||!this._isComposing||this._compositionTransactionId!==e||!this._compositionEndBelongsToCurrentTransaction(i))return;this._compositionEndTimer=void 0,this._finalizeComposition(!0,i),this._dispatchCompositionSessionEvent(new CustomEvent(Zn,{bubbles:!0}));let r=this._pendingComposition;r?.transactionId===e&&this._sendPendingComposition(r,!0)});this._compositionEndTimer=t}_hasCompositionProgress(){let i=this._textarea.selectionStart??this._textarea.value.length,e=this._textarea.selectionEnd??i;return this._compositionHasObservedProgress||this._textarea.value!==this._compositionStartValue||i!==this._compositionStartSelection.start||e!==this._compositionStartSelection.end}_compositionEndBelongsToCurrentTransaction(i){return this._hasCompositionProgress()||i.length>0&&i===this._lastCompositionData}_defer(i){let e=setTimeout(()=>{this._compositionTimers.delete(e),i()},0);return this._compositionTimers.add(e),e}_cancelDeferredTimer(i){i!==void 0&&(clearTimeout(i),this._compositionTimers.delete(i))}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;let i=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){let e=this._textarea.value,t=e.replace(i,"");this._dataAlreadySent=t,e.length>i.length?this._coreService.triggerDataEvent(t,!0):e.lengththis.updateCompositionElements(!0)))}}};Ee=y([m(2,D),m(3,R),m(4,Y),m(5,V)],Ee);var J=0,Q=0,ee=0,W=0,ts={css:"#00000000",rgba:0},O;(t=>{function n(r,s,o,a){return a!==void 0?`#${$e(r)}${$e(s)}${$e(o)}${$e(a)}`:`#${$e(r)}${$e(s)}${$e(o)}`}t.toCss=n;function i(r,s,o,a=255){return(r<<24|s<<16|o<<8|a)>>>0}t.toRgba=i;function e(r,s,o,a){return{css:t.toCss(r,s,o,a),rgba:t.toRgba(r,s,o,a)}}t.toColor=e})(O||={});var k;(a=>{function n(l,h){if(W=(h.rgba&255)/255,W===1)return{css:h.css,rgba:h.rgba};let d=h.rgba>>24&255,c=h.rgba>>16&255,u=h.rgba>>8&255,_=l.rgba>>24&255,p=l.rgba>>16&255,v=l.rgba>>8&255;J=_+Math.round((d-_)*W),Q=p+Math.round((c-p)*W),ee=v+Math.round((u-v)*W);let f=O.toCss(J,Q,ee),S=O.toRgba(J,Q,ee);return{css:f,rgba:S}}a.blend=n;function i(l){return(l.rgba&255)===255}a.isOpaque=i;function e(l,h,d){let c=Oi.ensureContrastRatio(l.rgba,h.rgba,d);if(c)return O.toColor(c>>24&255,c>>16&255,c>>8&255)}a.ensureContrastRatio=e;function t(l){let h=(l.rgba|255)>>>0;return[J,Q,ee]=Oi.toChannels(h),{css:O.toCss(J,Q,ee),rgba:h}}a.opaque=t;function r(l,h){return W=Math.round(h*255),[J,Q,ee]=Oi.toChannels(l.rgba),{css:O.toCss(J,Q,ee,W),rgba:O.toRgba(J,Q,ee,W)}}a.opacity=r;function s(l,h){return W=l.rgba&255,r(l,W*h/255)}a.multiplyOpacity=s;function o(l){return[l.rgba>>24&255,l.rgba>>16&255,l.rgba>>8&255]}a.toColorRGB=o})(k||={});var M;(t=>{let n,i;try{let r=document.createElement("canvas");r.width=1,r.height=1;let s=r.getContext("2d",{willReadFrequently:!0});s&&(n=s,n.globalCompositeOperation="copy",i=n.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),O.toColor(J,Q,ee);case 5:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),W=parseInt(r.slice(4,5).repeat(2),16),O.toColor(J,Q,ee,W);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let s=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(s)return J=parseInt(s[1],10),Q=parseInt(s[2],10),ee=parseInt(s[3],10),W=Math.round((s[5]===void 0?1:parseFloat(s[5]))*255),O.toColor(J,Q,ee,W);if(r==="transparent")return{css:"transparent",rgba:0};if(!n||!i)throw new Error("css.toColor: Unsupported css format");if(n.fillStyle=i,n.fillStyle=r,typeof n.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(n.fillRect(0,0,1,1),[J,Q,ee,W]=n.getImageData(0,0,1,1).data,W!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:O.toRgba(J,Q,ee,W),css:r}}t.toColor=e})(M||={});var Z;(e=>{function n(t){return i(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=n;function i(t,r,s){let o=t/255,a=r/255,l=s/255,h=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4),d=a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4),c=l<=.03928?l/12.92:Math.pow((l+.055)/1.055,2.4);return h*.2126+d*.7152+c*.0722}e.relativeLuminance2=i})(Z||={});var Oi;(s=>{function n(o,a){if(W=(a&255)/255,W===1)return a;let l=a>>24&255,h=a>>16&255,d=a>>8&255,c=o>>24&255,u=o>>16&255,_=o>>8&255;return J=c+Math.round((l-c)*W),Q=u+Math.round((h-u)*W),ee=_+Math.round((d-_)*W),O.toRgba(J,Q,ee)}s.blend=n;function i(o,a,l){let h=Z.relativeLuminance(o>>8),d=Z.relativeLuminance(a>>8);if(De(h,d)>8));if(v>8));return v>S?p:f}return p}let u=t(o,a,l),_=De(h,Z.relativeLuminance(u>>8));if(_>8));return _>v?u:p}return u}}s.ensureContrastRatio=i;function e(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v0||_>0||p>0);)u-=Math.max(0,Math.ceil(u*.1)),_-=Math.max(0,Math.ceil(_*.1)),p-=Math.max(0,Math.ceil(p*.1)),v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));return(u<<24|_<<16|p<<8|255)>>>0}s.reduceLuminance=e;function t(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v>>0}s.increaseLuminance=t;function r(o){return[o>>24&255,o>>16&255,o>>8&255,o&255]}s.toChannels=r})(Oi||={});function $e(n){let i=n.toString(16);return i.length<2?"0"+i:i}function De(n,i){return n1){let u=this._getJoinedRanges(r,l,a,e,o);for(let _=0;_1){let c=this._getJoinedRanges(r,l,a,e,o);for(let u=0;u=ks,Lr=ae,x=this._workCell;if(v.length>0&&ae===v[0][0]&&Ze){let A=v.shift(),Br=this._isCellInSelection(A[0],e);for(T=A[0]+1;T=A[1],Ze?(fi=!0,x=new Ni(this._workCell,i.translateToString(!0,A[0],A[1]),A[1]-A[0]),Lr=A[1]-1,Rr=x.getWidth()):ks=A[1]}let Nt=this._isCellInSelection(ae,e),Ar=t&&ae===o,kr=kn&&ae>=c&&ae<=u;_&&x.isBlink()&&(_.hasBlinkingCells=!0),!l&&x.isBlink()&&N.push("xterm-blink-hidden");let Pr=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{Pr=!0});let _i=x.getChars()||" ";if(_i===" "&&(x.isUnderline()||x.isOverline())&&(_i="\xA0"),Ot=Rr*h-d.get(_i,x.isBold(),x.isItalic()),!C)C=this._document.createElement("span");else if(w&&(Nt&&ui||!Nt&&!ui&&x.bg===te)&&(Nt&&ui&&f.selectionForeground||x.fg===Ds)&&x.extended.ext===Rs&&kr===Ls&&Ot===As&&!Ar&&!fi&&!Pr&&Ze){x.isInvisible()?L+=" ":L+=_i,w++;continue}else w&&(C.textContent=L),C=this._document.createElement("span"),w=0,L="";if(te=x.bg,Ds=x.fg,Rs=x.extended.ext,Ls=kr,As=Ot,ui=Nt,fi&&o>=ae&&o<=Lr&&(o=ae),!this._coreService.isCursorHidden&&Ar&&this._coreService.isCursorInitialized){if(N.push("xterm-cursor"),this._coreBrowserService.isFocused)a&&N.push("xterm-cursor-blink"),N.push(r==="bar"?"xterm-cursor-bar":r==="underline"?"xterm-cursor-underline":"xterm-cursor-block");else if(s)switch(s){case"outline":N.push("xterm-cursor-outline");break;case"block":N.push("xterm-cursor-block");break;case"bar":N.push("xterm-cursor-bar");break;case"underline":N.push("xterm-cursor-underline");break;default:break}}if(x.isBold()&&N.push("xterm-bold"),x.isItalic()&&N.push("xterm-italic"),x.isDim()&&N.push("xterm-dim"),x.isInvisible()?L=" ":L=x.getChars()||" ",x.isUnderline()&&(N.push(`xterm-underline-${x.extended.underlineStyle}`),L===" "&&(L="\xA0"),!x.isUnderlineColorDefault()))if(x.isUnderlineColorRGB())C.style.textDecorationColor=`rgb(${ue.toColorRGB(x.getUnderlineColor()).join(",")})`;else{let A=x.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&x.isBold()&&A<8&&(A+=8),C.style.textDecorationColor=f.ansi[A].css}x.isOverline()&&(N.push("xterm-overline"),L===" "&&(L="\xA0")),x.isStrikethrough()&&N.push("xterm-strikethrough"),kr&&(C.style.textDecoration="underline");let de=x.getFgColor(),Ft=x.getFgColorMode(),Se=x.getBgColor(),Ht=x.getBgColorMode(),Mr=!!x.isInverse();if(Mr){let A=de;de=Se,Se=A;let Br=Ft;Ft=Ht,Ht=Br}let Ae,pi,Wt=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{A.options.layer!=="top"&&Wt||(A.backgroundColorRGB&&(Ht=50331648,Se=A.backgroundColorRGB.rgba>>8&16777215,Ae=A.backgroundColorRGB),A.foregroundColorRGB&&(Ft=50331648,de=A.foregroundColorRGB.rgba>>8&16777215,pi=A.foregroundColorRGB),Wt=A.options.layer==="top")}),!Wt&&Nt&&(Ae=this._coreBrowserService.isFocused?f.selectionBackgroundOpaque:f.selectionInactiveBackgroundOpaque,Se=Ae.rgba>>8&16777215,Ht=50331648,Wt=!0,f.selectionForeground&&(Ft=50331648,de=f.selectionForeground.rgba>>8&16777215,pi=f.selectionForeground)),Wt&&N.push("xterm-decoration-top");let ke;switch(Ht){case 16777216:case 33554432:ke=f.ansi[Se],N.push(`xterm-bg-${Se}`);break;case 50331648:ke=O.toColor(Se>>16,Se>>8&255,Se&255),this._addStyle(C,`background-color:#${(Se>>>0).toString(16).padStart(6,"0")}`);break;case 0:default:Mr?(ke=f.foreground,N.push(`xterm-bg-${257}`)):ke=f.background}switch(Ae||x.isDim()&&(Ae=k.multiplyOpacity(ke,.5)),Ft){case 16777216:case 33554432:x.isBold()&&de<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(de+=8),this._applyMinimumContrast(C,ke,f.ansi[de],x,Ae,void 0)||N.push(`xterm-fg-${de}`);break;case 50331648:let A=O.toColor(de>>16&255,de>>8&255,de&255);this._applyMinimumContrast(C,ke,A,x,Ae,pi)||this._addStyle(C,`color:#${de.toString(16).padStart(6,"0")}`);break;case 0:default:this._applyMinimumContrast(C,ke,f.foreground,x,Ae,pi)||Mr&&N.push(`xterm-fg-${257}`)}N.length&&(C.className=N.join(" "),N.length=0),!Ar&&!fi&&!Pr&&Ze?w++:C.textContent=L,Ot!==this.defaultSpacing&&(C.style.letterSpacing=`${Ot}px`),p.push(C),ae=Lr}return C&&w&&(C.textContent=L),p}_applyMinimumContrast(i,e,t,r,s,o){if(this._optionsService.rawOptions.minimumContrastRatio===1||Zs(r.getCode()))return!1;let a=this._getContrastCache(r),l;if(!s&&!o&&(l=a.getColor(e.rgba,t.rgba)),l===void 0){let h=this._optionsService.rawOptions.minimumContrastRatio/(r.isDim()?2:1);l=k.ensureContrastRatio(s??e,o??t,h),a.setColor((s??e).rgba,(o??t).rgba,l??null)}return l?(this._addStyle(i,`color:${l.css}`),!0):!1}_getContrastCache(i){return i.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(i,e){i.setAttribute("style",`${i.getAttribute("style")||""}${e};`)}_isCellInSelection(i,e){let t=this._selectionStart,r=this._selectionEnd;return!t||!r?!1:this._columnSelectMode?t[0]<=r[0]?i>=t[0]&&e>=t[1]&&i=t[1]&&i>=r[0]&&e<=r[1]:e>t[1]&&e=t[0]&&i=t[0]}};_t=y([m(1,gi),m(2,R),m(3,G),m(4,Y),m(5,ge),m(6,_e)],_t);var Hi=class{constructor(i=()=>new rs){this._flat=new Float32Array(256);this._font="";this._fontSize=0;this._weight="normal";this._weightBold="bold";this._canvasElements=[];this._canvasElements=[i(),i(),i(),i()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(i,e,t,r){i===this._font&&e===this._fontSize&&t===this._weight&&r===this._weightBold||(this._font=i,this._fontSize=e,this._weight=t,this._weightBold=r,this._canvasElements[0].setFont(i,e,t,!1),this._canvasElements[1].setFont(i,e,r,!1),this._canvasElements[2].setFont(i,e,t,!0),this._canvasElements[3].setFont(i,e,r,!0),this.clear())}get(i,e,t){let r;if(!e&&!t&&i.length===1&&(r=i.charCodeAt(0))<256){if(this._flat[r]!==-9999)return this._flat[r];let a=this._measure(i,0);return a>0&&(this._flat[r]=a),a}let s=i;e&&(s+="B"),t&&(s+="I");let o=this._holey.get(s);if(o===void 0){let a=0;e&&(a|=1),t&&(a|=2),o=this._measure(i,a),o>0&&this._holey.set(s,o)}return o}_measure(i,e){return this._canvasElements[e].measure(i)}},rs=class{constructor(){typeof OffscreenCanvas<"u"?(this._canvas=new OffscreenCanvas(1,1),this._ctx=is(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=is(this._canvas.getContext("2d")))}setFont(i,e,t,r){let s=r?"italic":"";this._ctx.font=`${s} ${t} ${e}px ${i}`.trim()}measure(i){return this._ctx.measureText(i).width}};var ss=class{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(i,e,t,r=!1){if(this.selectionStart=e,this.selectionEnd=t,!e||!t||e[0]===t[0]&&e[1]===t[1]){this.clear();return}let s=i.buffers.active.ydisp,o=e[1]-s,a=t[1]-s,l=Math.max(o,0),h=Math.min(a,i.rows-1);if(l>=i.rows||h<0){this.clear();return}this.hasSelection=!0,this.columnSelectMode=r,this.viewportStartRow=o,this.viewportEndRow=a,this.viewportCappedStartRow=l,this.viewportCappedEndRow=h,this.startCol=e[0],this.endCol=t[0]}isCellSelected(i,e,t){return this.hasSelection?(t-=i.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?e>=this.startCol&&t>=this.viewportCappedStartRow&&e=this.viewportCappedStartRow&&e>=this.endCol&&t<=this.viewportCappedEndRow:t>this.viewportStartRow&&t=this.startCol&&e=this.startCol):!1}};function Qs(){return new ss}var Wi=class extends g{constructor(e,t,r){super();this._renderCallback=e;this._coreBrowserService=t;this._optionsService=r;this._intervalDuration=0;this._blinkOn=!0;this._needsBlinkInViewport=!1;this._isViewportVisible=!0;this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",s=>{this.setIntervalDuration(s)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register(E(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(this._interval!==void 0)return;let t=this._blinkOn;this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),t||this._renderCallback();return}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){this._interval!==void 0&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}};var eo=1,mt=class extends g{constructor(e,t,r,s,o,a,l,h,d,c,u,_,p,v){super();this._terminal=e;this._document=t;this._element=r;this._screenElement=s;this._viewportElement=o;this._helperContainer=a;this._linkifier2=l;this._charSizeService=d;this._optionsService=c;this._bufferService=u;this._coreService=_;this._coreBrowserService=p;this._themeService=v;this._terminalClass=eo++;this._rowElements=[];this._selectionRenderModel=Qs();this._lastSelectionColumnMode=!1;this._rowHasBlinkingCells=[];this._rowHasBlinkingCellsCount=0;this._onRequestRedraw=this._register(new b);this.onRequestRedraw=this._onRequestRedraw.event;this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=Js(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(f=>this._injectCss(f))),this._injectCss(this._themeService.colors),this._rowFactory=h.createInstance(_t,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(f=>this._handleLinkHover(f))),this._register(this._linkifier2.onHideLinkUnderline(f=>this._handleLinkLeave(f))),this._cursorBlinkStateManager=new ns(this._rowContainer,this._coreBrowserService),this._register(I(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register(E(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new Wi(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register(E(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new Hi,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){let e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(let r of this._rowElements)r.style.width=`${this.dimensions.css.canvas.width}px`,r.style.height=`${this.dimensions.css.cell.height}px`,r.style.lineHeight=`${this.dimensions.css.cell.height}px`,r.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));let t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${k.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;let r=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,o=`blink_block_${this._terminalClass}`;t+=`@keyframes ${r} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${o} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${o} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(let[a,l]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${a} { color: ${l.css}; }${this._terminalSelector} .xterm-fg-${a}.xterm-dim { color: ${k.multiplyOpacity(l,.5).css}; }${this._terminalSelector} .xterm-bg-${a} { background-color: ${l.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${257} { color: ${k.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${257}.xterm-dim { color: ${k.multiplyOpacity(k.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${257} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){let e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let r=this._rowElements.length;r<=t;r++){let s=this._document.createElement("div");this._rowContainer.appendChild(s),this._rowElements.push(s),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,r){let s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,r);let o=0,a=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(o=this._selectionRenderModel.viewportCappedStartRow,a=this._selectionRenderModel.viewportCappedEndRow));let l=0,h=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,r),this._selectionRenderModel.hasSelection){let u=this._selectionRenderModel.viewportStartRow,_=this._selectionRenderModel.viewportEndRow,p=this._selectionRenderModel.viewportCappedStartRow,v=this._selectionRenderModel.viewportCappedEndRow;l=p,h=v;let f=this._document.createDocumentFragment();if(r){let S=e[0]>t[0];f.appendChild(this._createSelectionElement(p,S?t[0]:e[0],S?e[0]:t[0],v-p+1))}else{let S=u===p?e[0]:0,C=p===_?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(p,S,C));let w=v-p-1;if(f.appendChild(this._createSelectionElement(p+1,0,this._bufferService.cols,w)),p!==v){let L=_===v?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(v,0,L))}}this._selectionContainer.appendChild(f)}let d=Math.min(o,l),c=Math.max(a,h);if(c>=0){d=Math.max(d,0),c=Math.min(c,s-1);let _=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&_>=0&&_this.dimensions.css.canvas.width&&(l=this.dimensions.css.canvas.width-a),o.style.height=`${s*this.dimensions.css.cell.height}px`,o.style.top=`${e*this.dimensions.css.cell.height}px`,o.style.left=`${a}px`,o.style.width=`${l}px`,o}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(let e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){let r=this._bufferService.buffer,s=r.ybase+r.y,o=Math.min(r.x,this._bufferService.cols-1),a=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,l=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,h=this._optionsService.rawOptions.cursorInactiveStyle,d={hasBlinkingCells:!1};for(let c=e;c<=t;c++){let u=c+r.ydisp,_=this._rowElements[c];if(!_)continue;let p=r.lines.get(u);if(!p){_.replaceChildren(),this._setRowBlinkState(c,!1);continue}_.replaceChildren(...this._rowFactory.createRow(p,u,u===s,l,h,o,a,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,d)),this._setRowBlinkState(c,d.hasBlinkingCells)}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,r,s,o,a){r<0&&(e=0),s<0&&(t=0);let l=this._bufferService.rows-1;r=Math.max(Math.min(r,l),0),s=Math.max(Math.min(s,l),0),o=Math.min(o,this._bufferService.cols);let h=this._bufferService.buffer,d=h.ybase+h.y,c=Math.min(h.x,o-1),u=this._optionsService.rawOptions.cursorBlink,_=this._optionsService.rawOptions.cursorStyle,p=this._optionsService.rawOptions.cursorInactiveStyle,v={hasBlinkingCells:!1};for(let f=r;f<=s;++f){let S=f+h.ydisp,C=this._rowElements[f];if(!C)continue;let w=h.lines.get(S);if(!w){C.replaceChildren(),this._setRowBlinkState(f,!1);continue}C.replaceChildren(...this._rowFactory.createRow(w,S,S===d,_,p,c,u,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,a?f===r?e:0:-1,a?(f===s?t:o)-1:-1,v)),this._setRowBlinkState(f,v.hasBlinkingCells)}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};mt=y([m(7,et),m(8,Be),m(9,R),m(10,D),m(11,Y),m(12,G),m(13,_e)],mt);var ns=class{constructor(i,e){this._rowContainer=i;this._coreBrowserService=e;this._isIdlePaused=!1;this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){this._idleTimeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}};var bt=class extends g{constructor(e,t,r){super();this._optionsService=r;this.width=0;this.height=0;this._onCharSizeChange=this._register(new b);this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new as(this._optionsService))}catch{this._measureStrategy=this._register(new os(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}get hasValidSize(){return this.width>0&&this.height>0}measure(){let e=this._measureStrategy.measure();(e.width!==this.width||e.height!==this.height)&&(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};bt=y([m(2,R)],bt);var Ui=class extends g{constructor(){super(...arguments);this._result={width:0,height:0}}_validateAndSet(e,t){e!==void 0&&e>0&&t!==void 0&&t>0&&(this._result.width=e,this._result.height=t)}},os=class extends Ui{constructor(e,t,r){super();this._document=e;this._parentElement=t;this._optionsService=r;this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}},as=class extends Ui{constructor(e){super();this._optionsService=e;this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");let t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;let e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}};var Ki=class extends g{constructor(e,t,r){super();this._textarea=e;this._window=t;this.mainDocument=r;this._isFocused=!1;this._cachedIsFocused=void 0;this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._onWindowChange=this._register(new b);this.onWindowChange=this._onWindowChange.event;this._screenDprMonitor=this._register(new ls(this._window)),this._register(this.onWindowChange(s=>this._screenDprMonitor.setWindow(s))),this._register(j.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register(I(this._textarea,"focus",()=>this._isFocused=!0)),this._register(I(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return this._cachedIsFocused===void 0&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}},ls=class extends g{constructor(e){super();this._parentWindow=e;this._windowResizeListener=this._register(new B);this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register(E(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=I(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){!this._resolutionMediaMatchList||!this._outerListener||(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}};var zi=class extends g{constructor(){super();this.linkProviders=[];this._register(E(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{let t=this.linkProviders.indexOf(e);t!==-1&&this.linkProviders.splice(t,1)}}}};function qt(n,i,e){let t=e.getBoundingClientRect(),r=n.getComputedStyle(e),s=parseInt(r.getPropertyValue("padding-left"),10),o=parseInt(r.getPropertyValue("padding-top"),10);return[i.clientX-t.left-s,i.clientY-t.top-o]}function en(n,i,e,t,r,s,o,a,l){if(!s)return;let h=qt(n,i,e);return h[0]=Math.ceil((h[0]+(l?o/2:0))/o),h[1]=Math.ceil(h[1]/a),h[0]=Math.min(Math.max(h[0],1),t+(l?1:0)),h[1]=Math.min(Math.max(h[1],1),r),h}var vt=class{constructor(i,e){this._charSizeService=i;this._renderService=e}getCoords(i,e,t,r,s){return en(se(e),i,e,t,r,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,s)}getMouseReportCoords(i,e){let t=qt(se(e),i,e);if(this._charSizeService.hasValidSize)return t[0]=Math.min(Math.max(t[0],0),this._renderService.dimensions.css.canvas.width-1),t[1]=Math.min(Math.max(t[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(t[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(t[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(t[0]),y:Math.floor(t[1])}}};vt=y([m(0,Be),m(1,V)],vt);var tn=typeof window=="object"?window:globalThis;function ce(n,i=0){return n[n.length-(1+i)]}function to(n,i,e){let t=null,r=null;if(typeof e.value=="function"?(t="value",r=e.value,r.length!==0&&console.warn("Memoize should only be used in functions with zero parameters")):typeof e.get=="function"&&(t="get",r=e.get),!r||!t)throw new Error("not supported");let s=`$memoize$${i}`,o=e;o[t]=function(...a){return this.hasOwnProperty(s)||Object.defineProperty(this,s,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,a)}),this[s]}}var St=class St{constructor(i){this.element=i,this.next=St.Undefined,this.prev=St.Undefined}};St.Undefined=new St(void 0);var re=St,Gi=class{constructor(){this._first=re.Undefined;this._last=re.Undefined}push(i){return this._insert(i,!0)}_insert(i,e){let t=new re(i);if(this._first===re.Undefined)this._first=t,this._last=t;else if(e){let s=this._last;this._last=t,t.prev=s,s.next=t}else{let s=this._first;this._first=t,t.next=s,s.prev=t}let r=!1;return()=>{r||(r=!0,this._remove(t))}}_remove(i){if(i.prev!==re.Undefined&&i.next!==re.Undefined){let e=i.prev;e.next=i.next,i.next.prev=e}else i.prev===re.Undefined&&i.next===re.Undefined?(this._first=re.Undefined,this._last=re.Undefined):i.next===re.Undefined?(this._last=this._last.prev,this._last.next=re.Undefined):i.prev===re.Undefined&&(this._first=this._first.next,this._first.prev=re.Undefined)}*[Symbol.iterator](){let i=this._first;for(;i!==re.Undefined;)yield i.element,i=i.next}},he;(s=>(s.TAP="-xterm-gesturetap",s.CHANGE="-xterm-gesturechange",s.START="-xterm-gesturestart",s.END="-xterm-gesturesend",s.CONTEXT_MENU="-xterm-gesturecontextmenu"))(he||={});var K=class K extends g{constructor(){super();this._dispatched=!1;this._targets=new Gi;this._ignoreTargets=new Gi;this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;let e=tn;this._register(I(e.document,"touchstart",t=>this._handleTouchStart(t),{passive:!1})),this._register(I(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(I(e.document,"touchmove",t=>this._handleTouchMove(t),{passive:!1}))}static addTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._targets.push(e);return E(t)}static ignoreTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._ignoreTargets.push(e);return E(t)}static isTouchDevice(){return"ontouchstart"in tn||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){let t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let r=0,s=e.targetTouches.length;r=K._holdDelay&&Math.abs(h.initialPageX-ce(h.rollingPageX))<30&&Math.abs(h.initialPageY-ce(h.rollingPageY))<30){let c=this._newGestureEvent(he.CONTEXT_MENU,h.initialTarget);c.pageX=ce(h.rollingPageX),c.pageY=ce(h.rollingPageY),this._dispatchEvent(c)}else if(s===1){let c=ce(h.rollingPageX),u=ce(h.rollingPageY),_=ce(h.rollingTimestamps)-h.rollingTimestamps[0],p=c-h.rollingPageX[0],v=u-h.rollingPageY[0],f=[...this._targets].filter(S=>h.initialTarget instanceof Node&&S.contains(h.initialTarget));this._inertia(e,f,r,Math.abs(p)/_,p>0?1:-1,c,Math.abs(v)/_,v>0?1:-1,u)}this._dispatchEvent(this._newGestureEvent(he.END,h.initialTarget)),delete this._activeTouches[l.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){let r=document.createEvent("CustomEvent");return r.initEvent(e,!1,!0),r.initialTarget=t,r.tapCount=0,r}_dispatchEvent(e){if(e.type===he.TAP){let t=new Date().getTime(),r;t-this._lastSetTapCountTime>K._clearTapCountTime?r=1:r=2,this._lastSetTapCountTime=t,e.tapCount=r}else(e.type===he.CHANGE||e.type===he.CONTEXT_MENU)&&(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(let r of this._ignoreTargets)if(r.contains(e.initialTarget))return;let t=[];for(let r of this._targets)if(r.contains(e.initialTarget)){let s=0,o=e.initialTarget;for(;o&&o!==r;)s++,o=o.parentElement;t.push([s,r])}t.sort((r,s)=>r[0]-s[0]);for(let[,r]of t)r.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,r,s,o,a,l,h,d){this._handle=it(e,()=>{let c=Date.now(),u=c-r,_=0,p=0,v=!0;s+=K._scrollFriction*u,l+=K._scrollFriction*u,s>0&&(v=!1,_=o*s*u),l>0&&(v=!1,p=h*l*u);let f=this._newGestureEvent(he.CHANGE);f.translationX=_,f.translationY=p,t.forEach(S=>S.dispatchEvent(f)),v||this._inertia(e,t,c,s,o,a+_,l,h,d+p)})}_handleTouchMove(e){let t=Date.now();for(let r=0,s=e.changedTouches.length;r3&&(a.rollingPageX.shift(),a.rollingPageY.shift(),a.rollingTimestamps.shift()),a.rollingPageX.push(o.pageX),a.rollingPageY.push(o.pageY),a.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}};K._scrollFriction=-.005,K._holdDelay=700,K._clearTapCountTime=400,y([to],K,"isTouchDevice",1);var Vi=K;var gt=class{constructor(i,e,t,r,s,o,a,l,h){this._renderService=i;this._mouseCoordsService=e;this._mouseStateService=t;this._coreService=r;this._bufferService=s;this._optionsService=o;this._selectionService=a;this._logService=l;this._coreBrowserService=h;this._lastEvent=null;this._wheelPartialScroll=0;this._touchScrollAccumulator=0}bindMouse(i,e,t){let{element:r,document:s}=i,o={mouseup:null,wheel:null,mousedrag:null,mousemove:null},a={target:i,focus:t,requestedEvents:o},l={mouseup:h=>this._handleMouseUp(a,h),wheel:h=>this._handleWheel(a,h),mousedrag:h=>this._handleMouseDrag(a,h),mousemove:h=>this._handleMouseMove(a,h)};this._altMouseCursor=new cs(r,s,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),e(this._altMouseCursor),e(this._mouseStateService.onProtocolChange(h=>{this._handleProtocolChange(a,l,h)})),e(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(r),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,e(E(()=>{o.mouseup&&s.removeEventListener("mouseup",o.mouseup),o.mousedrag&&s.removeEventListener("mousemove",o.mousedrag)})),e(I(r,"mousedown",h=>this._handleMouseDown(a,h))),e(I(r,"wheel",h=>this._handlePassiveWheel(a,h),{passive:!1})),e(Vi.addTarget(i.screenElement)),e(I(i.screenElement,he.START,()=>this._handleTouchStart())),e(I(i.screenElement,he.CHANGE,h=>this._handleTouchChange(a,h)))}_sendEvent(i,e){let t=this._mouseCoordsService.getMouseReportCoords(e,i.target.screenElement);if(!t)return!1;let r,s;switch(e.overrideType||e.type){case"mousemove":s=32,e.buttons===void 0?(r=3,e.button!==void 0&&(r=e.button<3?e.button:3)):r=e.buttons&1?0:e.buttons&4?1:e.buttons&2?2:3;break;case"mouseup":s=0,r=e.button<3?e.button:3;break;case"mousedown":s=1,r=e.button<3?e.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;let a=e.deltaY;if(a===0||this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return!1;s=a<0?0:1,r=4;break;default:return!1}if(s===void 0||r===void 0||r>4||r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!e.altKey)return!1;let o=r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:t.col,row:t.row,x:t.x,y:t.y,button:r,action:s,ctrl:e.ctrlKey,alt:o?!1:e.altKey,shift:e.shiftKey})}_handleMouseUp(i,e){this._sendEvent(i,e),e.buttons||(i.requestedEvents.mouseup&&i.target.document.removeEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.removeEventListener("mousemove",i.requestedEvents.mousedrag))}_handleWheel(i,e){return this._sendEvent(i,e),e.preventDefault(),e.stopPropagation(),!1}_handleMouseDrag(i,e){e.buttons&&this._sendEvent(i,e)}_handleMouseMove(i,e){e.buttons||this._sendEvent(i,e)}_handleMouseDown(i,e){e.preventDefault(),i.focus(),!(!this._mouseStateService.areMouseEventsActive||this._selectionService.shouldForceSelection(e))&&(this._sendEvent(i,e),i.requestedEvents.mouseup&&i.target.document.addEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.addEventListener("mousemove",i.requestedEvents.mousedrag))}_handlePassiveWheel(i,e){if(!i.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;if(!this._bufferService.buffer.hasScrollback){if(e.deltaY===0)return!1;if(this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return e.preventDefault(),e.stopPropagation(),!1;let s="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(e.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(s,!0),e.preventDefault(),e.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(i,e){if(e.preventDefault(),e.stopPropagation(),i.requestedEvents.wheel){this._handleTouchScrollAsWheel(i,e);return}if(!this._bufferService.buffer.hasScrollback){this._handleTouchScrollAsKeys(e);return}i.target.handleTouchScroll?.(e.translationY)}_handleTouchScrollAsKeys(i){let e=this._renderService?.dimensions.css.cell.height;if(!e)return;this._touchScrollAccumulator-=i.translationY;let t=Math.trunc(this._touchScrollAccumulator/e);if(t===0)return;this._touchScrollAccumulator-=t*e;let r="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t<0?"A":"B");for(let s=0;s0?1:-1),this._wheelPartialScroll%=1):i.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(s*=this._bufferService.rows),s}_triggerMouseEvent(i){if(i.col<0||i.col>=this._bufferService.cols||i.row<0||i.row>=this._bufferService.rows||i.button===4&&i.action===32||i.button===3&&i.action!==32||i.button!==4&&(i.action===2||i.action===3)||(i.col++,i.row++,i.action===32&&this._lastEvent&&this._equalEvents(this._lastEvent,i,this._mouseStateService.isPixelEncoding))||!this._mouseStateService.restrictMouseEvent(i))return!1;let e=this._mouseStateService.encodeMouseEvent(i);return e&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(e):this._coreService.triggerDataEvent(e,!0)),this._lastEvent=i,!0}_explainEvents(i){return{down:!!(i&1),up:!!(i&2),drag:!!(i&4),move:!!(i&8),wheel:!!(i&16)}}_equalEvents(i,e,t){if(t){if(i.x!==e.x||i.y!==e.y)return!1}else if(i.col!==e.col||i.row!==e.row)return!1;return!(i.button!==e.button||i.action!==e.action||i.ctrl!==e.ctrl||i.alt!==e.alt||i.shift!==e.shift)}};gt=y([m(0,V),m(1,Oe),m(2,Me),m(3,Y),m(4,D),m(5,R),m(6,Si),m(7,fe),m(8,G)],gt);var cs=class{constructor(i,e,t){this._element=i;this._document=e;this._isActive=t;this._listeners=new B}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;let i=new pe,e=r=>this.syncFromModifier(r);i.add(I(this._document,"keydown",e)),i.add(I(this._document,"keyup",e)),i.add(I(this._element,"mousemove",e));let t=this._element.ownerDocument?.defaultView;t&&i.add(I(t,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=i}resetClass(){this._updateClass(!1)}syncFromModifier(i){this._isActive()&&this._updateClass(i.getModifierState("Alt"))}_updateClass(i){i?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}};var $i=class{constructor(i,e){this._renderCallback=i;this._coreBrowserService=e;this._refreshCallbacks=[]}dispose(){this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)}addRefreshCallback(i){return this._refreshCallbacks.push(i),this._animationFrame??=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()),this._animationFrame}refresh(i,e,t){this._rowCount=t,i=i??0,e=e??this._rowCount-1,this._rowStart=this._rowStart!==void 0?Math.min(this._rowStart,i):i,this._rowEnd=this._rowEnd!==void 0?Math.max(this._rowEnd,e):e,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,this._rowStart===void 0||this._rowEnd===void 0||this._rowCount===void 0){this._runRefreshCallbacks();return}let i=Math.max(this._rowStart,0),e=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(i,e),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(let i of this._refreshCallbacks)i(0);this._refreshCallbacks=[]}};var qi=class{constructor(i){this._tasks=[];this._i=0;this._logService=i}enqueue(i){this._tasks.push(i),this._start()}flush(){for(;this._is){r-e<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-e))}ms`),this._start();return}r=s}this.clear()}},hs=class extends qi{_requestCallback(i){return setTimeout(()=>i(this._createDeadline(16)))}_cancelCallback(i){clearTimeout(i)}_createDeadline(i){let e=performance.now()+i;return{timeRemaining:()=>Math.max(0,e-performance.now())}}},ds=class extends qi{_requestCallback(i){return requestIdleCallback(i)}_cancelCallback(i){cancelIdleCallback(i)}},Ct="requestIdleCallback"in globalThis?ds:hs,Xi=class{constructor(i){this._queue=new Ct(i)}set(i){this._queue.clear(),this._queue.enqueue(i)}flush(){this._queue.flush()}dispose(){this._queue.clear()}};var It=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._rowCount=e;this._optionsService=r;this._logService=s;this._charSizeService=o;this._coreService=a;this._coreBrowserService=d;this._renderer=this._register(new B);this._observerDisposable=this._register(new B);this._isPaused=!1;this._needsFullRefresh=!1;this._isNextRenderRedrawOnly=!0;this._needsSelectionRefresh=!1;this._canvasWidth=0;this._canvasHeight=0;this._selectionState={start:void 0,end:void 0,columnSelectMode:!1};this._onDimensionsChange=this._register(new b);this.onDimensionsChange=this._onDimensionsChange.event;this._onRenderedViewportChange=this._register(new b);this.onRenderedViewportChange=this._onRenderedViewportChange.event;this._onRender=this._register(new b);this.onRender=this._onRender.event;this._onRefreshRequest=this._register(new b);this.onRefreshRequest=this._onRefreshRequest.event;this._pausedResizeTask=this._register(new Xi(this._logService)),this._renderDebouncer=new $i((u,_)=>this._renderRows(u,_),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new us(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register(E(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(h.onResize(()=>this._fullRefresh())),this._register(h.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(h.cols,h.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(h.buffer.y,h.buffer.y,void 0,!0))),this._register(c.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(u=>this._registerIntersectionObserver(u,t)))}get dimensions(){return this._renderer.value.dimensions}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){let r=new e.IntersectionObserver(s=>this._handleIntersectionChange(s[s.length-1]),{threshold:0});this._observerDisposable.value=E(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=r,r.observe(t)}}_handleIntersectionChange(e){this._isPaused=e.isIntersecting===void 0?e.intersectionRatio===0:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),!this._isPaused&&!this._charSizeService.hasValidSize&&this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,r=!1,s=!1){if(this._isPaused){this._needsFullRefresh=!0;return}if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}let o=this._syncOutputHandler.flush();o&&(e=Math.min(e,o.start),t=Math.max(t,o.end)),s||(this._isNextRenderRedrawOnly=!1),r?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){if(this._renderer.value){if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0}}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(t=>this.refreshRows(t.start,t.end,t.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,r){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=r,this._renderer.value?.handleSelectionChanged(e,t,r)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};It=y([m(2,R),m(3,fe),m(4,Be),m(5,Y),m(6,ge),m(7,D),m(8,G),m(9,_e)],It);var us=class{constructor(i,e,t){this._coreBrowserService=i;this._coreService=e;this._onTimeout=t;this._start=0;this._end=0;this._isBuffering=!1}bufferRows(i,e){this._isBuffering?(this._start=Math.min(this._start,i),this._end=Math.max(this._end,e)):(this._start=i,this._end=e,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;let i={start:this._start,end:this._end};return this._isBuffering=!1,i}dispose(){this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}};function rn(n,i,e,t){let r=e.buffer.x,s=e.buffer.y;if(!e.buffer.hasScrollback)return oo(r,s,n,i,e,t)+Yi(s,i,e,t)+ao(r,s,n,i,e,t);let o;if(s===i)return o=r>n?"D":"C",Yt(Math.abs(r-n),Xt(o,t));o=s>i?"D":"C";let a=Math.abs(s-i),l=no(s>i?n:r,e)+(a-1)*e.cols+1+so(s>i?r:n,e);return Yt(l,Xt(o,t))}function so(n,i){return n-1}function no(n,i){return i.cols-n}function oo(n,i,e,t,r,s){return Yi(i,t,r,s).length===0?"":Yt(nn(n,i,n,i-qe(i,r),!1,r).length,Xt("D",s))}function Yi(n,i,e,t){let r=n-qe(n,e),s=i-qe(i,e),o=Math.abs(r-s)-lo(n,i,e);return Yt(o,Xt(sn(n,i),t))}function ao(n,i,e,t,r,s){let o;Yi(i,t,r,s).length>0?o=t-qe(t,r):o=i;let a=t,l=co(n,i,e,t,r,s);return Yt(nn(n,o,e,a,l==="C",r).length,Xt(l,s))}function lo(n,i,e){let t=0,r=n-qe(n,e),s=i-qe(i,e);for(let o=0;o=0&&n0?o=t-qe(t,r):o=i,n=e&&oi?"A":"B"}function nn(n,i,e,t,r,s){let o=n,a=i,l="";for(;(o!==e||a!==t)&&a>=0&&as.cols-1?(l+=s.buffer.translateBufferLineToString(a,!1,n,o),o=0,n=0,a++):!r&&o<0&&(l+=s.buffer.translateBufferLineToString(a,!1,0,n+1),o=s.cols-1,n=o,a--);return l+s.buffer.translateBufferLineToString(a,!1,n,o)}function Xt(n,i){let e=i?"O":"[";return"\x1B"+e+n}function Yt(n,i){n=Math.floor(n);let e="";for(let t=0;tthis._bufferService.cols?i%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)-1]:[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[i,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){let i=this.selectionStart[0]+this.selectionStartLength;return i>this._bufferService.cols?[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[Math.max(i,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){let i=this.selectionStart,e=this.selectionEnd;return!i||!e?!1:i[1]>e[1]||i[1]===e[1]&&i[0]>e[0]}handleTrim(i){return this.selectionStart&&(this.selectionStart[1]-=i),this.selectionEnd&&(this.selectionEnd[1]-=i),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):this.selectionStart&&this.selectionStart[1]<0?(this.selectionStart=[0,0],!0):!1}};function fs(n,i){if(n.start.y>n.end.y)throw new Error(`Buffer range end (${n.end.x}, ${n.end.y}) cannot be before start (${n.start.x}, ${n.start.y})`);return i*(n.end.y-n.start.y)+(n.end.x-n.start.x+1)}var ho="\xA0",uo=new RegExp(ho,"g");var Et=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._element=e;this._screenElement=t;this._linkifier=r;this._bufferService=s;this._coreService=o;this._mouseCoordsService=a;this._optionsService=l;this._mouseStateService=h;this._renderService=d;this._coreBrowserService=c;this._dragScrollAmount=0;this._enabled=!0;this._trimListener=this._register(new B);this._workCell=new F;this._mouseDownTimeStamp=0;this._oldHasSelection=!1;this._oldSelectionStart=void 0;this._oldSelectionEnd=void 0;this._onLinuxMouseSelection=this._register(new b);this.onLinuxMouseSelection=this._onLinuxMouseSelection.event;this._onRedrawRequest=this._register(new b);this.onRequestRedraw=this._onRedrawRequest.event;this._onSelectionChange=this._register(new b);this.onSelectionChange=this._onSelectionChange.event;this._onRequestScrollLines=this._register(new b);this.onRequestScrollLines=this._onRequestScrollLines.event;this._mouseMoveListener=u=>this._handleMouseMove(u),this._mouseUpListener=u=>this._handleMouseUp(u),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(u=>this._handleTrim(u)),this._register(this._bufferService.buffers.onBufferActivate(u=>this._handleBufferActivate(u))),this.enable(),this._model=new ji(this._bufferService),this._activeSelectionMode=0,this._register(E(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(u=>{u.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!e||!t?!1:e[0]!==t[0]||e[1]!==t[1]}get selectionText(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";let r=this._bufferService.buffer,s=[];if(this._activeSelectionMode===3){if(e[0]===t[0])return"";let a=e[0]a.replace(uo," ")).join(Ke?`\r ++`)})),this._register(this._bufferService.onResize(()=>this.queueSync())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._latestYDisp=void 0,this.queueSync()})),this._register(this._bufferService.onScroll(()=>this._sync())),this._register(this._renderService.onRender(()=>{this._needsSyncOnRender&&(this._needsSyncOnRender=!1,this._sync())})),this._register(this._scrollableElement.onScroll(u=>this._handleScroll(u)))}scrollLines(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){let e=this._optionsService.rawOptions.scrollbar?.showScrollbar??!0,t=this._optionsService.rawOptions.scrollbar?.showArrows??!1,r=e?this._optionsService.rawOptions.scrollbar?.width??14:0;return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,vertical:e?1:2,verticalScrollbarSize:r,verticalHasArrows:t}}queueSync(e){e!==void 0&&(this._latestYDisp=e),this._queuedAnimationFrame===void 0&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback(()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)}))}_sync(e=this._bufferService.buffer.ydisp){if(!(!this._renderService||this._isSyncing)){if(this._coreService.decPrivateModes.synchronizedOutput){this._needsSyncOnRender=!0;return}this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1}}_handleScroll(e){if(!this._renderService||this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;let t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),r=t-this._bufferService.buffer.ydisp;r!==0&&(this._latestYDisp=t,this._onRequestScrollLines.fire(r)),this._isHandlingScroll=!1}handleTouchScroll(e){let t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({scrollTop:t.scrollTop-e})}};ut=y([m(2,D),m(3,G),m(4,Y),m(5,Me),m(6,_e),m(7,R),m(8,V)],ut);var ft=class extends g{constructor(e,t,r,s,o){super();this._screenElement=e;this._bufferService=t;this._coreBrowserService=r;this._decorationService=s;this._renderService=o;this._decorationElements=new Map;this._altBufferIsActive=!1;this._dimensionsChanged=!1;this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange(()=>this._doRefreshDecorations())),this._register(this._renderService.onDimensionsChange(()=>{this._dimensionsChanged=!0,this._queueRefresh()})),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt})),this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh())),this._register(this._decorationService.onDecorationRemoved(a=>this._removeDecoration(a))),this._register(E(()=>{this._container.remove(),this._decorationElements.clear()}))}_queueRefresh(){this._animationFrame===void 0&&(this._animationFrame=this._renderService.addRefreshCallback(()=>{this._doRefreshDecorations(),this._animationFrame=void 0}))}_doRefreshDecorations(){for(let e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){let t=this._coreBrowserService.mainDocument.createElement("div");t.classList.add("xterm-decoration"),t.classList.toggle("xterm-decoration-top-layer",e?.options?.layer==="top"),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,t.style.top=`${(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height}px`,t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;let r=e.options.x??0;return r&&r>this._bufferService.cols&&(t.style.display="none"),this._refreshXPosition(e,t),t}_refreshStyle(e){let t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let r=this._decorationElements.get(e);r||(r=this._createElement(e),e.element=r,this._decorationElements.set(e,r),this._container.appendChild(r),e.onDispose(()=>{this._decorationElements.delete(e),r.remove()})),r.style.display=this._altBufferIsActive?"none":"block",this._altBufferIsActive||(r.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,r.style.height=`${(e.options.height||1)*this._renderService.dimensions.css.cell.height}px`,r.style.top=`${t*this._renderService.dimensions.css.cell.height}px`,r.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(r)}}_refreshXPosition(e,t=e.element){if(!t)return;let r=e.options.x??0;(e.options.anchor||"left")==="right"?t.style.right=r?`${r*this._renderService.dimensions.css.cell.width}px`:"":t.style.left=r?`${r*this._renderService.dimensions.css.cell.width}px`:""}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};ft=y([m(1,D),m(2,G),m(3,ge),m(4,V)],ft);var Bi=class{constructor(){this._zones=[];this._zonePool=[];this._zonePoolIndex=0;this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(i){if(i.options.overviewRulerOptions){for(let e of this._zones)if(e.color===i.options.overviewRulerOptions.color&&e.position===i.options.overviewRulerOptions.position){if(this._lineIntersectsZone(e,i.marker.line))return;if(this._lineAdjacentToZone(e,i.marker.line,i.options.overviewRulerOptions.position)){this._addLineToZone(e,i.marker.line);return}}if(this._zonePoolIndex=i.startBufferLine&&e<=i.endBufferLine}_lineAdjacentToZone(i,e,t){return e>=i.startBufferLine-this._linePadding[t||"full"]&&e<=i.endBufferLine+this._linePadding[t||"full"]}_addLineToZone(i,e){i.startBufferLine=Math.min(i.startBufferLine,e),i.endBufferLine=Math.max(i.endBufferLine,e)}};var Ie={full:0,left:0,center:0,right:0},He={full:0,left:0,center:0,right:0},$t={full:0,left:0,center:0,right:0},Ge=class extends g{constructor(e,t,r,s,o,a,l,h){super();this._viewportElement=e;this._screenElement=t;this._bufferService=r;this._decorationService=s;this._renderService=o;this._optionsService=a;this._themeService=l;this._coreBrowserService=h;this._colorZoneStore=new Bi;this._shouldUpdateDimensions=!0;this._shouldUpdateAnchor=!0;this._lastKnownBufferLength=0;this._canvas=this._coreBrowserService.mainDocument.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register(E(()=>this._canvas?.remove()));let d=this._canvas.getContext("2d");if(d)this._ctx=d;else throw new Error("Ctx cannot be null");this._register(this._decorationService.onDecorationRegistered(()=>this._queueRefresh(void 0,!0))),this._register(this._decorationService.onDecorationRemoved(()=>this._queueRefresh(void 0,!0))),this._register(this._renderService.onRenderedViewportChange(()=>this._queueRefresh())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"})),this._register(this._bufferService.onScroll(()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})),this._register(this._renderService.onDimensionsChange(()=>this._queueRefresh(!0))),this._register(this._coreBrowserService.onDprChange(()=>this._queueRefresh(!0))),this._register(this._optionsService.onSpecificOptionChange("scrollbar",()=>this._queueRefresh(!0))),this._register(this._themeService.onChangeColors(()=>this._queueRefresh())),this._register(E(()=>{this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)})),this._queueRefresh(!0)}get _width(){let e=this._optionsService.rawOptions.scrollbar;return e?.showScrollbar??!0?e?.width??0:0}_refreshDrawConstants(){let e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);He.full=this._canvas.width,He.left=e,He.center=t,He.right=e,this._refreshDrawHeightConstants(),$t.full=1,$t.left=1,$t.center=1+He.left,$t.right=1+He.left+He.center}_refreshDrawHeightConstants(){Ie.full=Math.round(2*this._coreBrowserService.dpr);let e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);Ie.left=t,Ie.center=t,Ie.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*Ie.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;let e=this._renderService.dimensions.css.canvas.height,t=this._renderService.dimensions.device.canvas.height;this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${e}px`,this._canvas.height=t,this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){if(this._store.isDisposed||!this._renderService.hasRenderer())return;this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(let t of this._decorationService.decorations)this._colorZoneStore.addDecoration(t);this._ctx.lineWidth=1,this._renderRulerOutline();let e=this._colorZoneStore.zones;for(let t of e)t.position!=="full"&&this._renderColorZone(t);for(let t of e)t.position==="full"&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect($t[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-Ie[e.position||"full"]/2),He[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+Ie[e.position||"full"]))}_queueRefresh(e,t){this._store.isDisposed||(this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>{this._store.isDisposed||this._refreshDecorations(),this._animationFrame=void 0})))}};Ge=y([m(2,D),m(3,ge),m(4,V),m(5,R),m(6,_e),m(7,G)],Ge);var jn="xterm-composition-session-start",js="xterm-composition-session-end",Zn="xterm-composition-transaction-accepted",Ee=class{constructor(i,e,t,r,s,o){this._textarea=i;this._compositionView=e;this._bufferService=t;this._optionsService=r;this._coreService=s;this._renderService=o;this._isComposing=!1,this._isAwaitingCompositionEnd=!1,this._compositionPosition={start:0,end:0},this._compositionSuffix="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionStartValue="",this._compositionStartSelection={start:0,end:0},this._compositionHasObservedProgress=!1,this._compositionTransactionId=0,this._compositionTimers=new Set}get isComposing(){return this._isComposing}get hasPendingCompositionFinalization(){return this._pendingComposition!==void 0}get _isSendingComposition(){return this.hasPendingCompositionFinalization}get _pendingKeypressData(){return this._pendingComposition?.keypressData??""}compositionstart(){this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=void 0,this._cancelDeferredTimer(this._compositionViewTimer),this._compositionViewTimer=void 0,this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._textareaChangeTimer!==void 0&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);let i=this._textarea.selectionStart??this._textarea.value.length,e=this._textarea.selectionEnd??i;this._compositionPosition.start=Math.min(i,e),this._compositionPosition.end=Math.max(i,e),this._compositionStartValue=this._textarea.value,this._compositionStartSelection={start:i,end:e},this._compositionHasObservedProgress=!1,this._pendingComposition&&(this._pendingComposition.nextCompositionStart=this._compositionPosition.start),this._compositionTransactionId++,this._isComposing=!0,this._isAwaitingCompositionEnd=!0,this._compositionSuffix=this._textarea.value.substring(this._compositionPosition.end),this._compositionView.textContent="",this._dataAlreadySent="",this._compositionInputData="",this._lastCompositionData="",this._compositionView.classList.add("active"),this._dispatchCompositionSessionEvent(new CustomEvent(jn,{bubbles:!0,detail:{id:this._compositionTransactionId}}))}compositionupdate(i){this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._compositionHasObservedProgress||=this._hasCompositionProgress(),i.data?.length>0&&(this._lastCompositionData=i.data),this._compositionView.textContent=`\u200E${i.data??""}\u200E`,this.updateCompositionElements();let e=this._compositionTransactionId;this._cancelDeferredTimer(this._compositionPositionTimer),this._compositionPositionTimer=this._defer(()=>{if(this._isComposing&&this._compositionTransactionId===e){this._compositionHasObservedProgress||=this._hasCompositionProgress();let t=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,t)}})}compositionend(i){if(!this._isAwaitingCompositionEnd)return!1;if(!this._isComposing){let t=this._pendingComposition;return t?.transactionId===this._compositionTransactionId&&(t.endData=i?.data??"",this._updatePostCompositionInputExpectation(t)),!1}let e=i?.data??"";if(this._compositionHasObservedProgress||=this._hasCompositionProgress(),!this._compositionEndBelongsToCurrentTransaction(e)){let t=this._pendingComposition;return t&&t.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(t),this._deferCompositionEnd(e),!1}return this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._finalizeComposition(!0,e),!0}blur(){if(this._cancelDeferredTimer(this._compositionEndTimer),this._compositionEndTimer=void 0,this._isComposing){let i=this._textarea.selectionEnd??this._textarea.value.length;this._compositionPosition.end=Math.max(this._compositionPosition.start,i)}(this._isComposing||this.hasPendingCompositionFinalization)&&this._finalizeComposition(!1)}dispose(){this._textareaChangeTimer!==void 0&&(clearTimeout(this._textareaChangeTimer),this._textareaChangeTimer=void 0);for(let i of this._compositionTimers)clearTimeout(i);this._compositionTimers.clear(),this._compositionPositionTimer=void 0,this._compositionViewTimer=void 0,this._compositionEndTimer=void 0,this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionTransactionId++}keydown(i){if(this._canceledKey?.code===i.code&&this._canceledKey.timeStamp===i.timeStamp)return this._canceledKey=void 0,!1;if(i.key==="Escape"&&(this._isComposing||this.hasPendingCompositionFinalization))return this._canceledKey={code:i.code,timeStamp:i.timeStamp},this._cancelComposition(),!1;if(this._isComposing||this.hasPendingCompositionFinalization){if(i.keyCode===20||i.keyCode===229||i.keyCode===16||i.keyCode===17||i.keyCode===18)return!1;this._finalizeComposition(!1)}return i.keyCode===229?(this._handleAnyTextareaChanges(),!1):!0}keypress(i){let e=this._pendingComposition;return e?e.keypressMayOverlapComposition?(e.keypressData+=i,!0):e.expectsPostCompositionInput&&e.keypressData.length===0?(e.keypressData=i,!0):(this._sendPendingComposition(e),!1):!1}input(i){if(this._isComposing)return this._compositionHasObservedProgress||=this._hasCompositionProgress(),this._compositionInputData+=i,!0;let e=this._pendingComposition;if(!e)return!1;if(e.expectsPostCompositionInput)return e.inputData+=i,e.expectsPostCompositionInput=!1,this._sendPendingComposition(e),!0;let t=i.length>0&&this._getPendingTextareaInput(e)===i&&this._getPendingTextareaInput(e,!0)===i;return this._sendPendingComposition(e),t||this._coreService.triggerDataEvent(i,!0),!0}_finalizeComposition(i,e=""){let t=this._isComposing;if(this._compositionView.classList.remove("active"),this._isComposing=!1,!(i&&!t)){if(i){this._pendingComposition&&this._sendPendingComposition(this._pendingComposition);let r={transactionId:this._compositionTransactionId,lifecycleSettled:!1,sessionEnded:!1,position:{start:this._compositionPosition.start,end:this._compositionPosition.end},suffix:this._compositionSuffix,dataAlreadySent:this._dataAlreadySent,compositionData:this._lastCompositionData,endData:e,inputData:this._compositionInputData,keypressData:"",keypressMayOverlapComposition:this._lastCompositionData.length===0&&e.length===0,expectsPostCompositionInput:!1};this._updatePostCompositionInputExpectation(r),this._pendingComposition=r,r.finalizerTimer=this._defer(()=>{r.finalizerTimer=void 0,this._compositionTransactionId===r.transactionId&&(this._isAwaitingCompositionEnd=!1),this._pendingComposition===r&&this._sendPendingComposition(r,!0)})}else if(this._pendingComposition&&this._sendPendingComposition(this._pendingComposition,!0),t){let r=this._getCompositionInput(this._compositionPosition.start+this._dataAlreadySent.length,this._compositionSuffix);this._sendCompositionInput(this._compositionTransactionId,r)}}}_sendPendingComposition(i,e=!1){this._cancelPendingFinalizer(i),this._pendingComposition===i&&(this._pendingComposition=void 0);let t=this._getPendingTextareaInput(i,e),r=this._removeAlreadySentData(i.inputData||i.keypressData,i.dataAlreadySent),s=this._mergeTextObservations(t||i.endData||(r?i.compositionData:""),r,i.keypressMayOverlapComposition);this._sendCompositionInput(i.transactionId,s,!i.sessionEnded),this._settlePendingComposition(i)}_cancelPendingFinalizer(i){i.finalizerTimer!==void 0&&(clearTimeout(i.finalizerTimer),this._compositionTimers.delete(i.finalizerTimer),i.finalizerTimer=void 0)}_settlePendingComposition(i){i.lifecycleSettled||(i.lifecycleSettled=!0,this._dispatchCompositionTransactionSettled())}_mergeTextObservations(i,e,t){if(!e||i.includes(e))return i;if(!i||e.includes(i))return e;if(t){let s=Math.min(i.length,e.length);for(;s>0&&!i.endsWith(e.substring(0,s));)s--;let o=Math.min(i.length,e.length);for(;o>0&&!e.endsWith(i.substring(0,o));)o--;return s>o?i+e.substring(s):e+i.substring(o)}let r=Math.min(i.length,e.length);for(;r>0&&!i.endsWith(e.substring(0,r));)r--;return i+e.substring(r)}_updatePostCompositionInputExpectation(i){i.expectsPostCompositionInput=(i.endData.length>0||i.compositionData.length>0)&&i.inputData.length===0&&this._getPendingTextareaInput(i).length===0}_getPendingTextareaInput(i,e=!1){let t=this._textarea.value,r=i.position.start+i.dataAlreadySent.length;if(i.nextCompositionStart!==void 0)return t.substring(r,Math.max(r,i.nextCompositionStart));let s=i.suffix.length>0&&t.endsWith(i.suffix)?t.length-i.suffix.length:t.length,o=(i.endData||i.compositionData).length,a=e?s:Math.max(i.position.end,r+o);return t.substring(r,Math.max(r,Math.min(s,a)))}_getCompositionInput(i,e){let t=this._textarea.value,r=e.length>0&&t.endsWith(e)?t.length-e.length:t.length;return t.substring(i,Math.max(i,r))}_removeAlreadySentData(i,e){return e.length===0?i:i.startsWith(e)?i.substring(e.length):e.includes(i)?"":i}_cancelComposition(){let i=this._pendingComposition;i&&this._isComposing&&i.transactionId!==this._compositionTransactionId&&this._sendPendingComposition(i);let e=this._isComposing?this._compositionTransactionId:this._pendingComposition?.transactionId??0,t=i!==void 0&&this._pendingComposition===i;this._pendingComposition=void 0,this._isAwaitingCompositionEnd=!1,this._isComposing=!1,this._compositionView.classList.remove("active"),this._textarea.value=this._textarea.value.substring(0,this._compositionPosition.start)+this._compositionSuffix,this._sendCompositionInput(e,""),t&&i&&this._settlePendingComposition(i)}_sendCompositionInput(i,e,t=!0){let r=!1;if(t){let s=new CustomEvent(js,{bubbles:!0,cancelable:!0,detail:{id:i,data:e}});this._dispatchCompositionSessionEvent(s),r=s.defaultPrevented}e.length>0&&!r&&this._coreService.triggerDataEvent(e,!0)}_endPendingCompositionSession(i){if(i.sessionEnded)return;i.sessionEnded=!0;let e=this._getPendingTextareaInput(i)||i.endData||i.compositionData;this._dispatchCompositionSessionEvent(new CustomEvent(js,{bubbles:!0,cancelable:!0,detail:{id:i.transactionId,data:e,dataPendingReconciliation:!0}}))}_dispatchCompositionSessionEvent(i){typeof this._textarea.dispatchEvent=="function"&&this._textarea.dispatchEvent(i)}_dispatchCompositionTransactionSettled(){this._dispatchCompositionSessionEvent(new CustomEvent("xterm-composition-transaction-settled",{bubbles:!0}))}_deferCompositionEnd(i){this._cancelDeferredTimer(this._compositionEndTimer);let e=this._compositionTransactionId,t=this._defer(()=>{if(this._compositionEndTimer!==t||!this._isComposing||this._compositionTransactionId!==e||!this._compositionEndBelongsToCurrentTransaction(i))return;this._compositionEndTimer=void 0,this._finalizeComposition(!0,i),this._dispatchCompositionSessionEvent(new CustomEvent(Zn,{bubbles:!0}));let r=this._pendingComposition;r?.transactionId===e&&this._sendPendingComposition(r,!0)});this._compositionEndTimer=t}_hasCompositionProgress(){let i=this._textarea.selectionStart??this._textarea.value.length,e=this._textarea.selectionEnd??i;return this._compositionHasObservedProgress||this._textarea.value!==this._compositionStartValue||i!==this._compositionStartSelection.start||e!==this._compositionStartSelection.end}_compositionEndBelongsToCurrentTransaction(i){return this._hasCompositionProgress()||i.length>0&&i===this._lastCompositionData}_defer(i){let e=setTimeout(()=>{this._compositionTimers.delete(e),i()},0);return this._compositionTimers.add(e),e}_cancelDeferredTimer(i){i!==void 0&&(clearTimeout(i),this._compositionTimers.delete(i))}_handleAnyTextareaChanges(){if(this._textareaChangeTimer)return;let i=this._textarea.value;this._textareaChangeTimer=window.setTimeout(()=>{if(this._textareaChangeTimer=void 0,!this._isComposing){let e=this._textarea.value,t=e.replace(i,"");this._dataAlreadySent=t,e.length>i.length?this._coreService.triggerDataEvent(t,!0):e.lengththis.updateCompositionElements(!0)))}}};Ee=y([m(2,D),m(3,R),m(4,Y),m(5,V)],Ee);var J=0,Q=0,ee=0,W=0,ts={css:"#00000000",rgba:0},O;(t=>{function n(r,s,o,a){return a!==void 0?`#${$e(r)}${$e(s)}${$e(o)}${$e(a)}`:`#${$e(r)}${$e(s)}${$e(o)}`}t.toCss=n;function i(r,s,o,a=255){return(r<<24|s<<16|o<<8|a)>>>0}t.toRgba=i;function e(r,s,o,a){return{css:t.toCss(r,s,o,a),rgba:t.toRgba(r,s,o,a)}}t.toColor=e})(O||={});var k;(a=>{function n(l,h){if(W=(h.rgba&255)/255,W===1)return{css:h.css,rgba:h.rgba};let d=h.rgba>>24&255,c=h.rgba>>16&255,u=h.rgba>>8&255,_=l.rgba>>24&255,p=l.rgba>>16&255,v=l.rgba>>8&255;J=_+Math.round((d-_)*W),Q=p+Math.round((c-p)*W),ee=v+Math.round((u-v)*W);let f=O.toCss(J,Q,ee),S=O.toRgba(J,Q,ee);return{css:f,rgba:S}}a.blend=n;function i(l){return(l.rgba&255)===255}a.isOpaque=i;function e(l,h,d){let c=Oi.ensureContrastRatio(l.rgba,h.rgba,d);if(c)return O.toColor(c>>24&255,c>>16&255,c>>8&255)}a.ensureContrastRatio=e;function t(l){let h=(l.rgba|255)>>>0;return[J,Q,ee]=Oi.toChannels(h),{css:O.toCss(J,Q,ee),rgba:h}}a.opaque=t;function r(l,h){return W=Math.round(h*255),[J,Q,ee]=Oi.toChannels(l.rgba),{css:O.toCss(J,Q,ee,W),rgba:O.toRgba(J,Q,ee,W)}}a.opacity=r;function s(l,h){return W=l.rgba&255,r(l,W*h/255)}a.multiplyOpacity=s;function o(l){return[l.rgba>>24&255,l.rgba>>16&255,l.rgba>>8&255]}a.toColorRGB=o})(k||={});var M;(t=>{let n,i;try{let r=document.createElement("canvas");r.width=1,r.height=1;let s=r.getContext("2d",{willReadFrequently:!0});s&&(n=s,n.globalCompositeOperation="copy",i=n.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),O.toColor(J,Q,ee);case 5:return J=parseInt(r.slice(1,2).repeat(2),16),Q=parseInt(r.slice(2,3).repeat(2),16),ee=parseInt(r.slice(3,4).repeat(2),16),W=parseInt(r.slice(4,5).repeat(2),16),O.toColor(J,Q,ee,W);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let s=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(s)return J=parseInt(s[1],10),Q=parseInt(s[2],10),ee=parseInt(s[3],10),W=Math.round((s[5]===void 0?1:parseFloat(s[5]))*255),O.toColor(J,Q,ee,W);if(r==="transparent")return{css:"transparent",rgba:0};if(!n||!i)throw new Error("css.toColor: Unsupported css format");if(n.fillStyle=i,n.fillStyle=r,typeof n.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(n.fillRect(0,0,1,1),[J,Q,ee,W]=n.getImageData(0,0,1,1).data,W!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:O.toRgba(J,Q,ee,W),css:r}}t.toColor=e})(M||={});var Z;(e=>{function n(t){return i(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=n;function i(t,r,s){let o=t/255,a=r/255,l=s/255,h=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4),d=a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4),c=l<=.03928?l/12.92:Math.pow((l+.055)/1.055,2.4);return h*.2126+d*.7152+c*.0722}e.relativeLuminance2=i})(Z||={});var Oi;(s=>{function n(o,a){if(W=(a&255)/255,W===1)return a;let l=a>>24&255,h=a>>16&255,d=a>>8&255,c=o>>24&255,u=o>>16&255,_=o>>8&255;return J=c+Math.round((l-c)*W),Q=u+Math.round((h-u)*W),ee=_+Math.round((d-_)*W),O.toRgba(J,Q,ee)}s.blend=n;function i(o,a,l){let h=Z.relativeLuminance(o>>8),d=Z.relativeLuminance(a>>8);if(De(h,d)>8));if(v>8));return v>S?p:f}return p}let u=t(o,a,l),_=De(h,Z.relativeLuminance(u>>8));if(_>8));return _>v?u:p}return u}}s.ensureContrastRatio=i;function e(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v0||_>0||p>0);)u-=Math.max(0,Math.ceil(u*.1)),_-=Math.max(0,Math.ceil(_*.1)),p-=Math.max(0,Math.ceil(p*.1)),v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));return(u<<24|_<<16|p<<8|255)>>>0}s.reduceLuminance=e;function t(o,a,l){let h=o>>24&255,d=o>>16&255,c=o>>8&255,u=a>>24&255,_=a>>16&255,p=a>>8&255,v=De(Z.relativeLuminance2(u,_,p),Z.relativeLuminance2(h,d,c));for(;v>>0}s.increaseLuminance=t;function r(o){return[o>>24&255,o>>16&255,o>>8&255,o&255]}s.toChannels=r})(Oi||={});function $e(n){let i=n.toString(16);return i.length<2?"0"+i:i}function De(n,i){return n1){let u=this._getJoinedRanges(r,l,a,e,o);for(let _=0;_1){let c=this._getJoinedRanges(r,l,a,e,o);for(let u=0;u=ks,Lr=ae,x=this._workCell;if(v.length>0&&ae===v[0][0]&&Ze){let A=v.shift(),Br=this._isCellInSelection(A[0],e);for(T=A[0]+1;T=A[1],Ze?(fi=!0,x=new Ni(this._workCell,i.translateToString(!0,A[0],A[1]),A[1]-A[0]),Lr=A[1]-1,Rr=x.getWidth()):ks=A[1]}let Nt=this._isCellInSelection(ae,e),Ar=t&&ae===o,kr=kn&&ae>=c&&ae<=u;_&&x.isBlink()&&(_.hasBlinkingCells=!0),!l&&x.isBlink()&&N.push("xterm-blink-hidden");let Pr=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{Pr=!0});let _i=x.getChars()||" ";if(_i===" "&&(x.isUnderline()||x.isOverline())&&(_i="\xA0"),Ot=Rr*h-d.get(_i,x.isBold(),x.isItalic()),!C)C=this._document.createElement("span");else if(w&&(Nt&&ui||!Nt&&!ui&&x.bg===te)&&(Nt&&ui&&f.selectionForeground||x.fg===Ds)&&x.extended.ext===Rs&&kr===Ls&&Ot===As&&!Ar&&!fi&&!Pr&&Ze){x.isInvisible()?L+=" ":L+=_i,w++;continue}else w&&(C.textContent=L),C=this._document.createElement("span"),w=0,L="";if(te=x.bg,Ds=x.fg,Rs=x.extended.ext,Ls=kr,As=Ot,ui=Nt,fi&&o>=ae&&o<=Lr&&(o=ae),!this._coreService.isCursorHidden&&Ar&&this._coreService.isCursorInitialized){if(N.push("xterm-cursor"),this._coreBrowserService.isFocused)a&&N.push("xterm-cursor-blink"),N.push(r==="bar"?"xterm-cursor-bar":r==="underline"?"xterm-cursor-underline":"xterm-cursor-block");else if(s)switch(s){case"outline":N.push("xterm-cursor-outline");break;case"block":N.push("xterm-cursor-block");break;case"bar":N.push("xterm-cursor-bar");break;case"underline":N.push("xterm-cursor-underline");break;default:break}}if(x.isBold()&&N.push("xterm-bold"),x.isItalic()&&N.push("xterm-italic"),x.isDim()&&N.push("xterm-dim"),x.isInvisible()?L=" ":L=x.getChars()||" ",x.isUnderline()&&(N.push(`xterm-underline-${x.extended.underlineStyle}`),L===" "&&(L="\xA0"),!x.isUnderlineColorDefault()))if(x.isUnderlineColorRGB())C.style.textDecorationColor=`rgb(${ue.toColorRGB(x.getUnderlineColor()).join(",")})`;else{let A=x.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&x.isBold()&&A<8&&(A+=8),C.style.textDecorationColor=f.ansi[A].css}x.isOverline()&&(N.push("xterm-overline"),L===" "&&(L="\xA0")),x.isStrikethrough()&&N.push("xterm-strikethrough"),kr&&(C.style.textDecoration="underline");let de=x.getFgColor(),Ft=x.getFgColorMode(),Se=x.getBgColor(),Ht=x.getBgColorMode(),Mr=!!x.isInverse();if(Mr){let A=de;de=Se,Se=A;let Br=Ft;Ft=Ht,Ht=Br}let Ae,pi,Wt=!1;this._decorationService.forEachDecorationAtCell(ae,e,void 0,A=>{A.options.layer!=="top"&&Wt||(A.backgroundColorRGB&&(Ht=50331648,Se=A.backgroundColorRGB.rgba>>8&16777215,Ae=A.backgroundColorRGB),A.foregroundColorRGB&&(Ft=50331648,de=A.foregroundColorRGB.rgba>>8&16777215,pi=A.foregroundColorRGB),Wt=A.options.layer==="top")}),!Wt&&Nt&&(Ae=this._coreBrowserService.isFocused?f.selectionBackgroundOpaque:f.selectionInactiveBackgroundOpaque,Se=Ae.rgba>>8&16777215,Ht=50331648,Wt=!0,f.selectionForeground&&(Ft=50331648,de=f.selectionForeground.rgba>>8&16777215,pi=f.selectionForeground)),Wt&&N.push("xterm-decoration-top");let ke;switch(Ht){case 16777216:case 33554432:ke=f.ansi[Se],N.push(`xterm-bg-${Se}`);break;case 50331648:ke=O.toColor(Se>>16,Se>>8&255,Se&255),this._addStyle(C,`background-color:#${(Se>>>0).toString(16).padStart(6,"0")}`);break;case 0:default:Mr?(ke=f.foreground,N.push(`xterm-bg-${257}`)):ke=f.background}switch(Ae||x.isDim()&&(Ae=k.multiplyOpacity(ke,.5)),Ft){case 16777216:case 33554432:x.isBold()&&de<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&(de+=8),this._applyMinimumContrast(C,ke,f.ansi[de],x,Ae,void 0)||N.push(`xterm-fg-${de}`);break;case 50331648:let A=O.toColor(de>>16&255,de>>8&255,de&255);this._applyMinimumContrast(C,ke,A,x,Ae,pi)||this._addStyle(C,`color:#${de.toString(16).padStart(6,"0")}`);break;case 0:default:this._applyMinimumContrast(C,ke,f.foreground,x,Ae,pi)||Mr&&N.push(`xterm-fg-${257}`)}N.length&&(C.className=N.join(" "),N.length=0),!Ar&&!fi&&!Pr&&Ze?w++:C.textContent=L,Ot!==this.defaultSpacing&&(C.style.letterSpacing=`${Ot}px`),p.push(C),ae=Lr}return C&&w&&(C.textContent=L),p}_applyMinimumContrast(i,e,t,r,s,o){if(this._optionsService.rawOptions.minimumContrastRatio===1||Zs(r.getCode()))return!1;let a=this._getContrastCache(r),l;if(!s&&!o&&(l=a.getColor(e.rgba,t.rgba)),l===void 0){let h=this._optionsService.rawOptions.minimumContrastRatio/(r.isDim()?2:1);l=k.ensureContrastRatio(s??e,o??t,h),a.setColor((s??e).rgba,(o??t).rgba,l??null)}return l?(this._addStyle(i,`color:${l.css}`),!0):!1}_getContrastCache(i){return i.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(i,e){i.setAttribute("style",`${i.getAttribute("style")||""}${e};`)}_isCellInSelection(i,e){let t=this._selectionStart,r=this._selectionEnd;return!t||!r?!1:this._columnSelectMode?t[0]<=r[0]?i>=t[0]&&e>=t[1]&&i=t[1]&&i>=r[0]&&e<=r[1]:e>t[1]&&e=t[0]&&i=t[0]}};_t=y([m(1,gi),m(2,R),m(3,G),m(4,Y),m(5,ge),m(6,_e)],_t);var Hi=class{constructor(i=()=>new rs){this._flat=new Float32Array(256);this._font="";this._fontSize=0;this._weight="normal";this._weightBold="bold";this._canvasElements=[];this._canvasElements=[i(),i(),i(),i()],this.clear()}dispose(){this._canvasElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(i,e,t,r){i===this._font&&e===this._fontSize&&t===this._weight&&r===this._weightBold||(this._font=i,this._fontSize=e,this._weight=t,this._weightBold=r,this._canvasElements[0].setFont(i,e,t,!1),this._canvasElements[1].setFont(i,e,r,!1),this._canvasElements[2].setFont(i,e,t,!0),this._canvasElements[3].setFont(i,e,r,!0),this.clear())}get(i,e,t){let r;if(!e&&!t&&i.length===1&&(r=i.charCodeAt(0))<256){if(this._flat[r]!==-9999)return this._flat[r];let a=this._measure(i,0);return a>0&&(this._flat[r]=a),a}let s=i;e&&(s+="B"),t&&(s+="I");let o=this._holey.get(s);if(o===void 0){let a=0;e&&(a|=1),t&&(a|=2),o=this._measure(i,a),o>0&&this._holey.set(s,o)}return o}_measure(i,e){return this._canvasElements[e].measure(i)}},rs=class{constructor(){typeof OffscreenCanvas<"u"?(this._canvas=new OffscreenCanvas(1,1),this._ctx=is(this._canvas.getContext("2d"))):(this._canvas=document.createElement("canvas"),this._canvas.width=1,this._canvas.height=1,this._ctx=is(this._canvas.getContext("2d")))}setFont(i,e,t,r){let s=r?"italic":"";this._ctx.font=`${s} ${t} ${e}px ${i}`.trim()}measure(i){return this._ctx.measureText(i).width}};var ss=class{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(i,e,t,r=!1){if(this.selectionStart=e,this.selectionEnd=t,!e||!t||e[0]===t[0]&&e[1]===t[1]){this.clear();return}let s=i.buffers.active.ydisp,o=e[1]-s,a=t[1]-s,l=Math.max(o,0),h=Math.min(a,i.rows-1);if(l>=i.rows||h<0){this.clear();return}this.hasSelection=!0,this.columnSelectMode=r,this.viewportStartRow=o,this.viewportEndRow=a,this.viewportCappedStartRow=l,this.viewportCappedEndRow=h,this.startCol=e[0],this.endCol=t[0]}isCellSelected(i,e,t){return this.hasSelection?(t-=i.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?e>=this.startCol&&t>=this.viewportCappedStartRow&&e=this.viewportCappedStartRow&&e>=this.endCol&&t<=this.viewportCappedEndRow:t>this.viewportStartRow&&t=this.startCol&&e=this.startCol):!1}};function Qs(){return new ss}var Wi=class extends g{constructor(e,t,r){super();this._renderCallback=e;this._coreBrowserService=t;this._optionsService=r;this._intervalDuration=0;this._blinkOn=!0;this._needsBlinkInViewport=!1;this._isViewportVisible=!0;this._register(this._optionsService.onSpecificOptionChange("blinkIntervalDuration",s=>{this.setIntervalDuration(s)})),this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration),this._register(E(()=>this._clearInterval()))}get isBlinkOn(){return this._blinkOn}get isEnabled(){return this._intervalDuration>0}setNeedsBlinkInViewport(e){this._needsBlinkInViewport!==e&&(this._needsBlinkInViewport=e,this._updateIntervalState())}setViewportVisible(e){this._isViewportVisible!==e&&(this._isViewportVisible=e,this._updateIntervalState())}setIntervalDuration(e){e!==this._intervalDuration&&(this._intervalDuration=e,this._clearInterval(),this._updateIntervalState())}_updateIntervalState(){if(this._intervalDuration>0&&this._needsBlinkInViewport&&this._isViewportVisible){if(this._interval!==void 0)return;let t=this._blinkOn;this._blinkOn=!0,this._interval=this._coreBrowserService.window.setInterval(()=>{this._blinkOn=!this._blinkOn,this._renderCallback()},this._intervalDuration),t||this._renderCallback();return}this._clearInterval(),this._blinkOn||(this._blinkOn=!0,this._renderCallback())}_clearInterval(){this._interval!==void 0&&(this._coreBrowserService.window.clearInterval(this._interval),this._interval=void 0)}};var eo=1,mt=class extends g{constructor(e,t,r,s,o,a,l,h,d,c,u,_,p,v){super();this._terminal=e;this._document=t;this._element=r;this._screenElement=s;this._viewportElement=o;this._helperContainer=a;this._linkifier2=l;this._charSizeService=d;this._optionsService=c;this._bufferService=u;this._coreService=_;this._coreBrowserService=p;this._themeService=v;this._terminalClass=eo++;this._rowElements=[];this._selectionRenderModel=Qs();this._lastSelectionColumnMode=!1;this._rowHasBlinkingCells=[];this._rowHasBlinkingCellsCount=0;this._onRequestRedraw=this._register(new b);this.onRequestRedraw=this._onRequestRedraw.event;this._rowContainer=this._document.createElement("div"),this._rowContainer.classList.add("xterm-rows"),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement("div"),this._selectionContainer.classList.add("xterm-selection"),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=Js(),this._updateDimensions(),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._themeService.onChangeColors(f=>this._injectCss(f))),this._injectCss(this._themeService.colors),this._rowFactory=h.createInstance(_t,document),this._element.classList.add("xterm-dom-renderer-owner-"+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline(f=>this._handleLinkHover(f))),this._register(this._linkifier2.onHideLinkUnderline(f=>this._handleLinkLeave(f))),this._cursorBlinkStateManager=new ns(this._rowContainer,this._coreBrowserService),this._register(I(this._document,"mousedown",()=>this._cursorBlinkStateManager.restartBlinkAnimation())),this._register(E(()=>this._cursorBlinkStateManager.dispose())),this._textBlinkStateManager=this._register(new Wi(()=>this._onRequestRedraw.fire({start:0,end:this._bufferService.rows-1}),this._coreBrowserService,this._optionsService)),this._register(E(()=>{this._element.classList.remove("xterm-dom-renderer-owner-"+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()})),this._widthCache=new Hi,this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){let e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(let r of this._rowElements)r.style.width=`${this.dimensions.css.canvas.width}px`,r.style.height=`${this.dimensions.css.cell.height}px`,r.style.lineHeight=`${this.dimensions.css.cell.height}px`,r.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));let t=`${this._terminalSelector} .xterm-rows span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .xterm-rows { pointer-events: none; color: ${e.foreground.css};}`;t+=`${this._terminalSelector} .xterm-rows, ${this._terminalSelector} .xterm-rows span { font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`,t+=`${this._terminalSelector} .xterm-rows .xterm-dim { color: ${k.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}${this._terminalSelector} span.xterm-blink-hidden { visibility: hidden;}`;let r=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,o=`blink_block_${this._terminalClass}`;t+=`@keyframes ${r} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${o} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-focus .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${o} 1s step-end infinite;}${this._terminalSelector} .xterm-rows.xterm-cursor-blink-idle .xterm-cursor.xterm-cursor-blink { animation: none !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .xterm-rows .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .xterm-selection { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .xterm-selection div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .xterm-selection div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(let[a,l]of e.ansi.entries())t+=`${this._terminalSelector} .xterm-fg-${a} { color: ${l.css}; }${this._terminalSelector} .xterm-fg-${a}.xterm-dim { color: ${k.multiplyOpacity(l,.5).css}; }${this._terminalSelector} .xterm-bg-${a} { background-color: ${l.css}; }`;t+=`${this._terminalSelector} .xterm-fg-${257} { color: ${k.opaque(e.background).css}; }${this._terminalSelector} .xterm-fg-${257}.xterm-dim { color: ${k.multiplyOpacity(k.opaque(e.background),.5).css}; }${this._terminalSelector} .xterm-bg-${257} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){let e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let r=this._rowElements.length;r<=t;r++){let s=this._document.createElement("div");this._rowContainer.appendChild(s),this._rowElements.push(s),this._rowHasBlinkingCells.push(!1)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop()),this._rowHasBlinkingCells.pop()&&this._rowHasBlinkingCellsCount--}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove("xterm-focus"),this._cursorBlinkStateManager.pause(),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add("xterm-focus"),this._cursorBlinkStateManager.resume(),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleViewportVisibilityChange(e){this._textBlinkStateManager.setViewportVisible(e)}handleSelectionChanged(e,t,r){let s=this._bufferService.rows;this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,r);let o=0,a=-1;this._lastSelectionStart&&this._lastSelectionEnd&&(this._selectionRenderModel.update(this._terminal,this._lastSelectionStart,this._lastSelectionEnd,this._lastSelectionColumnMode),this._selectionRenderModel.hasSelection&&(o=this._selectionRenderModel.viewportCappedStartRow,a=this._selectionRenderModel.viewportCappedEndRow));let l=0,h=-1;if(!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,r),this._selectionRenderModel.hasSelection){let u=this._selectionRenderModel.viewportStartRow,_=this._selectionRenderModel.viewportEndRow,p=this._selectionRenderModel.viewportCappedStartRow,v=this._selectionRenderModel.viewportCappedEndRow;l=p,h=v;let f=this._document.createDocumentFragment();if(r){let S=e[0]>t[0];f.appendChild(this._createSelectionElement(p,S?t[0]:e[0],S?e[0]:t[0],v-p+1))}else{let S=u===p?e[0]:0,C=p===_?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(p,S,C));let w=v-p-1;if(f.appendChild(this._createSelectionElement(p+1,0,this._bufferService.cols,w)),p!==v){let L=_===v?t[0]:this._bufferService.cols;f.appendChild(this._createSelectionElement(v,0,L))}}this._selectionContainer.appendChild(f)}let d=Math.min(o,l),c=Math.max(a,h);if(c>=0){d=Math.max(d,0),c=Math.min(c,s-1);let _=this._bufferService.buffer.y;this._selectionRenderModel.hasSelection&&_>=0&&_this.dimensions.css.canvas.width&&(l=this.dimensions.css.canvas.width-a),o.style.height=`${s*this.dimensions.css.cell.height}px`,o.style.top=`${e*this.dimensions.css.cell.height}px`,o.style.left=`${a}px`,o.style.width=`${l}px`,o}handleCursorMove(){this._cursorBlinkStateManager.restartBlinkAnimation()}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(let e of this._rowElements)e.replaceChildren();this._rowHasBlinkingCellsCount>0&&(this._rowHasBlinkingCells.fill(!1),this._rowHasBlinkingCellsCount=0,this._textBlinkStateManager.setNeedsBlinkInViewport(!1))}renderRows(e,t){let r=this._bufferService.buffer,s=r.ybase+r.y,o=Math.min(r.x,this._bufferService.cols-1),a=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,l=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,h=this._optionsService.rawOptions.cursorInactiveStyle,d={hasBlinkingCells:!1};for(let c=e;c<=t;c++){let u=c+r.ydisp,_=this._rowElements[c];if(!_)continue;let p=r.lines.get(u);if(!p){_.replaceChildren(),this._setRowBlinkState(c,!1);continue}_.replaceChildren(...this._rowFactory.createRow(p,u,u===s,l,h,o,a,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,-1,-1,d)),this._setRowBlinkState(c,d.hasBlinkingCells)}this._updateTextBlinkState()}get _terminalSelector(){return`.xterm-dom-renderer-owner-${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,r,s,o,a){r<0&&(e=0),s<0&&(t=0);let l=this._bufferService.rows-1;r=Math.max(Math.min(r,l),0),s=Math.max(Math.min(s,l),0),o=Math.min(o,this._bufferService.cols);let h=this._bufferService.buffer,d=h.ybase+h.y,c=Math.min(h.x,o-1),u=this._optionsService.rawOptions.cursorBlink,_=this._optionsService.rawOptions.cursorStyle,p=this._optionsService.rawOptions.cursorInactiveStyle,v={hasBlinkingCells:!1};for(let f=r;f<=s;++f){let S=f+h.ydisp,C=this._rowElements[f];if(!C)continue;let w=h.lines.get(S);if(!w){C.replaceChildren(),this._setRowBlinkState(f,!1);continue}C.replaceChildren(...this._rowFactory.createRow(w,S,S===d,_,p,c,u,this._textBlinkStateManager.isBlinkOn,this.dimensions.css.cell.width,this._widthCache,a?f===r?e:0:-1,a?(f===s?t:o)-1:-1,v)),this._setRowBlinkState(f,v.hasBlinkingCells)}this._updateTextBlinkState()}_setRowBlinkState(e,t){this._rowHasBlinkingCells[e]!==t&&(this._rowHasBlinkingCells[e]=t,this._rowHasBlinkingCellsCount+=t?1:-1)}_updateTextBlinkState(){this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount>0)}};mt=y([m(7,et),m(8,Be),m(9,R),m(10,D),m(11,Y),m(12,G),m(13,_e)],mt);var ns=class{constructor(i,e){this._rowContainer=i;this._coreBrowserService=e;this._isIdlePaused=!1;this._coreBrowserService.isFocused&&this._resetIdleTimer()}dispose(){this._clearIdleTimer()}restartBlinkAnimation(){this._isIdlePaused&&this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}pause(){this._isIdlePaused=!1,this._clearIdleTimer()}resume(){this._isIdlePaused=!1,this._rowContainer.classList.remove("xterm-cursor-blink-idle"),this._resetIdleTimer()}_resetIdleTimer(){this._isIdlePaused=!1,this._clearIdleTimer(),this._idleTimeout=this._coreBrowserService.window.setTimeout(()=>{this._stopBlinkingDueToIdle()},3e5)}_clearIdleTimer(){this._idleTimeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._idleTimeout),this._idleTimeout=void 0)}_stopBlinkingDueToIdle(){this._rowContainer.classList.add("xterm-cursor-blink-idle"),this._isIdlePaused=!0,this._idleTimeout=void 0}};var bt=class extends g{constructor(e,t,r){super();this._optionsService=r;this.width=0;this.height=0;this._onCharSizeChange=this._register(new b);this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new as(this._optionsService))}catch{this._measureStrategy=this._register(new os(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],()=>this.measure()))}get hasValidSize(){return this.width>0&&this.height>0}measure(){let e=this._measureStrategy.measure();(e.width!==this.width||e.height!==this.height)&&(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};bt=y([m(2,R)],bt);var Ui=class extends g{constructor(){super(...arguments);this._result={width:0,height:0}}_validateAndSet(e,t){e!==void 0&&e>0&&t!==void 0&&t>0&&(this._result.width=e,this._result.height=t)}},os=class extends Ui{constructor(e,t,r){super();this._document=e;this._parentElement=t;this._optionsService=r;this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}},as=class extends Ui{constructor(e){super();this._optionsService=e;this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext("2d");let t=this._ctx.measureText("W");if(!("width"in t&&"fontBoundingBoxAscent"in t&&"fontBoundingBoxDescent"in t))throw new Error("Required font metrics not supported")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;let e=this._ctx.measureText("W");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}};var Ki=class extends g{constructor(e,t,r){super();this._textarea=e;this._window=t;this.mainDocument=r;this._isFocused=!1;this._cachedIsFocused=void 0;this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._onWindowChange=this._register(new b);this.onWindowChange=this._onWindowChange.event;this._screenDprMonitor=this._register(new ls(this._window)),this._register(this.onWindowChange(s=>this._screenDprMonitor.setWindow(s))),this._register(j.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register(I(this._textarea,"focus",()=>this._isFocused=!0)),this._register(I(this._textarea,"blur",()=>this._isFocused=!1))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return this._cachedIsFocused===void 0&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask(()=>this._cachedIsFocused=void 0)),this._cachedIsFocused}},ls=class extends g{constructor(e){super();this._parentWindow=e;this._windowResizeListener=this._register(new B);this._onDprChange=this._register(new b);this.onDprChange=this._onDprChange.event;this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register(E(()=>this.clearListener()))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=I(this._parentWindow,"resize",()=>this._setDprAndFireIfDiffers())}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){!this._resolutionMediaMatchList||!this._outerListener||(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}};var zi=class extends g{constructor(){super();this.linkProviders=[];this._register(E(()=>this.linkProviders.length=0))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{let t=this.linkProviders.indexOf(e);t!==-1&&this.linkProviders.splice(t,1)}}}};function qt(n,i,e){let t=e.getBoundingClientRect(),r=n.getComputedStyle(e),s=parseInt(r.getPropertyValue("padding-left"),10),o=parseInt(r.getPropertyValue("padding-top"),10);return[i.clientX-t.left-s,i.clientY-t.top-o]}function en(n,i,e,t,r,s,o,a,l){if(!s)return;let h=qt(n,i,e);return h[0]=Math.ceil((h[0]+(l?o/2:0))/o),h[1]=Math.ceil(h[1]/a),h[0]=Math.min(Math.max(h[0],1),t+(l?1:0)),h[1]=Math.min(Math.max(h[1],1),r),h}var vt=class{constructor(i,e){this._charSizeService=i;this._renderService=e}getCoords(i,e,t,r,s){return en(se(e),i,e,t,r,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,s)}getMouseReportCoords(i,e){let t=qt(se(e),i,e);if(this._charSizeService.hasValidSize)return t[0]=Math.min(Math.max(t[0],0),this._renderService.dimensions.css.canvas.width-1),t[1]=Math.min(Math.max(t[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(t[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(t[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(t[0]),y:Math.floor(t[1])}}};vt=y([m(0,Be),m(1,V)],vt);var tn=typeof window=="object"?window:globalThis;function ce(n,i=0){return n[n.length-(1+i)]}function to(n,i,e){let t=null,r=null;if(typeof e.value=="function"?(t="value",r=e.value,r.length!==0&&console.warn("Memoize should only be used in functions with zero parameters")):typeof e.get=="function"&&(t="get",r=e.get),!r||!t)throw new Error("not supported");let s=`$memoize$${i}`,o=e;o[t]=function(...a){return this.hasOwnProperty(s)||Object.defineProperty(this,s,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,a)}),this[s]}}var St=class St{constructor(i){this.element=i,this.next=St.Undefined,this.prev=St.Undefined}};St.Undefined=new St(void 0);var re=St,Gi=class{constructor(){this._first=re.Undefined;this._last=re.Undefined}push(i){return this._insert(i,!0)}_insert(i,e){let t=new re(i);if(this._first===re.Undefined)this._first=t,this._last=t;else if(e){let s=this._last;this._last=t,t.prev=s,s.next=t}else{let s=this._first;this._first=t,t.next=s,s.prev=t}let r=!1;return()=>{r||(r=!0,this._remove(t))}}_remove(i){if(i.prev!==re.Undefined&&i.next!==re.Undefined){let e=i.prev;e.next=i.next,i.next.prev=e}else i.prev===re.Undefined&&i.next===re.Undefined?(this._first=re.Undefined,this._last=re.Undefined):i.next===re.Undefined?(this._last=this._last.prev,this._last.next=re.Undefined):i.prev===re.Undefined&&(this._first=this._first.next,this._first.prev=re.Undefined)}*[Symbol.iterator](){let i=this._first;for(;i!==re.Undefined;)yield i.element,i=i.next}},he;(s=>(s.TAP="-xterm-gesturetap",s.CHANGE="-xterm-gesturechange",s.START="-xterm-gesturestart",s.END="-xterm-gesturesend",s.CONTEXT_MENU="-xterm-gesturecontextmenu"))(he||={});var K=class K extends g{constructor(){super();this._dispatched=!1;this._targets=new Gi;this._ignoreTargets=new Gi;this._activeTouches={},this._handle=null,this._lastSetTapCountTime=0;let e=tn;this._register(I(e.document,"touchstart",t=>this._handleTouchStart(t),{passive:!1})),this._register(I(e.document,"touchend",t=>this._handleTouchEnd(e,t))),this._register(I(e.document,"touchmove",t=>this._handleTouchMove(t),{passive:!1}))}static addTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._targets.push(e);return E(t)}static ignoreTarget(e){if(!K.isTouchDevice())return g.None;K._instance||(K._instance=new K);let t=K._instance._ignoreTargets.push(e);return E(t)}static isTouchDevice(){return"ontouchstart"in tn||navigator.maxTouchPoints>0}dispose(){this._handle&&(this._handle.dispose(),this._handle=null),super.dispose()}_handleTouchStart(e){let t=Date.now();this._handle&&(this._handle.dispose(),this._handle=null);for(let r=0,s=e.targetTouches.length;r=K._holdDelay&&Math.abs(h.initialPageX-ce(h.rollingPageX))<30&&Math.abs(h.initialPageY-ce(h.rollingPageY))<30){let c=this._newGestureEvent(he.CONTEXT_MENU,h.initialTarget);c.pageX=ce(h.rollingPageX),c.pageY=ce(h.rollingPageY),this._dispatchEvent(c)}else if(s===1){let c=ce(h.rollingPageX),u=ce(h.rollingPageY),_=ce(h.rollingTimestamps)-h.rollingTimestamps[0],p=c-h.rollingPageX[0],v=u-h.rollingPageY[0],f=[...this._targets].filter(S=>h.initialTarget instanceof Node&&S.contains(h.initialTarget));this._inertia(e,f,r,Math.abs(p)/_,p>0?1:-1,c,Math.abs(v)/_,v>0?1:-1,u)}this._dispatchEvent(this._newGestureEvent(he.END,h.initialTarget)),delete this._activeTouches[l.identifier]}this._dispatched&&(t.preventDefault(),t.stopPropagation(),this._dispatched=!1)}_newGestureEvent(e,t){let r=document.createEvent("CustomEvent");return r.initEvent(e,!1,!0),r.initialTarget=t,r.tapCount=0,r}_dispatchEvent(e){if(e.type===he.TAP){let t=new Date().getTime(),r;t-this._lastSetTapCountTime>K._clearTapCountTime?r=1:r=2,this._lastSetTapCountTime=t,e.tapCount=r}else(e.type===he.CHANGE||e.type===he.CONTEXT_MENU)&&(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(let r of this._ignoreTargets)if(r.contains(e.initialTarget))return;let t=[];for(let r of this._targets)if(r.contains(e.initialTarget)){let s=0,o=e.initialTarget;for(;o&&o!==r;)s++,o=o.parentElement;t.push([s,r])}t.sort((r,s)=>r[0]-s[0]);for(let[,r]of t)r.dispatchEvent(e),this._dispatched=!0}}_inertia(e,t,r,s,o,a,l,h,d){this._handle=it(e,()=>{let c=Date.now(),u=c-r,_=0,p=0,v=!0;s+=K._scrollFriction*u,l+=K._scrollFriction*u,s>0&&(v=!1,_=o*s*u),l>0&&(v=!1,p=h*l*u);let f=this._newGestureEvent(he.CHANGE);f.translationX=_,f.translationY=p,t.forEach(S=>S.dispatchEvent(f)),v||this._inertia(e,t,c,s,o,a+_,l,h,d+p)})}_handleTouchMove(e){let t=Date.now();for(let r=0,s=e.changedTouches.length;r3&&(a.rollingPageX.shift(),a.rollingPageY.shift(),a.rollingTimestamps.shift()),a.rollingPageX.push(o.pageX),a.rollingPageY.push(o.pageY),a.rollingTimestamps.push(t)}this._dispatched&&(e.preventDefault(),e.stopPropagation(),this._dispatched=!1)}};K._scrollFriction=-.005,K._holdDelay=700,K._clearTapCountTime=400,y([to],K,"isTouchDevice",1);var Vi=K;var gt=class{constructor(i,e,t,r,s,o,a,l,h){this._renderService=i;this._mouseCoordsService=e;this._mouseStateService=t;this._coreService=r;this._bufferService=s;this._optionsService=o;this._selectionService=a;this._logService=l;this._coreBrowserService=h;this._lastEvent=null;this._wheelPartialScroll=0;this._touchScrollAccumulator=0}bindMouse(i,e,t){let{element:r,document:s}=i,o={mouseup:null,wheel:null,mousedrag:null,mousemove:null},a={target:i,focus:t,requestedEvents:o},l={mouseup:h=>this._handleMouseUp(a,h),wheel:h=>this._handleWheel(a,h),mousedrag:h=>this._handleMouseDrag(a,h),mousemove:h=>this._handleMouseMove(a,h)};this._altMouseCursor=new cs(r,s,()=>this._mouseStateService.areMouseEventsActive&&!!this._optionsService.rawOptions.mouseEventsRequireAlt),e(this._altMouseCursor),e(this._mouseStateService.onProtocolChange(h=>{this._handleProtocolChange(a,l,h)})),e(this._optionsService.onSpecificOptionChange("mouseEventsRequireAlt",()=>{this._syncMouseModeState(r),this._altMouseCursor?.sync()})),this._mouseStateService.activeProtocol=this._mouseStateService.activeProtocol,e(E(()=>{o.mouseup&&s.removeEventListener("mouseup",o.mouseup),o.mousedrag&&s.removeEventListener("mousemove",o.mousedrag)})),e(I(r,"mousedown",h=>this._handleMouseDown(a,h))),e(I(r,"wheel",h=>this._handlePassiveWheel(a,h),{passive:!1})),e(Vi.addTarget(i.screenElement)),e(I(i.screenElement,he.START,()=>this._handleTouchStart())),e(I(i.screenElement,he.CHANGE,h=>this._handleTouchChange(a,h)))}_sendEvent(i,e){let t=this._mouseCoordsService.getMouseReportCoords(e,i.target.screenElement);if(!t)return!1;let r,s;switch(e.overrideType||e.type){case"mousemove":s=32,e.buttons===void 0?(r=3,e.button!==void 0&&(r=e.button<3?e.button:3)):r=e.buttons&1?0:e.buttons&4?1:e.buttons&2?2:3;break;case"mouseup":s=0,r=e.button<3?e.button:3;break;case"mousedown":s=1,r=e.button<3?e.button:3;break;case"wheel":if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;let a=e.deltaY;if(a===0||this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return!1;s=a<0?0:1,r=4;break;default:return!1}if(s===void 0||r===void 0||r>4||r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&!e.altKey)return!1;let o=r!==4&&this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive;return this._triggerMouseEvent({col:t.col,row:t.row,x:t.x,y:t.y,button:r,action:s,ctrl:e.ctrlKey,alt:o?!1:e.altKey,shift:e.shiftKey})}_handleMouseUp(i,e){this._sendEvent(i,e),e.buttons||(i.requestedEvents.mouseup&&i.target.document.removeEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.removeEventListener("mousemove",i.requestedEvents.mousedrag))}_handleWheel(i,e){return this._sendEvent(i,e),e.preventDefault(),e.stopPropagation(),!1}_handleMouseDrag(i,e){e.buttons&&this._sendEvent(i,e)}_handleMouseMove(i,e){e.buttons||this._sendEvent(i,e)}_handleMouseDown(i,e){e.preventDefault(),i.focus(),!(!this._mouseStateService.areMouseEventsActive||this._selectionService.shouldForceSelection(e))&&(this._sendEvent(i,e),i.requestedEvents.mouseup&&i.target.document.addEventListener("mouseup",i.requestedEvents.mouseup),i.requestedEvents.mousedrag&&i.target.document.addEventListener("mousemove",i.requestedEvents.mousedrag))}_handlePassiveWheel(i,e){if(!i.requestedEvents.wheel){if(!this._mouseStateService.allowCustomWheelEvent(e))return!1;if(!this._bufferService.buffer.hasScrollback){if(e.deltaY===0)return!1;if(this._consumeWheelEvent(e,this._renderService?.dimensions?.device?.cell?.height,this._coreBrowserService?.dpr)===0)return e.preventDefault(),e.stopPropagation(),!1;let s="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(e.deltaY<0?"A":"B");return this._coreService.triggerDataEvent(s,!0),e.preventDefault(),e.stopPropagation(),!1}}}_handleTouchStart(){this._touchScrollAccumulator=0}_handleTouchChange(i,e){if(e.preventDefault(),e.stopPropagation(),i.requestedEvents.wheel){this._handleTouchScrollAsWheel(i,e);return}if(!this._bufferService.buffer.hasScrollback){this._handleTouchScrollAsKeys(e);return}i.target.handleTouchScroll?.(e.translationY)}_handleTouchScrollAsKeys(i){let e=this._renderService?.dimensions.css.cell.height;if(!e)return;this._touchScrollAccumulator-=i.translationY;let t=Math.trunc(this._touchScrollAccumulator/e);if(t===0)return;this._touchScrollAccumulator-=t*e;let r="\x1B"+(this._coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(t<0?"A":"B");for(let s=0;s0?1:-1),this._wheelPartialScroll%=1):i.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(s*=this._bufferService.rows),s}_triggerMouseEvent(i){if(i.col<0||i.col>=this._bufferService.cols||i.row<0||i.row>=this._bufferService.rows||i.button===4&&i.action===32||i.button===3&&i.action!==32||i.button!==4&&(i.action===2||i.action===3)||(i.col++,i.row++,i.action===32&&this._lastEvent&&this._equalEvents(this._lastEvent,i,this._mouseStateService.isPixelEncoding))||!this._mouseStateService.restrictMouseEvent(i))return!1;let e=this._mouseStateService.encodeMouseEvent(i);return e&&(this._mouseStateService.isDefaultEncoding?this._coreService.triggerBinaryEvent(e):this._coreService.triggerDataEvent(e,!0)),this._lastEvent=i,!0}_explainEvents(i){return{down:!!(i&1),up:!!(i&2),drag:!!(i&4),move:!!(i&8),wheel:!!(i&16)}}_equalEvents(i,e,t){if(t){if(i.x!==e.x||i.y!==e.y)return!1}else if(i.col!==e.col||i.row!==e.row)return!1;return!(i.button!==e.button||i.action!==e.action||i.ctrl!==e.ctrl||i.alt!==e.alt||i.shift!==e.shift)}};gt=y([m(0,V),m(1,Oe),m(2,Me),m(3,Y),m(4,D),m(5,R),m(6,Si),m(7,fe),m(8,G)],gt);var cs=class{constructor(i,e,t){this._element=i;this._document=e;this._isActive=t;this._listeners=new B}dispose(){this._listeners.dispose()}sync(){if(this._listeners.clear(),!this._isActive())return;let i=new pe,e=r=>this.syncFromModifier(r);i.add(I(this._document,"keydown",e)),i.add(I(this._document,"keyup",e)),i.add(I(this._element,"mousemove",e));let t=this._element.ownerDocument?.defaultView;t&&i.add(I(t,"blur",()=>{this._isActive()&&this.resetClass()})),this._listeners.value=i}resetClass(){this._updateClass(!1)}syncFromModifier(i){this._isActive()&&this._updateClass(i.getModifierState("Alt"))}_updateClass(i){i?this._element.classList.add("enable-mouse-events"):this._element.classList.remove("enable-mouse-events")}};var $i=class{constructor(i,e){this._renderCallback=i;this._coreBrowserService=e;this._refreshCallbacks=[]}dispose(){this._animationFrame!==void 0&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)}addRefreshCallback(i){return this._refreshCallbacks.push(i),this._animationFrame??=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()),this._animationFrame}refresh(i,e,t){this._rowCount=t,i=i??0,e=e??this._rowCount-1,this._rowStart=this._rowStart!==void 0?Math.min(this._rowStart,i):i,this._rowEnd=this._rowEnd!==void 0?Math.max(this._rowEnd,e):e,this._animationFrame===void 0&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._innerRefresh()))}_innerRefresh(){if(this._animationFrame=void 0,this._rowStart===void 0||this._rowEnd===void 0||this._rowCount===void 0){this._runRefreshCallbacks();return}let i=Math.max(this._rowStart,0),e=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(i,e),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(let i of this._refreshCallbacks)i(0);this._refreshCallbacks=[]}};var qi=class{constructor(i){this._tasks=[];this._i=0;this._logService=i}enqueue(i){this._tasks.push(i),this._start()}flush(){for(;this._is){r-e<-20&&this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(r-e))}ms`),this._start();return}r=s}this.clear()}},hs=class extends qi{_requestCallback(i){return setTimeout(()=>i(this._createDeadline(16)))}_cancelCallback(i){clearTimeout(i)}_createDeadline(i){let e=performance.now()+i;return{timeRemaining:()=>Math.max(0,e-performance.now())}}},ds=class extends qi{_requestCallback(i){return requestIdleCallback(i)}_cancelCallback(i){cancelIdleCallback(i)}},Ct="requestIdleCallback"in globalThis?ds:hs,Xi=class{constructor(i){this._queue=new Ct(i)}set(i){this._queue.clear(),this._queue.enqueue(i)}flush(){this._queue.flush()}dispose(){this._queue.clear()}};var It=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._rowCount=e;this._optionsService=r;this._logService=s;this._charSizeService=o;this._coreService=a;this._coreBrowserService=d;this._renderer=this._register(new B);this._observerDisposable=this._register(new B);this._isPaused=!1;this._needsFullRefresh=!1;this._isNextRenderRedrawOnly=!0;this._needsSelectionRefresh=!1;this._canvasWidth=0;this._canvasHeight=0;this._selectionState={start:void 0,end:void 0,columnSelectMode:!1};this._onDimensionsChange=this._register(new b);this.onDimensionsChange=this._onDimensionsChange.event;this._onRenderedViewportChange=this._register(new b);this.onRenderedViewportChange=this._onRenderedViewportChange.event;this._onRender=this._register(new b);this.onRender=this._onRender.event;this._onRefreshRequest=this._register(new b);this.onRefreshRequest=this._onRefreshRequest.event;this._pausedResizeTask=this._register(new Xi(this._logService)),this._renderDebouncer=new $i((u,_)=>this._renderRows(u,_),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new us(this._coreBrowserService,this._coreService,()=>this._fullRefresh()),this._register(E(()=>this._syncOutputHandler.dispose())),this._register(this._coreBrowserService.onDprChange(()=>this.handleDevicePixelRatioChange())),this._register(h.onResize(()=>this._fullRefresh())),this._register(h.buffers.onBufferActivate(()=>this._renderer.value?.clear())),this._register(this._optionsService.onOptionChange(()=>this._handleOptionsChanged())),this._register(this._charSizeService.onCharSizeChange(()=>this.handleCharSizeChanged())),this._register(l.onDecorationRegistered(()=>this._fullRefresh())),this._register(l.onDecorationRemoved(()=>this._fullRefresh())),this._register(this._optionsService.onMultipleOptionChange(["drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio","rescaleOverlappingGlyphs"],()=>{this.clear(),this.handleResize(h.cols,h.rows),this._fullRefresh()})),this._register(this._optionsService.onMultipleOptionChange(["cursorBlink","cursorStyle"],()=>this.refreshRows(h.buffer.y,h.buffer.y,void 0,!0))),this._register(c.onChangeColors(()=>this._fullRefresh())),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange(u=>this._registerIntersectionObserver(u,t)))}get dimensions(){return this._renderer.value.dimensions}_registerIntersectionObserver(e,t){if("IntersectionObserver"in e){let r=new e.IntersectionObserver(s=>this._handleIntersectionChange(s[s.length-1]),{threshold:0});this._observerDisposable.value=E(()=>{this._intersectionObserver?.disconnect(),this._intersectionObserver=void 0}),this._intersectionObserver=r,r.observe(t)}}_handleIntersectionChange(e){this._isPaused=e.isIntersecting===void 0?e.intersectionRatio===0:!e.isIntersecting,this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused),!this._isPaused&&!this._charSizeService.hasValidSize&&this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,r=!1,s=!1){if(this._isPaused){this._needsFullRefresh=!0;return}if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}let o=this._syncOutputHandler.flush();o&&(e=Math.min(e,o.start),t=Math.max(t,o.end)),s||(this._isNextRenderRedrawOnly=!1),r?this._renderRows(e,t):this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){if(this._renderer.value){if(this._coreService.decPrivateModes.synchronizedOutput){this._syncOutputHandler.bufferRows(e,t);return}e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0}}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw(t=>this.refreshRows(t.start,t.end,t.sync,!0)),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set(()=>this._renderer.value?.handleResize(e,t)):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,r){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=r,this._renderer.value?.handleSelectionChanged(e,t,r)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};It=y([m(2,R),m(3,fe),m(4,Be),m(5,Y),m(6,ge),m(7,D),m(8,G),m(9,_e)],It);var us=class{constructor(i,e,t){this._coreBrowserService=i;this._coreService=e;this._onTimeout=t;this._start=0;this._end=0;this._isBuffering=!1}bufferRows(i,e){this._isBuffering?(this._start=Math.min(this._start,i),this._end=Math.max(this._end,e)):(this._start=i,this._end=e,this._isBuffering=!0),this._timeout??=this._coreBrowserService.window.setTimeout(()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()},1e3)}flush(){if(this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;let i={start:this._start,end:this._end};return this._isBuffering=!1,i}dispose(){this._timeout!==void 0&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}};function rn(n,i,e,t){let r=e.buffer.x,s=e.buffer.y;if(!e.buffer.hasScrollback)return oo(r,s,n,i,e,t)+Yi(s,i,e,t)+ao(r,s,n,i,e,t);let o;if(s===i)return o=r>n?"D":"C",Yt(Math.abs(r-n),Xt(o,t));o=s>i?"D":"C";let a=Math.abs(s-i),l=no(s>i?n:r,e)+(a-1)*e.cols+1+so(s>i?r:n,e);return Yt(l,Xt(o,t))}function so(n,i){return n-1}function no(n,i){return i.cols-n}function oo(n,i,e,t,r,s){return Yi(i,t,r,s).length===0?"":Yt(nn(n,i,n,i-qe(i,r),!1,r).length,Xt("D",s))}function Yi(n,i,e,t){let r=n-qe(n,e),s=i-qe(i,e),o=Math.abs(r-s)-lo(n,i,e);return Yt(o,Xt(sn(n,i),t))}function ao(n,i,e,t,r,s){let o;Yi(i,t,r,s).length>0?o=t-qe(t,r):o=i;let a=t,l=co(n,i,e,t,r,s);return Yt(nn(n,o,e,a,l==="C",r).length,Xt(l,s))}function lo(n,i,e){let t=0,r=n-qe(n,e),s=i-qe(i,e);for(let o=0;o=0&&n0?o=t-qe(t,r):o=i,n=e&&oi?"A":"B"}function nn(n,i,e,t,r,s){let o=n,a=i,l="";for(;(o!==e||a!==t)&&a>=0&&as.cols-1?(l+=s.buffer.translateBufferLineToString(a,!1,n,o),o=0,n=0,a++):!r&&o<0&&(l+=s.buffer.translateBufferLineToString(a,!1,0,n+1),o=s.cols-1,n=o,a--);return l+s.buffer.translateBufferLineToString(a,!1,n,o)}function Xt(n,i){let e=i?"O":"[";return"\x1B"+e+n}function Yt(n,i){n=Math.floor(n);let e="";for(let t=0;tthis._bufferService.cols?i%this._bufferService.cols===0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)-1]:[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[i,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){let i=this.selectionStart[0]+this.selectionStartLength;return i>this._bufferService.cols?[i%this._bufferService.cols,this.selectionStart[1]+Math.floor(i/this._bufferService.cols)]:[Math.max(i,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){let i=this.selectionStart,e=this.selectionEnd;return!i||!e?!1:i[1]>e[1]||i[1]===e[1]&&i[0]>e[0]}handleTrim(i){return this.selectionStart&&(this.selectionStart[1]-=i),this.selectionEnd&&(this.selectionEnd[1]-=i),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):this.selectionStart&&this.selectionStart[1]<0?(this.selectionStart=[0,0],!0):!1}};function fs(n,i){if(n.start.y>n.end.y)throw new Error(`Buffer range end (${n.end.x}, ${n.end.y}) cannot be before start (${n.start.x}, ${n.start.y})`);return i*(n.end.y-n.start.y)+(n.end.x-n.start.x+1)}var ho="\xA0",uo=new RegExp(ho,"g");var Et=class extends g{constructor(e,t,r,s,o,a,l,h,d,c){super();this._element=e;this._screenElement=t;this._linkifier=r;this._bufferService=s;this._coreService=o;this._mouseCoordsService=a;this._optionsService=l;this._mouseStateService=h;this._renderService=d;this._coreBrowserService=c;this._dragScrollAmount=0;this._enabled=!0;this._trimListener=this._register(new B);this._workCell=new F;this._mouseDownTimeStamp=0;this._oldHasSelection=!1;this._oldSelectionStart=void 0;this._oldSelectionEnd=void 0;this._onLinuxMouseSelection=this._register(new b);this.onLinuxMouseSelection=this._onLinuxMouseSelection.event;this._onRedrawRequest=this._register(new b);this.onRequestRedraw=this._onRedrawRequest.event;this._onSelectionChange=this._register(new b);this.onSelectionChange=this._onSelectionChange.event;this._onRequestScrollLines=this._register(new b);this.onRequestScrollLines=this._onRequestScrollLines.event;this._mouseMoveListener=u=>this._handleMouseMove(u),this._mouseUpListener=u=>this._handleMouseUp(u),this._coreService.onUserInput(()=>{this.hasSelection&&this.clearSelection()}),this._trimListener.value=this._bufferService.buffer.lines.onTrim(u=>this._handleTrim(u)),this._register(this._bufferService.buffers.onBufferActivate(u=>this._handleBufferActivate(u))),this.enable(),this._model=new ji(this._bufferService),this._activeSelectionMode=0,this._register(E(()=>{this._removeMouseDownListeners()})),this._register(this._bufferService.onResize(u=>{u.rowsChanged&&this.clearSelection()}))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!e||!t?!1:e[0]!==t[0]||e[1]!==t[1]}get selectionText(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";let r=this._bufferService.buffer,s=[];if(this._activeSelectionMode===3){if(e[0]===t[0])return"";let a=e[0]a.replace(uo," ")).join(Ke?`\r `:` -`)}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame(()=>this._refresh())),zt&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:this._activeSelectionMode===3})}_isClickInSelection(e){let t=this._getMouseBufferCoords(e),r=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!r||!s||!t?!1:this._areCoordsInSelection(t,r,s)}isCellInSelection(e,t){let r=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!r||!s?!1:this._areCoordsInSelection([e,t],r,s)}_areCoordsInSelection(e,t,r){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){let r=this._linkifier.currentLink?.link?.range;if(r)return this._model.selectionStart=[r.start.x-1,r.start.y-1],this._model.selectionStartLength=fs(r,this._bufferService.cols),this._model.selectionEnd=void 0,!0;let s=this._getMouseBufferCoords(e);return s?(this._selectWordAt(s,t),this._model.selectionEnd=void 0,!0):!1}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){let t=this._mouseCoordsService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=qt(this._coreBrowserService.window,e,this._screenElement)[1],r=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=r?0:(t>r&&(t-=r),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(t*14))}shouldForceSelection(e){return this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive?!e.altKey:ie?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,!(e.button===2&&this.hasSelection)&&e.button===0&&!(this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive&&e.altKey)){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):e.detail===1?this._handleSingleClick(e):e.detail===2?this._handleDoubleClick(e):e.detail===3&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener("mouseup",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval(()=>this._dragScroll(),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener("mouseup",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){let t=this.hasSelection;if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0,t&&this._fireOnSelectionChange(this._model.finalSelectionStart,this._model.finalSelectionEnd,!1);let r=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);r&&r.length!==this._model.selectionStart[0]&&r.hasWidth(this._model.selectionStart[0])===0&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){let t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return this._optionsService.rawOptions.mouseEventsRequireAlt&&this._mouseStateService.areMouseEventsActive?!1:e.altKey&&!(ie&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;let t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd){this.refresh(!0);return}this._activeSelectionMode===2?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));let r=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(this._activeSelectionMode!==3&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows-1,e.lines.length-1)):(this._activeSelectionMode!==3&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){let t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){let r=this._mouseCoordsService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(r&&r[0]!==void 0&&r[1]!==void 0){let s=tn(r[0]-1,r[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(s,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){let e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,r=!!e&&!!t&&(e[0]!==t[0]||e[1]!==t[1]);if(!r){this._oldHasSelection&&this._fireOnSelectionChange(e,t,r);return}!e||!t||(!this._oldSelectionStart||!this._oldSelectionEnd||e[0]!==this._oldSelectionStart[0]||e[1]!==this._oldSelectionStart[1]||t[0]!==this._oldSelectionEnd[0]||t[1]!==this._oldSelectionEnd[1])&&this._fireOnSelectionChange(e,t,r)}_fireOnSelectionChange(e,t,r){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=r,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.value=e.activeBuffer.lines.onTrim(t=>this._handleTrim(t))}_convertViewportColToCharacterIndex(e,t){let r=t;for(let s=0;t>=s;s++){let o=e.loadCell(s,this._workCell).getChars().length;this._workCell.getWidth()===0?r--:o>1&&t!==s&&(r+=o-1)}return r}setSelection(e,t,r){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=r,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,r=!0,s=!0){if(e[0]>=this._bufferService.cols)return;let o=this._bufferService.buffer,a=o.lines.get(e[1]);if(!a)return;let l=o.translateBufferLineToString(e[1],!1),h=this._convertViewportColToCharacterIndex(a,e[0]),d=h,c=e[0]-h,u=0,_=0,p=0,v=0;if(l.charAt(h)===" "){for(;h>0&&l.charAt(h-1)===" ";)h--;for(;d1&&(v+=L-1,d+=L-1);I>0&&h>0&&!this._isCharWordSeparator(a.loadCell(I-1,this._workCell));){a.loadCell(I-1,this._workCell);let T=this._workCell.getChars().length;this._workCell.getWidth()===0?(u++,I--):T>1&&(p+=T-1,h-=T-1),h--,I--}for(;w1&&(v+=T-1,d+=T-1),d++,w++}}d++;let f=h+c-u+p,S=Math.min(this._bufferService.cols,d-h+u+_-p-v);if(!(!t&&l.slice(h,d).trim()==="")){if(r&&f===0&&a.getCodePoint(0)!==32){let I=o.lines.get(e[1]-1);if(I&&a.isWrapped&&I.getCodePoint(this._bufferService.cols-1)!==32){let w=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(w){let L=this._bufferService.cols-w.start;f-=L,S+=L}}}if(s&&f+S===this._bufferService.cols&&a.getCodePoint(this._bufferService.cols-1)!==32){let I=o.lines.get(e[1]+1);if(I?.isWrapped&&I.getCodePoint(0)!==32){let w=this._getWordAt([0,e[1]+1],!1,!1,!0);w&&(S+=w.length)}}return{start:f,length:S}}}_selectWordAt(e,t){let r=this._getWordAt(e,t);if(r){for(;r.start<0;)r.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[r.start,e[1]],this._model.selectionStartLength=r.length}}_selectToWordAt(e){let t=this._getWordAt(e,!0);if(t){let r=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,r--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,r++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,r]}}_isCharWordSeparator(e){return e.getWidth()===0?!1:this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){let t=this._bufferService.buffer.getWrappedRangeForLine(e),r={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=fs(r,this._bufferService.cols)}};Et=y([m(3,D),m(4,Y),m(5,Pe),m(6,R),m(7,Me),m(8,V),m(9,G)],Et);var jt=class{constructor(){this._data={}}set(i,e,t){this._data[i]||(this._data[i]={}),this._data[i][e]=t}get(i,e){return this._data[i]?this._data[i][e]:void 0}clear(){this._data={}}};var Zt=class{constructor(){this._color=new jt;this._css=new jt}setCss(i,e,t){this._css.set(i,e,t)}getCss(i,e){return this._css.get(i,e)}setColor(i,e,t){this._color.set(i,e,t)}getColor(i,e){return this._color.get(i,e)}clear(){this._color.clear(),this._css.clear()}};var $=Object.freeze((()=>{let n=[B.toColor("#2e3436"),B.toColor("#cc0000"),B.toColor("#4e9a06"),B.toColor("#c4a000"),B.toColor("#3465a4"),B.toColor("#75507b"),B.toColor("#06989a"),B.toColor("#d3d7cf"),B.toColor("#555753"),B.toColor("#ef2929"),B.toColor("#8ae234"),B.toColor("#fce94f"),B.toColor("#729fcf"),B.toColor("#ad7fa8"),B.toColor("#34e2e2"),B.toColor("#eeeeec")],i=[0,95,135,175,215,255];for(let e=0;e<216;e++){let t=i[e/36%6|0],r=i[e/6%6|0],s=i[e%6];n.push({css:O.toCss(t,r,s),rgba:O.toRgba(t,r,s)})}for(let e=0;e<24;e++){let t=8+e*10;n.push({css:O.toCss(t,t,t),rgba:O.toRgba(t,t,t)})}return n})());var qe=B.toColor("#ffffff"),Qt=B.toColor("#000000"),nn=B.toColor("#ffffff"),on=Qt,Jt={css:"rgba(255, 255, 255, 0.3)",rgba:4294967117},co=qe,yt=class extends g{constructor(e){super();this._optionsService=e;this._contrastCache=new Zt;this._halfContrastCache=new Zt;this._onChangeColors=this._register(new b);this.onChangeColors=this._onChangeColors.event;this._colors={foreground:qe,background:Qt,cursor:nn,cursorAccent:on,selectionForeground:void 0,selectionBackgroundTransparent:Jt,selectionBackgroundOpaque:k.blend(Qt,Jt),selectionInactiveBackgroundTransparent:Jt,selectionInactiveBackgroundOpaque:k.blend(Qt,Jt),scrollbarSliderBackground:k.opacity(qe,.2),scrollbarSliderHoverBackground:k.opacity(qe,.4),scrollbarSliderActiveBackground:k.opacity(qe,.5),overviewRulerBorder:qe,ansi:$.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this._register(this._optionsService.onSpecificOptionChange("minimumContrastRatio",()=>this._contrastCache.clear())),this._register(this._optionsService.onSpecificOptionChange("theme",()=>this._setTheme(this._optionsService.rawOptions.theme)))}get colors(){return this._colors}_setTheme(e={}){let t=this._colors;if(t.foreground=M(e.foreground,qe),t.background=M(e.background,Qt),t.cursor=k.blend(t.background,M(e.cursor,nn)),t.cursorAccent=k.blend(t.background,M(e.cursorAccent,on)),t.selectionBackgroundTransparent=M(e.selectionBackground,Jt),t.selectionBackgroundOpaque=k.blend(t.background,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundTransparent=M(e.selectionInactiveBackground,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundOpaque=k.blend(t.background,t.selectionInactiveBackgroundTransparent),t.selectionForeground=e.selectionForeground?M(e.selectionForeground,ts):void 0,t.selectionForeground===ts&&(t.selectionForeground=void 0),k.isOpaque(t.selectionBackgroundTransparent)&&(t.selectionBackgroundTransparent=k.opacity(t.selectionBackgroundTransparent,.3)),k.isOpaque(t.selectionInactiveBackgroundTransparent)&&(t.selectionInactiveBackgroundTransparent=k.opacity(t.selectionInactiveBackgroundTransparent,.3)),t.scrollbarSliderBackground=M(e.scrollbarSliderBackground,k.opacity(t.foreground,.2)),t.scrollbarSliderHoverBackground=M(e.scrollbarSliderHoverBackground,k.opacity(t.foreground,.4)),t.scrollbarSliderActiveBackground=M(e.scrollbarSliderActiveBackground,k.opacity(t.foreground,.5)),t.overviewRulerBorder=M(e.overviewRulerBorder,co),t.ansi=$.slice(),t.ansi[0]=M(e.black,$[0]),t.ansi[1]=M(e.red,$[1]),t.ansi[2]=M(e.green,$[2]),t.ansi[3]=M(e.yellow,$[3]),t.ansi[4]=M(e.blue,$[4]),t.ansi[5]=M(e.magenta,$[5]),t.ansi[6]=M(e.cyan,$[6]),t.ansi[7]=M(e.white,$[7]),t.ansi[8]=M(e.brightBlack,$[8]),t.ansi[9]=M(e.brightRed,$[9]),t.ansi[10]=M(e.brightGreen,$[10]),t.ansi[11]=M(e.brightYellow,$[11]),t.ansi[12]=M(e.brightBlue,$[12]),t.ansi[13]=M(e.brightMagenta,$[13]),t.ansi[14]=M(e.brightCyan,$[14]),t.ansi[15]=M(e.brightWhite,$[15]),e.extendedAnsi){let r=Math.min(t.ansi.length-16,e.extendedAnsi.length);for(let s=0;s"],191:["/","?"],192:["`","~"],219:["[","{"],220:["\\","|"],221:["]","}"],222:["'",'"']};function ln(n,i,e,t){let r={type:0,cancel:!1,key:void 0},s=(n.shiftKey?1:0)|(n.altKey?2:0)|(n.ctrlKey?4:0)|(n.metaKey?8:0);switch(n.keyCode){case 0:n.key==="UIKeyInputUpArrow"?i?r.key="\x1BOA":r.key="\x1B[A":n.key==="UIKeyInputLeftArrow"?i?r.key="\x1BOD":r.key="\x1B[D":n.key==="UIKeyInputRightArrow"?i?r.key="\x1BOC":r.key="\x1B[C":n.key==="UIKeyInputDownArrow"&&(i?r.key="\x1BOB":r.key="\x1B[B");break;case 8:r.key=n.ctrlKey?"\b":"\x7F",n.altKey&&(r.key="\x1B"+r.key);break;case 9:if(n.shiftKey){r.key="\x1B[Z";break}r.key=" ",r.cancel=!0;break;case 13:n.key==="c"&&n.ctrlKey?r.key="":r.key=n.altKey?"\x1B\r":"\r",r.cancel=!0;break;case 27:r.key="\x1B",n.altKey&&(r.key="\x1B\x1B"),r.cancel=!0;break;case 37:if(n.metaKey)break;s?r.key="\x1B[1;"+(s+1)+"D":i?r.key="\x1BOD":r.key="\x1B[D";break;case 39:if(n.metaKey)break;s?r.key="\x1B[1;"+(s+1)+"C":i?r.key="\x1BOC":r.key="\x1B[C";break;case 38:if(n.metaKey)break;s?r.key="\x1B[1;"+(s+1)+"A":i?r.key="\x1BOA":r.key="\x1B[A";break;case 40:if(n.metaKey)break;s?r.key="\x1B[1;"+(s+1)+"B":i?r.key="\x1BOB":r.key="\x1B[B";break;case 45:!n.shiftKey&&!n.ctrlKey&&(r.key="\x1B[2~");break;case 46:s?r.key="\x1B[3;"+(s+1)+"~":r.key="\x1B[3~";break;case 36:s?r.key="\x1B[1;"+(s+1)+"H":i?r.key="\x1BOH":r.key="\x1B[H";break;case 35:s?r.key="\x1B[1;"+(s+1)+"F":i?r.key="\x1BOF":r.key="\x1B[F";break;case 33:n.shiftKey?r.type=2:n.ctrlKey?r.key="\x1B[5;"+(s+1)+"~":r.key="\x1B[5~";break;case 34:n.shiftKey?r.type=3:n.ctrlKey?r.key="\x1B[6;"+(s+1)+"~":r.key="\x1B[6~";break;case 112:s?r.key="\x1B[1;"+(s+1)+"P":r.key="\x1BOP";break;case 113:s?r.key="\x1B[1;"+(s+1)+"Q":r.key="\x1BOQ";break;case 114:s?r.key="\x1B[1;"+(s+1)+"R":r.key="\x1BOR";break;case 115:s?r.key="\x1B[1;"+(s+1)+"S":r.key="\x1BOS";break;case 116:s?r.key="\x1B[15;"+(s+1)+"~":r.key="\x1B[15~";break;case 117:s?r.key="\x1B[17;"+(s+1)+"~":r.key="\x1B[17~";break;case 118:s?r.key="\x1B[18;"+(s+1)+"~":r.key="\x1B[18~";break;case 119:s?r.key="\x1B[19;"+(s+1)+"~":r.key="\x1B[19~";break;case 120:s?r.key="\x1B[20;"+(s+1)+"~":r.key="\x1B[20~";break;case 121:s?r.key="\x1B[21;"+(s+1)+"~":r.key="\x1B[21~";break;case 122:s?r.key="\x1B[23;"+(s+1)+"~":r.key="\x1B[23~";break;case 123:s?r.key="\x1B[24;"+(s+1)+"~":r.key="\x1B[24~";break;default:if(n.ctrlKey&&!n.shiftKey&&!n.altKey&&!n.metaKey)n.keyCode>=65&&n.keyCode<=90?r.key=String.fromCharCode(n.keyCode-64):n.keyCode===32?r.key="\0":n.keyCode>=51&&n.keyCode<=55?r.key=String.fromCharCode(n.keyCode-51+27):n.keyCode===56?r.key="\x7F":n.key==="/"?r.key="":n.keyCode===219?r.key="\x1B":n.keyCode===220?r.key="":n.keyCode===221&&(r.key="");else if((!e||t)&&n.altKey&&!n.metaKey){let a=ho[n.keyCode]?.[n.shiftKey?1:0];if(a)r.key="\x1B"+a;else if(n.keyCode>=65&&n.keyCode<=90){let l=n.ctrlKey?n.keyCode-64:n.keyCode+32,h=String.fromCharCode(l);n.shiftKey&&(h=h.toUpperCase()),r.key="\x1B"+h}else if(n.keyCode===32)r.key="\x1B"+(n.ctrlKey?"\0":" ");else if(n.key==="Dead"&&n.code.startsWith("Key")){let l=n.code.slice(3,4);n.shiftKey||(l=l.toLowerCase()),r.key="\x1B"+l,r.cancel=!0}}else if(e&&!n.altKey&&!n.ctrlKey&&!n.shiftKey&&n.metaKey)n.keyCode===65&&(r.type=1);else if(n.key&&!n.ctrlKey&&!n.altKey&&!n.metaKey&&n.keyCode>=48&&n.key.length===1)r.key=n.key;else if(n.key&&n.ctrlKey&&n.shiftKey)switch(n.code){case"Minus":r.key="";break;case"Digit2":r.key="\0";break;case"Digit6":r.key="";break}break}return r}var ei=class{constructor(){this._functionalKeyCodes={Escape:27,Enter:13,Tab:9,Backspace:127,CapsLock:57358,ScrollLock:57359,NumLock:57360,PrintScreen:57361,Pause:57362,ContextMenu:57363,F13:57376,F14:57377,F15:57378,F16:57379,F17:57380,F18:57381,F19:57382,F20:57383,F21:57384,F22:57385,F23:57386,F24:57387,F25:57388,KP_0:57399,KP_1:57400,KP_2:57401,KP_3:57402,KP_4:57403,KP_5:57404,KP_6:57405,KP_7:57406,KP_8:57407,KP_9:57408,KP_Decimal:57409,KP_Divide:57410,KP_Multiply:57411,KP_Subtract:57412,KP_Add:57413,KP_Enter:57414,KP_Equal:57415,ShiftLeft:57441,ShiftRight:57447,ControlLeft:57442,ControlRight:57448,AltLeft:57443,AltRight:57449,MetaLeft:57444,MetaRight:57450,MediaPlayPause:57430,MediaStop:57432,MediaTrackNext:57435,MediaTrackPrevious:57436,AudioVolumeDown:57438,AudioVolumeUp:57439,AudioVolumeMute:57440};this._csiTildeKeys={Insert:2,Delete:3,PageUp:5,PageDown:6,F5:15,F6:17,F7:18,F8:19,F9:20,F10:21,F11:23,F12:24};this._csiLetterKeys={ArrowUp:"A",ArrowDown:"B",ArrowRight:"C",ArrowLeft:"D",Home:"H",End:"F"};this._ss3FunctionKeys={F1:"P",F2:"Q",F3:"R",F4:"S"}}_getNumpadKeyCode(i){if(i.code.startsWith("Numpad")){let e=i.code.slice(6);if(e>="0"&&e<="9")return 57399+parseInt(e,10);switch(e){case"Decimal":return 57409;case"Divide":return 57410;case"Multiply":return 57411;case"Subtract":return 57412;case"Add":return 57413;case"Enter":return 57414;case"Equal":return 57415}}}_getModifierKeyCode(i){switch(i.code){case"ShiftLeft":return 57441;case"ShiftRight":return 57447;case"ControlLeft":return 57442;case"ControlRight":return 57448;case"AltLeft":return 57443;case"AltRight":return 57449;case"MetaLeft":return 57444;case"MetaRight":return 57450}}_encodeModifiers(i){let e=0;return i.shiftKey&&(e|=1),i.altKey&&(e|=2),i.ctrlKey&&(e|=4),i.metaKey&&(e|=8),e>0?e+1:0}_getKeyCode(i,e){let t=this._getNumpadKeyCode(i);if(t!==void 0)return t;let r=this._getModifierKeyCode(i);if(r!==void 0)return r;let s=this._functionalKeyCodes[i.key];if(s!==void 0)return s;if((i.shiftKey||e&&i.altKey)&&i.code){if(i.code.startsWith("Digit")&&i.code.length===6){let o=i.code.charAt(5);if(o>="0"&&o<="9")return o.charCodeAt(0)}if(i.code.startsWith("Key")&&i.code.length===4)return i.code.charAt(3).toLowerCase().charCodeAt(0)}if(i.key.length===1){let o=i.key.codePointAt(0);return o>=65&&o<=90?o+32:o}}_isModifierKey(i){return i.key==="Shift"||i.key==="Control"||i.key==="Alt"||i.key==="Meta"}_isLockKey(i){return i.key==="CapsLock"||i.key==="NumLock"||i.key==="ScrollLock"}_buildCsiLetterSequence(i,e,t,r){let s=r&&t!==1;if(e>0||s){let o="\x1B[1;"+(e>0?e:"1");return s&&(o+=":"+t),o+=i,o}return"\x1B["+i}_buildSs3Sequence(i,e,t,r){let s=r&&t!==1;if(e>0||s){let o="\x1B[1;"+(e>0?e:"1");return s&&(o+=":"+t),o+=i,o}return"\x1BO"+i}_buildCsiTildeSequence(i,e,t,r){let s=r&&t!==1,o="\x1B["+i;return(e>0||s)&&(o+=";"+(e>0?e:"1"),s&&(o+=":"+t)),o+="~",o}_buildCsiUSequence(i,e,t,r,s,o,a){let l=!!(s&2),h=!!(s&4),d="\x1B["+e,c;h&&i.shiftKey&&i.key.length===1&&!o&&!a&&(c=i.key.codePointAt(0),d+=":"+c);let _=!!(s&16)&&r!==3&&i.key.length===1&&!o&&!a&&!i.ctrlKey?i.key.codePointAt(0):void 0,p=l&&r!==1&&(r===3||_===void 0);return(t>0||p||_!==void 0)&&(d+=";",t>0?d+=t:p&&(d+="1"),p&&(d+=":"+r)),_!==void 0&&(d+=";"+_),d+="u",d}evaluate(i,e,t=1,r=!1){let s={type:0,cancel:!1,key:void 0},o=this._encodeModifiers(i),a=this._isModifierKey(i),l=!!(e&2);if(!l&&t===3||a&&!(e&8)||this._isLockKey(i)&&!(e&8))return s;let h=this._csiLetterKeys[i.key];if(h)return s.key=this._buildCsiLetterSequence(h,o,t,l),s.cancel=!0,s;let d=this._ss3FunctionKeys[i.key];if(d)return s.key=this._buildSs3Sequence(d,o,t,l),s.cancel=!0,s;let c=this._csiTildeKeys[i.key];if(c!==void 0)return s.key=this._buildCsiTildeSequence(c,o,t,l),s.cancel=!0,s;let u=this._getKeyCode(i,r);if(u===void 0)return s;let _=u===13||u===9||u===127;if(_&&t===3&&!(e&8))return s;let p=this._functionalKeyCodes[i.key]!==void 0||this._getNumpadKeyCode(i)!==void 0;if(!!(e&8||l&&t===3||(e&1||l)&&(p&&!_||o>0&&i.key.length!==1||o-1>1)))s.key=this._buildCsiUSequence(i,u,o,t,e,p,a),s.cancel=!0;else{let f=u===13?"\r":u===9?" ":u===127?"\x7F":void 0;f?s.key=f:i.key.length===1&&!i.ctrlKey&&!i.altKey&&!i.metaKey&&(s.key=i.key)}return s}static shouldUseProtocol(i){return i>0}};var Zi=class{constructor(){this._codeToVk={KeyA:65,KeyB:66,KeyC:67,KeyD:68,KeyE:69,KeyF:70,KeyG:71,KeyH:72,KeyI:73,KeyJ:74,KeyK:75,KeyL:76,KeyM:77,KeyN:78,KeyO:79,KeyP:80,KeyQ:81,KeyR:82,KeyS:83,KeyT:84,KeyU:85,KeyV:86,KeyW:87,KeyX:88,KeyY:89,KeyZ:90,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,F16:127,F17:128,F18:129,F19:130,F20:131,F21:132,F22:133,F23:134,F24:135,Numpad0:96,Numpad1:97,Numpad2:98,Numpad3:99,Numpad4:100,Numpad5:101,Numpad6:102,Numpad7:103,Numpad8:104,Numpad9:105,NumpadMultiply:106,NumpadAdd:107,NumpadSeparator:108,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,NumLock:144,ArrowUp:38,ArrowDown:40,ArrowLeft:37,ArrowRight:39,Home:36,End:35,PageUp:33,PageDown:34,Insert:45,Delete:46,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,CapsLock:20,ScrollLock:145,Escape:27,Enter:13,Tab:9,Space:32,Backspace:8,Pause:19,ContextMenu:93,PrintScreen:44,Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,IntlBackslash:226};this._codeToScancode={KeyQ:16,KeyW:17,KeyE:18,KeyR:19,KeyT:20,KeyY:21,KeyU:22,KeyI:23,KeyO:24,KeyP:25,KeyA:30,KeyS:31,KeyD:32,KeyF:33,KeyG:34,KeyH:35,KeyJ:36,KeyK:37,KeyL:38,KeyZ:44,KeyX:45,KeyC:46,KeyV:47,KeyB:48,KeyN:49,KeyM:50,Digit1:2,Digit2:3,Digit3:4,Digit4:5,Digit5:6,Digit6:7,Digit7:8,Digit8:9,Digit9:10,Digit0:11,F1:59,F2:60,F3:61,F4:62,F5:63,F6:64,F7:65,F8:66,F9:67,F10:68,F11:87,F12:88,Numpad0:82,Numpad1:79,Numpad2:80,Numpad3:81,Numpad4:75,Numpad5:76,Numpad6:77,Numpad7:71,Numpad8:72,Numpad9:73,NumpadMultiply:55,NumpadAdd:78,NumpadSubtract:74,NumpadDecimal:83,NumpadDivide:53,NumpadEnter:28,NumLock:69,ArrowUp:72,ArrowDown:80,ArrowLeft:75,ArrowRight:77,Home:71,End:79,PageUp:73,PageDown:81,Insert:82,Delete:83,ShiftLeft:42,ShiftRight:54,ControlLeft:29,ControlRight:29,AltLeft:56,AltRight:56,CapsLock:58,ScrollLock:70,Escape:1,Enter:28,Tab:15,Space:57,Backspace:14,Pause:69,Semicolon:39,Equal:13,Comma:51,Minus:12,Period:52,Slash:53,Backquote:41,BracketLeft:26,Backslash:43,BracketRight:27,Quote:40};this._enhancedKeyCodes=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Insert","Delete","NumpadEnter","NumpadDivide","ControlRight","AltRight","PrintScreen","Pause","ContextMenu","MetaLeft","MetaRight"]);this._keyToControlChar={Enter:13,Backspace:8,Tab:9,Escape:27}}_getVirtualKeyCode(i){let e=this._codeToVk[i.code];return e!==void 0?e:i.keyCode||0}_getScanCode(i){return this._codeToScancode[i.code]||0}_getUnicodeChar(i){if(i.ctrlKey&&!i.altKey&&!i.metaKey){if(i.key==="Enter")return 10;if(i.key==="Backspace")return 127}let e=this._keyToControlChar[i.key];if(e!==void 0)return e;if(i.key.length===1){let t=i.key.codePointAt(0)||0;if(i.ctrlKey&&!i.altKey&&!i.metaKey){if(t>=65&&t<=90)return t-64;if(t>=97&&t<=122)return t-96}return t}return 0}_getControlKeyState(i){let e=0;return i.shiftKey&&(e|=16),i.ctrlKey&&(i.code==="ControlRight"?e|=4:e|=8),i.altKey&&(i.code==="AltRight"?e|=1:e|=2),this._enhancedKeyCodes.has(i.code)&&(e|=256),e}evaluateKeyboardEvent(i,e){let t=this._getVirtualKeyCode(i),r=this._getScanCode(i),s=this._getUnicodeChar(i),o=e?1:0,a=this._getControlKeyState(i);return{type:0,cancel:!0,key:`\x1B[${t};${r};${s};${o};${a};1_`}}};var xt=class{constructor(i,e){this._coreService=i;this._optionsService=e}_getWin32InputMode(){return this._win32InputMode??=new Zi,this._win32InputMode}_getKittyKeyboard(){return this._kittyKeyboard??=new ei,this._kittyKeyboard}evaluateKeyDown(i){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(i,!0);let e=this._coreService.kittyKeyboard.flags;return this.useKitty?this._getKittyKeyboard().evaluate(i,e,i.repeat?2:1,ie&&this._optionsService.rawOptions.macOptionIsMeta):ln(i,this._coreService.decPrivateModes.applicationCursorKeys,ie,this._optionsService.rawOptions.macOptionIsMeta)}evaluateKeyUp(i){if(this.useWin32InputMode)return this._getWin32InputMode().evaluateKeyboardEvent(i,!1);let e=this._coreService.kittyKeyboard.flags;if(this.useKitty&&e&2)return this._getKittyKeyboard().evaluate(i,e,3,ie&&this._optionsService.rawOptions.macOptionIsMeta)}get useKitty(){let i=this._coreService.kittyKeyboard.flags;return!!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard&&ei.shouldUseProtocol(i))}get useWin32InputMode(){return!!(this._optionsService.rawOptions.vtExtensions?.win32InputMode&&this._coreService.decPrivateModes.win32InputMode)}};xt=y([m(0,Y),m(1,R)],xt);var ps=class{constructor(...i){this._entries=new Map;for(let[e,t]of i)this.set(e,t)}set(i,e){let t=this._entries.get(i);return this._entries.set(i,e),t}forEach(i){for(let[e,t]of this._entries.entries())i(e,t)}has(i){return this._entries.has(i)}get(i){return this._entries.get(i)}},Ji=class{constructor(){this._services=new ps;this._services.set(Qe,this)}setService(i,e){this._services.set(i,e)}getService(i){return this._services.get(i)}createInstance(i,...e){let t=Hs(i).sort((o,a)=>o.index-a.index),r=[];for(let o of t){let a=this._services.get(o.id);if(!a)throw new Error(`[createInstance] ${i.name} depends on UNKNOWN service ${o.id._id}.`);r.push(a)}let s=t.length>0?t[0].index:e.length;if(e.length!==s)throw new Error(`[createInstance] First service dependency of ${i.name} at position ${s+1} conflicts with ${e.length} static arguments`);return new i(...e,...r)}};var uo={trace:0,debug:1,info:2,warn:3,error:4,off:5},fo="xterm.js: ",wt=class extends g{constructor(e){super();this._optionsService=e;this._logLevel=5;this._updateLogLevel(),this._register(this._optionsService.onSpecificOptionChange("logLevel",()=>this._updateLogLevel()))}get logLevel(){return this._logLevel}_updateLogLevel(){this._logLevel=uo[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;tthis._length)for(let t=this._length;t=e;s--)this._array[this._getCyclicIndex(s+r.length)]=this._array[this._getCyclicIndex(s)];for(let s=0;sthis._maxLength){let s=this._length+r.length-this._maxLength;this._startIndex+=s,this._length=this._maxLength,this.onTrimEmitter.fire(s)}else this._length+=r.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,r){if(!(t<=0)){if(e<0||e>=this._length)throw new Error("start argument out of range");if(e+r<0)throw new Error("Cannot shift elements in list beyond index 0");if(r>0){for(let o=t-1;o>=0;o--)this.set(e+o+r,this.get(e+o));let s=e+t+r-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;sthis._limit?(this._builder.reset(),!0):!1}toString(){return this._builder.toString()}};var U=Object.freeze(new ue),Qi=0,hn=new F,er=new ii,De=class n{constructor(i,e,t,r=!1){this._stringCache=i;this.isWrapped=r;this._combined={};this._extendedAttrs={};this._data=new Uint32Array(e*3);let s=t??F.fromCharData([0,"",1,0]);for(let o=0;o>22,e&2097152?this._combined[i].charCodeAt(this._combined[i].length-1):t]}set(i,e){this._invalidateStringCache(),this._data[i*3+1]=e[0],e[1].length>1?(this._combined[i]=e[1],this._data[i*3+0]=i|2097152|e[2]<<22):this._data[i*3+0]=e[1].charCodeAt(0)|e[2]<<22}getWidth(i){return this._data[i*3+0]>>22}hasWidth(i){return this._data[i*3+0]&12582912}getFg(i){return this._data[i*3+1]}getBg(i){return this._data[i*3+2]}hasContent(i){return this._data[i*3+0]&4194303}getCodePoint(i){let e=this._data[i*3+0];return e&2097152?this._combined[i].charCodeAt(this._combined[i].length-1):e&2097151}isCombined(i){return this._data[i*3+0]&2097152}getString(i){let e=this._data[i*3+0];return e&2097152?this._combined[i]:e&2097151?be(e&2097151):""}isProtected(i){return this._data[i*3+2]&536870912}loadCell(i,e){return Qi=i*3,e.content=this._data[Qi+0],e.fg=this._data[Qi+1],e.bg=this._data[Qi+2],e.content&2097152?e.combinedData=this._combined[i]:e.combinedData="",e.bg&268435456?e.extended=this._extendedAttrs[i]:e.extended=U.extended.clone(),e}setCell(i,e){this._invalidateStringCache(),e.content&2097152&&(this._combined[i]=e.combinedData),e.bg&268435456&&(this._extendedAttrs[i]=e.extended),this._data[i*3+0]=e.content,this._data[i*3+1]=e.fg,this._data[i*3+2]=e.bg}setCellFromCodepoint(i,e,t,r){this._invalidateStringCache(),r.bg&268435456&&(this._extendedAttrs[i]=r.extended),this._data[i*3+0]=e|t<<22,this._data[i*3+1]=r.fg,this._data[i*3+2]=r.bg}addCodepointToCell(i,e,t){this._invalidateStringCache();let r=this._data[i*3+0];r&2097152?this._combined[i]+=be(e):r&2097151?(this._combined[i]=be(r&2097151)+be(e),r&=-2097152,r|=2097152):r=e|1<<22,t&&(r&=-12582913,r|=t<<22),this._data[i*3+0]=r}insertCells(i,e,t){if(this._invalidateStringCache(),i%=this.length,i&&this.getWidth(i-1)===2&&this.setCellFromCodepoint(i-1,0,1,t),e=0;--r)this.setCell(i+e+r,this.loadCell(i+r,hn));for(let r=0;rthis.length){if(this._data.buffer.byteLength>=t*4)this._data=new Uint32Array(this._data.buffer,0,t);else{let r=new Uint32Array(t);r.set(this._data),this._data=r}for(let r=this.length;r=i&&delete this._combined[a]}let s=Object.keys(this._extendedAttrs);for(let o=0;o=i&&delete this._extendedAttrs[a]}}return this.length=i,t*4*2=0;--i)if(this._data[i*3+0]&4194303)return i+(this._data[i*3+0]>>22);return 0}getNoBgTrimmedLength(){for(let i=this.length-1;i>=0;--i)if(this._data[i*3+0]&4194303||this._data[i*3+2]&50331648)return i+(this._data[i*3+0]>>22);return 0}copyCellsFrom(i,e,t,r,s){this._invalidateStringCache();let o=i._data;if(s)for(let a=r-1;a>=0;a--){for(let l=0;l<3;l++)this._data[(t+a)*3+l]=o[(e+a)*3+l];this._copyCellMapsFrom(i,e+a,t+a)}else for(let a=0;a>22||1}r&&r.push(e);let a=er.toString();if(er.reset(),s){let l=this._getStringCacheEntry(!0);l.value=a,l.isTrimmed=!!i}return a}_getStringCacheEntry(i){let e=this._stringCacheEntryRef?.deref();if(e&&e.generation===this._stringCache.generation)return e;if(!i)return;let t=this._stringCache.allocateEntry();return this._stringCacheEntryRef=new WeakRef(t),t}_invalidateStringCache(){let i=this._getStringCacheEntry(!1);i&&(i.value=void 0,i.isTrimmed=!1)}_copyCellMapsFrom(i,e,t){let r=e*3;i._data[r+0]&2097152&&(this._combined[t]=i._combined[e]),i._data[r+2]&268435456&&(this._extendedAttrs[t]=i._extendedAttrs[e])}_copySparseMapsFrom(i){this._combined={},this._extendedAttrs={};for(let e=0;ethis.entries.clear()))}touch(){this._scheduleClear()}allocateEntry(){let e={value:void 0,isTrimmed:!1,generation:this.generation};return this.entries.add(e),this._scheduleClear(),e}clear(){this._clearTimeout.clear(),this._lastAccessTimestamp=0,this.generation++;for(let e of this.entries)e.value=void 0,e.isTrimmed=!1;this.entries.clear()}_scheduleClear(){this._lastAccessTimestamp=Date.now(),!this._clearTimeout.value&&this._scheduleClearTimeout(15e3)}_scheduleClearTimeout(e){this._clearTimeout.value=Gs(()=>{let t=Date.now()-this._lastAccessTimestamp;if(t>=15e3){this.clear();return}this._scheduleClearTimeout(15e3-t)},e)}};function dn(n,i,e,t,r,s){let o=[];for(let a=0;a=a&&t0&&(f>c||d[f].getTrimmedLength()===0);f--)v++;v>0&&(o.push(a+d.length-v),o.push(v)),a+=d.length-1}return o}function un(n,i){let e=[],t=0,r=i[t],s=0;for(let o=0;ol&&(s-=l,o++);let h=n[o].getWidth(s-1)===2;h&&s--;let d=h?e-1:e;t.push(d),a+=d}return t}function Tt(n,i,e){if(i===n.length-1)return n[i].getTrimmedLength();let t=!n[i].hasContent(e-1)&&n[i].getWidth(e-1)===1,r=n[i+1].getWidth(0)===2;return t&&r?e-1:e}var rr=class rr{constructor(i){this.line=i;this.isDisposed=!1;this._disposables=[];this._id=rr._nextId++;this._onDispose=this.register(new b);this.onDispose=this._onDispose.event}get id(){return this._id}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),Oe(this._disposables),this._disposables.length=0)}register(i){return this._disposables.push(i),i}};rr._nextId=1;var ir=rr;var q={},Re=q.B;q[0]={"`":"\u25C6",a:"\u2592",b:"\u2409",c:"\u240C",d:"\u240D",e:"\u240A",f:"\xB0",g:"\xB1",h:"\u2424",i:"\u240B",j:"\u2518",k:"\u2510",l:"\u250C",m:"\u2514",n:"\u253C",o:"\u23BA",p:"\u23BB",q:"\u2500",r:"\u23BC",s:"\u23BD",t:"\u251C",u:"\u2524",v:"\u2534",w:"\u252C",x:"\u2502",y:"\u2264",z:"\u2265","{":"\u03C0","|":"\u2260","}":"\xA3","~":"\xB7"};q.A={"#":"\xA3"};q.B=void 0;q[4]={"#":"\xA3","@":"\xBE","[":"ij","\\":"\xBD","]":"|","{":"\xA8","|":"f","}":"\xBC","~":"\xB4"};q.C=q[5]={"[":"\xC4","\\":"\xD6","]":"\xC5","^":"\xDC","`":"\xE9","{":"\xE4","|":"\xF6","}":"\xE5","~":"\xFC"};q.R={"#":"\xA3","@":"\xE0","[":"\xB0","\\":"\xE7","]":"\xA7","{":"\xE9","|":"\xF9","}":"\xE8","~":"\xA8"};q.Q={"@":"\xE0","[":"\xE2","\\":"\xE7","]":"\xEA","^":"\xEE","`":"\xF4","{":"\xE9","|":"\xF9","}":"\xE8","~":"\xFB"};q.K={"@":"\xA7","[":"\xC4","\\":"\xD6","]":"\xDC","{":"\xE4","|":"\xF6","}":"\xFC","~":"\xDF"};q.Y={"#":"\xA3","@":"\xA7","[":"\xB0","\\":"\xE7","]":"\xE9","`":"\xF9","{":"\xE0","|":"\xF2","}":"\xE8","~":"\xEC"};q.E=q[6]={"@":"\xC4","[":"\xC6","\\":"\xD8","]":"\xC5","^":"\xDC","`":"\xE4","{":"\xE6","|":"\xF8","}":"\xE5","~":"\xFC"};q.Z={"#":"\xA3","@":"\xA7","[":"\xA1","\\":"\xD1","]":"\xBF","{":"\xB0","|":"\xF1","}":"\xE7"};q.H=q[7]={"@":"\xC9","[":"\xC4","\\":"\xD6","]":"\xC5","^":"\xDC","`":"\xE9","{":"\xE4","|":"\xF6","}":"\xE5","~":"\xFC"};q["="]={"#":"\xF9","@":"\xE0","[":"\xE9","\\":"\xE7","]":"\xEA","^":"\xEE",_:"\xE8","`":"\xF4","{":"\xE4","|":"\xF6","}":"\xFC","~":"\xFB"};var pn=4294967295,si=class extends g{constructor(e,t,r,s){super();this._hasScrollback=e;this._optionsService=t;this._bufferService=r;this._logService=s;this.ydisp=0;this.ybase=0;this.y=0;this.x=0;this.tabs={};this.savedY=0;this.savedX=0;this.savedCurAttrData=U.clone();this.savedCharset=Re;this.savedCharsets=[];this.savedGlevel=0;this.savedOriginMode=!1;this.savedWraparoundMode=!0;this.markers=[];this._nullCell=F.fromCharData([0,"",1,0]);this._whitespaceCell=F.fromCharData([0," ",1,32]);this._isClearing=!1;this._memoryCleanupPosition=0;this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new ti(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops(),this._memoryCleanupQueue=new It(this._logService),this._register(E(()=>this._memoryCleanupQueue.clear())),this._register(E(()=>this.clearAllMarkers())),this._stringCache=this._register(new tr)}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new ke),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new ke),this._whitespaceCell}getBlankLine(e,t){return new De(this._stringCache,this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){let t=this.ybase+this.y-this.ydisp;return t>=0&&tpn?pn:t}fillViewportRows(e){if(this.lines.length===0){e??=U;let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this._stringCache.clear(),this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new ti(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){let r=this.getNullCell(U);this._stringCache.clear();let s=0,o=this._getCorrectBufferLength(t);if(o>this.lines.maxLength&&(this.lines.maxLength=o),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+a+1?(this.ybase--,a++,this.ydisp>0&&this.ydisp--):this.lines.push(new De(this._stringCache,e,r,!1)));else for(let l=this._rows;l>t;l--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(o0&&(this.lines.trimStart(l),this.ybase=Math.max(this.ybase-l,0),this.ydisp=Math.max(this.ydisp-l,0),this.savedY=Math.max(this.savedY-l,0)),this.lines.maxLength=o}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),a&&(this.y+=a),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let a=0;a0){let a=Math.max(0,this.lines.length-this.ybase-1);this.y=Math.min(this.y,a)}this._memoryCleanupQueue.clear(),s>.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue(()=>this._batchedMemoryCleanup()))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){let e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&e.backend==="conpty"&&e.buildNumber>=21376:this._hasScrollback}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){let r=this._optionsService.rawOptions.reflowCursorLine,s=dn(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(U),r);if(s.length>0){let o=un(this.lines,s);fn(this.lines,o.layout),this._reflowLargerAdjustViewport(e,t,o.countRemoved)}}_reflowLargerAdjustViewport(e,t,r){let s=this.getNullCell(U),o=r;for(;o-- >0;)this.ybase===0?(this.y>0&&this.y--,this.lines.length=0;l--){let h=this.lines.get(l);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;let d=[h];for(;h.isWrapped&&l>0;)h=this.lines.get(--l),d.unshift(h);if(!r){let T=this.ybase+this.y;if(T>=l&&T0&&(o.push({start:l+d.length+a,newLines:v}),a+=v.length),d.push(...v);let f=u.length-1,S=u[f];S===0&&(f--,S=u[f]);let I=d.length-_-1,w=c;for(;I>=0;){let T=Math.min(w,S);if(d[f]===void 0)break;if(d[f].copyCellsFrom(d[I],w-T,S-T,T,!0),S-=T,S===0&&(f--,S=u[f]),w-=T,w===0){I--;let te=Math.max(I,0);w=Tt(d,te,this._cols)}}for(let T=0;T0;)this.ybase===0?this.y0){let l=[],h=[];for(let S=0;S=0;S--)if(_&&_.start>c+p){for(let I=_.newLines.length-1;I>=0;I--)this.lines.set(S--,_.newLines[I]);S++,l.push({index:c+1,amount:_.newLines.length}),p+=_.newLines.length,_=o[++u]}else this.lines.set(S,h[c--]);let v=0;for(let S=l.length-1;S>=0;S--)l[S].index+=v,this.lines.onInsertEmitter.fire(l[S]),v+=l[S].amount;let f=Math.max(0,d+a-this.lines.maxLength);f>0&&this.lines.onTrimEmitter.fire(f)}}translateBufferLineToString(e,t,r=0,s){let o=this.lines.get(e);return o?o.translateToString(t,r,s):""}getWrappedRangeForLine(e){let t=e,r=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;r+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(e??=this.x;!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=r,t.line<0&&t.dispose()})),t.register(this.lines.onInsert(r=>{t.line>=r.index&&(t.line+=r.amount)})),t.register(this.lines.onDelete(r=>{t.line>=r.index&&t.liner.index&&(t.line-=r.amount)})),t.register(t.onDispose(()=>this._removeMarker(t))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}};var sr=class extends g{constructor(e,t,r){super();this._optionsService=e;this._bufferService=t;this._logService=r;this._normalBuffer=this._register(new P);this._altBuffer=this._register(new P);this._onBufferActivate=this._register(new b);this.onBufferActivate=this._onBufferActivate.event;this.reset(),this._register(this._optionsService.onSpecificOptionChange("scrollback",()=>this.resize(this._bufferService.cols,this._bufferService.rows))),this._register(this._optionsService.onSpecificOptionChange("tabStopWidth",()=>this.setupTabStops()))}reset(){this._normal=new si(!0,this._optionsService,this._bufferService,this._logService),this._normalBuffer.value=this._normal,this._normal.fillViewportRows(),this._alt=new si(!1,this._optionsService,this._bufferService,this._logService),this._altBuffer.value=this._alt,this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}};var Dt=class extends g{constructor(e,t){super();this.isUserScrolling=!1;this._onResize=this._register(new b);this.onResize=this._onResize.event;this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;this.cols=Math.max(e.rawOptions.cols||0,2),this.rows=Math.max(e.rawOptions.rows||0,1),this.buffers=this._register(new sr(e,this,t)),this._register(this.buffers.onBufferActivate(r=>{this._onScroll.fire(r.activeBuffer.ydisp)}))}get buffer(){return this.buffers.active}resize(e,t){let r=this.cols!==e,s=this.rows!==t;this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t,colsChanged:r,rowsChanged:s})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){let r=this.buffer,s;s=this._cachedBlankLine,(!s||s.length!==this.cols||s.getFg(0)!==e.fg||s.getBg(0)!==e.bg)&&(s=r.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;let o=r.ybase+r.scrollTop,a=r.ybase+r.scrollBottom;if(r.scrollTop===0){let l=r.lines.isFull;a===r.lines.length-1?l?r.lines.recycle().copyFrom(s):r.lines.push(s.clone()):r.lines.splice(a+1,0,s.clone()),l?this.isUserScrolling&&(r.ydisp=Math.max(r.ydisp-1,0)):(r.ybase++,this.isUserScrolling||r.ydisp++)}else{let l=a-o+1;r.lines.shiftElements(o+1,l-1,-1),r.lines.set(a,s.clone())}this.isUserScrolling||(r.ydisp=r.ybase),this._onScroll.fire(r.ydisp)}scrollLines(e,t){let r=this.buffer;if(e<0){if(r.ydisp===0)return;this.isUserScrolling=!0}else e+r.ydisp>=r.ybase&&(this.isUserScrolling=!1);let s=r.ydisp;r.ydisp=Math.max(Math.min(r.ydisp+e,r.ybase),0),s!==r.ydisp&&(t||this._onScroll.fire(r.ydisp))}};Dt=y([m(0,R),m(1,fe)],Dt);var Rt={cols:80,rows:24,showCursorImmediately:!1,cursorBlink:!1,blinkIntervalDuration:0,cursorStyle:"block",cursorWidth:1,cursorInactiveStyle:"outline",drawBoldTextInBrightColors:!0,documentOverride:null,fastScrollSensitivity:5,fontFamily:"monospace",fontSize:15,fontWeight:"normal",fontWeightBold:"bold",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:"info",logger:null,scrollback:1e3,scrollbar:{showScrollbar:!0},scrollOnEraseInDisplay:!1,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,mouseEventsRequireAlt:!1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},reflowCursorLine:!1,rescaleOverlappingGlyphs:!1,rightClickSelectsWord:ie,windowOptions:{},windowsPty:{},wordSeparator:" ()[]{}',\"`",altClickMovesCursor:!0,convertEol:!1,termName:"xterm",quirks:{},vtExtensions:{}},po=["normal","bold","100","200","300","400","500","600","700","800","900"],nr=class extends g{constructor(e){super();this._onOptionChange=this._register(new b);this.onOptionChange=this._onOptionChange.event;let t={...Rt};for(let r in e)if(r in t)try{let s=e[r];t[r]=this._sanitizeAndValidateOption(r,s)}catch(s){console.error(s)}this.rawOptions=t,this.options={...t},this._setupOptions(),this._register(E(()=>{this.rawOptions.linkHandler=null,this.rawOptions.documentOverride=null}))}onSpecificOptionChange(e,t){return this.onOptionChange(r=>{r===e&&t(this.rawOptions[e])})}onMultipleOptionChange(e,t){return this.onOptionChange(r=>{e.indexOf(r)!==-1&&t()})}_setupOptions(){let e=r=>{if(!(r in Rt))throw new Error(`No option with key "${r}"`);return this.rawOptions[r]},t=(r,s)=>{if(!(r in Rt))throw new Error(`No option with key "${r}"`);s=this._sanitizeAndValidateOption(r,s),this.rawOptions[r]!==s&&(this.rawOptions[r]=s,this._onOptionChange.fire(r))};for(let r in this.rawOptions){let s={get:e.bind(this,r),set:t.bind(this,r)};Object.defineProperty(this.options,r,s)}}_sanitizeAndValidateOption(e,t){switch(e){case"cursorStyle":if(t||(t=Rt[e]),!mo(t))throw new Error(`"${t}" is not a valid value for ${e}`);break;case"wordSeparator":t||(t=Rt[e]);break;case"fontWeight":case"fontWeightBold":if(typeof t=="number"&&1<=t&&t<=1e3)break;t=po.includes(t)?t:Rt[e];break;case"blinkIntervalDuration":if(t=Math.floor(t),t<0)throw new Error(`${e} cannot be less than 0, value: ${t}`);break;case"cursorWidth":t=Math.floor(t);case"lineHeight":case"tabStopWidth":if(t<1)throw new Error(`${e} cannot be less than 1, value: ${t}`);break;case"minimumContrastRatio":t=Math.max(1,Math.min(21,Math.round(t*10)/10));break;case"scrollback":if(t=Math.min(t,4294967295),t<0)throw new Error(`${e} cannot be less than 0, value: ${t}`);break;case"fastScrollSensitivity":case"scrollSensitivity":if(t<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${t}`);break;case"rows":case"cols":if(!t&&t!==0)throw new Error(`${e} must be numeric, value: ${t}`);break;case"windowsPty":t=t??{};break}return t}};function mo(n){return n==="block"||n==="underline"||n==="bar"}var mn=Object.freeze({insertMode:!1}),bn=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,colorSchemeUpdates:!1,cursorBlink:void 0,cursorStyle:void 0,origin:!1,reverseWraparound:!1,sendFocus:!1,synchronizedOutput:!1,win32InputMode:!1,wraparound:!0}),vn=()=>({flags:0,mainFlags:0,altFlags:0,mainStack:[],altStack:[]}),Lt=class extends g{constructor(e,t,r){super();this._bufferService=e;this._logService=t;this._optionsService=r;this.isCursorHidden=!1;this._onData=this._register(new b);this.onData=this._onData.event;this._onUserInput=this._register(new b);this.onUserInput=this._onUserInput.event;this._onBinary=this._register(new b);this.onBinary=this._onBinary.event;this._onRequestScrollToBottom=this._register(new b);this.onRequestScrollToBottom=this._onRequestScrollToBottom.event;this.isCursorInitialized=r.rawOptions.showCursorImmediately??!1,this.modes=structuredClone(mn),this.decPrivateModes=structuredClone(bn),this.kittyKeyboard=vn()}reset(){this.modes=structuredClone(mn),this.decPrivateModes=structuredClone(bn),this.kittyKeyboard=vn()}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;let r=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&r.ybase!==r.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data "${e}"`),this._logService.trace("sending data (codes)",()=>e.split("").map(s=>s.charCodeAt(0))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary "${e}"`),this._logService.trace("sending binary (codes)",()=>e.split("").map(t=>t.charCodeAt(0))),this._onBinary.fire(e))}};Lt=y([m(0,D),m(1,fe),m(2,R)],Lt);var Sn={NONE:{events:0,restrict:()=>!1},X10:{events:1,restrict:n=>n.button===4||n.action!==1?!1:(n.ctrl=!1,n.alt=!1,n.shift=!1,!0)},VT200:{events:19,restrict:n=>n.action!==32},DRAG:{events:23,restrict:n=>!(n.action===32&&n.button===3)},ANY:{events:31,restrict:n=>!0}};function vs(n,i){let e=(n.ctrl?16:0)|(n.shift?4:0)|(n.alt?8:0);return n.button===4?(e|=64,e|=n.action):(e|=n.button&3,n.button&4&&(e|=64),n.button&8&&(e|=128),n.action===32?e|=32:n.action===0&&!i&&(e|=3)),e}var Ss=String.fromCharCode,gn={DEFAULT:n=>{let i=[vs(n,!1)+32,n.col+32,n.row+32];return i[0]>255||i[1]>255||i[2]>255?"":`\x1B[M${Ss(i[0])}${Ss(i[1])}${Ss(i[2])}`},SGR:n=>{let i=n.action===0&&n.button!==4?"m":"M";return`\x1B[<${vs(n,!0)};${n.col};${n.row}${i}`},SGR_PIXELS:n=>{let i=n.action===0&&n.button!==4?"m":"M";return`\x1B[<${vs(n,!0)};${n.x};${n.y}${i}`}},or=class extends g{constructor(){super();this._protocols={};this._encodings={};this._activeProtocol="";this._activeEncoding="";this._onProtocolChange=this._register(new b);this.onProtocolChange=this._onProtocolChange.event;for(let e of Object.keys(Sn))this.addProtocol(e,Sn[e]);for(let e of Object.keys(gn))this.addEncoding(e,gn[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return this._protocols[this._activeProtocol].events!==0}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol "${e}"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding "${e}"`);this._activeEncoding=e}reset(){this.activeProtocol="NONE",this.activeEncoding="DEFAULT"}setCustomWheelEventHandler(e){this._customWheelEventHandler=e}allowCustomWheelEvent(e){return this._customWheelEventHandler?this._customWheelEventHandler(e)!==!1:!0}restrictMouseEvent(e){return this._protocols[this._activeProtocol].restrict(e)}encodeMouseEvent(e){return this._encodings[this._activeEncoding](e)}get isDefaultEncoding(){return this._activeEncoding==="DEFAULT"}get isPixelEncoding(){return this._activeEncoding==="SGR_PIXELS"}};var me=class n{constructor(){this._providers=Object.create(null);this._active="";this._onChange=new b;this.onChange=this._onChange.event}static extractShouldJoin(i){return(i&1)!==0}static extractWidth(i){return i>>1&3}static extractCharKind(i){return i>>3}static createPropertyValue(i,e,t=!1){return(i&16777215)<<3|(e&3)<<1|(t?1:0)}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(i){if(!this._providers[i])throw new Error(`unknown Unicode version "${i}"`);this._active=i,this._activeProvider=this._providers[i],this._onChange.fire(i)}register(i){this._providers[i.version]=i,this._active||(this.activeVersion=i.version)}wcwidth(i){return this._activeProvider.wcwidth(i)}getStringCellWidth(i){let e=0,t=0,r=i.length;for(let s=0;s=r)return e+this.wcwidth(o);let h=i.charCodeAt(s);56320<=h&&h<=57343?o=(o-55296)*1024+h-56320+65536:e+=this.wcwidth(h)}let a=this.charProperties(o,t),l=n.extractWidth(a);n.extractShouldJoin(a)&&(l-=n.extractWidth(t)),e+=l,t=a}return e}charProperties(i,e){return this._activeProvider.charProperties(i,e)}};var gs=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],bo=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]],X;function vo(n,i){let e=0,t=i.length-1,r;if(ni[t][1])return!1;for(;t>=e;)if(r=e+t>>1,n>i[r][1])e=r+1;else if(n=131072&&i<=196605||i>=196608&&i<=262141?2:1}charProperties(i,e){let t=this.wcwidth(i),r=t===0&&e!==0;if(r){let s=me.extractWidth(e);s===0?r=!1:s>t&&(t=s)}return me.createPropertyValue(0,t,r)}};var lr=class{constructor(){this.glevel=0;this._charsets=[]}get charsets(){return this._charsets}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(i){this.glevel=i,this.charset=this._charsets[i]}setgCharset(i,e){this._charsets[i]=e,this.glevel===i&&(this.charset=e)}};function Is(n){let e=n.buffer.lines.get(n.buffer.ybase+n.buffer.y-1)?.get(n.cols-1),t=n.buffer.lines.get(n.buffer.ybase+n.buffer.y);t&&e&&(t.isWrapped=e[3]!==0&&e[3]!==32)}var At=class n{constructor(i=32,e=32){this.maxLength=i;this.maxSubParamsLength=e;if(e>256)throw new Error("maxSubParamsLength must not be greater than 256");this.params=new Int32Array(i),this.length=0,this._subParams=new Int32Array(e),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(i),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}static fromArray(i){let e=new n;if(!i.length)return e;for(let t=Array.isArray(i[0])?1:0;t>8,r=this._subParamsIdx[e]&255;r-t>0&&i.push(Array.prototype.slice.call(this._subParams,t,r))}return i}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}resetZdm(){this.length=1,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1,this._subParamsIdx[0]=0,this.params[0]=0}addParam(i){if(this._digitIsSub=!1,this.length>=this.maxLength){this._rejectDigits=!0;return}if(i<-1)throw new Error("values less than -1 are not allowed");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=i>2147483647?2147483647:i}addSubParam(i){if(this._digitIsSub=!0,!!this.length){if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength){this._rejectSubDigits=!0;return}if(i<-1)throw new Error("values less than -1 are not allowed");this._subParams[this._subParamsLength++]=i>2147483647?2147483647:i,this._subParamsIdx[this.length-1]++}}hasSubParams(i){return(this._subParamsIdx[i]&255)-(this._subParamsIdx[i]>>8)>0}getSubParams(i){let e=this._subParamsIdx[i]>>8,t=this._subParamsIdx[i]&255;return t-e>0?this._subParams.subarray(e,t):null}getSubParamsAll(){let i={};for(let e=0;e>8,r=this._subParamsIdx[e]&255;r-t>0&&(i[e]=this._subParams.slice(t,r))}return i}addDigit(i){let e;if(this._rejectDigits||!(e=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;let t=this._digitIsSub?this._subParams:this.params,r=t[e-1];t[e-1]=~r?Math.min(r*10+i,2147483647):i}};var ni=[],cr=class{constructor(){this._state=0;this._active=ni;this._id=-1;this._handlers=Object.create(null);this._handlerFb=()=>{};this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(i,e){this._handlers[i]??=[];let t=this._handlers[i];return t.push(e),{dispose:()=>{let r=t.indexOf(e);r!==-1&&t.splice(r,1)}}}clearHandler(i){this._handlers[i]&&delete this._handlers[i]}setHandlerFallback(i){this._handlerFb=i}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=ni}reset(){if(this._state===2)for(let i=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;i>=0;--i)this._active[i].end(!1);this._stack.paused=!1,this._active=ni,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||ni,!this._active.length)this._handlerFb(this._id,"START");else for(let i=this._active.length-1;i>=0;i--)this._active[i].start()}_put(i,e,t){if(!this._active.length)this._handlerFb(this._id,"PUT",ye(i,e,t));else for(let r=this._active.length-1;r>=0;r--)this._active[r].put(i,e,t)}start(){this.reset(),this._state=1}put(i,e,t){if(this._state!==3){if(this._state===1)for(;e0&&this._put(i,e,t)}}end(i,e=!0){if(this._state!==0){if(this._state!==3)if(this._state===1&&this._start(),!this._active.length)this._handlerFb(this._id,"END",i);else{let t=!1,r=this._active.length-1,s=!1;if(this._stack.paused&&(r=this._stack.loopPosition-1,t=e,s=this._stack.fallThrough,this._stack.paused=!1),!s&&t===!1){for(;r>=0&&(t=this._active[r].end(i),t!==!0);r--)if(t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!1,t;r--}for(;r>=0;r--)if(t=this._active[r].end(!1),t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!0,t}this._active=ni,this._id=-1,this._state=0}}},hr=class hr{constructor(i){this._handler=i;this._data=new We(hr._payloadLimit);this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(i,e,t){this._hitLimit||this._data.append(ye(i,e,t))&&(this._hitLimit=!0)}end(i){let e=!1;if(this._hitLimit)e=!1;else if(i&&(e=this._handler(this._data.toString()),e instanceof Promise))return e.then(t=>(this._data.reset(),this._hitLimit=!1,t));return this._data.reset(),this._hitLimit=!1,e}};hr._payloadLimit=1e7;var ne=hr;var oi=[],dr=class{constructor(){this._handlers=Object.create(null);this._active=oi;this._ident=0;this._handlerFb=()=>{};this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=oi}registerHandler(i,e){this._handlers[i]??=[];let t=this._handlers[i];return t.push(e),{dispose:()=>{let r=t.indexOf(e);r!==-1&&t.splice(r,1)}}}clearHandler(i){this._handlers[i]&&delete this._handlers[i]}setHandlerFallback(i){this._handlerFb=i}reset(){if(this._active.length)for(let i=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;i>=0;--i)this._active[i].unhook(!1);this._stack.paused=!1,this._active=oi,this._ident=0}hook(i,e){if(this.reset(),this._ident=i,this._active=this._handlers[i]||oi,!this._active.length)this._handlerFb(this._ident,"HOOK",e);else for(let t=this._active.length-1;t>=0;t--)this._active[t].hook(e)}put(i,e,t){if(!this._active.length)this._handlerFb(this._ident,"PUT",ye(i,e,t));else for(let r=this._active.length-1;r>=0;r--)this._active[r].put(i,e,t)}unhook(i,e=!0){if(!this._active.length)this._handlerFb(this._ident,"UNHOOK",i);else{let t=!1,r=this._active.length-1,s=!1;if(this._stack.paused&&(r=this._stack.loopPosition-1,t=e,s=this._stack.fallThrough,this._stack.paused=!1),!s&&t===!1){for(;r>=0&&(t=this._active[r].unhook(i),t!==!0);r--)if(t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!1,t;r--}for(;r>=0;r--)if(t=this._active[r].unhook(!1),t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!0,t}this._active=oi,this._ident=0}},ai=new At;ai.addParam(0);var ur=class ur{constructor(i){this._handler=i;this._data=new We(ur._payloadLimit);this._params=ai;this._hitLimit=!1}hook(i){this._params=i.length>1||i.params[0]?i.clone():ai,this._data.reset(),this._hitLimit=!1}put(i,e,t){this._hitLimit||this._data.append(ye(i,e,t))&&(this._hitLimit=!0)}unhook(i){let e=!1;if(this._hitLimit)e=!1;else if(i&&(e=this._handler(this._data.toString(),this._params),e instanceof Promise))return e.then(t=>(this._params=ai,this._data.reset(),this._hitLimit=!1,t));return this._params=ai,this._data.reset(),this._hitLimit=!1,e}};ur._payloadLimit=1e7;var li=ur;var ci=[],fr=class{constructor(){this._handlers=Object.create(null);this._active=ci;this._ident=0;this._handlerFb=()=>{};this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(i,e){this._handlers[i]??=[];let t=this._handlers[i];return t.push(e),{dispose:()=>{let r=t.indexOf(e);r!==-1&&t.splice(r,1)}}}clearHandler(i){this._handlers[i]&&delete this._handlers[i]}setHandlerFallback(i){this._handlerFb=i}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=ci}reset(){if(this._active.length)for(let i=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;i>=0;--i)this._active[i].end(!1);this._stack.paused=!1,this._active=ci,this._ident=0}start(i){if(this.reset(),this._ident=i,this._active=this._handlers[i]||ci,!this._active.length)this._handlerFb(this._ident,"START");else for(let e=this._active.length-1;e>=0;e--)this._active[e].start()}put(i,e,t){if(!this._active.length)this._handlerFb(this._ident,"PUT",ye(i,e,t));else for(let r=this._active.length-1;r>=0;r--)this._active[r].put(i,e,t)}end(i,e=!0){if(!this._active.length)this._handlerFb(this._ident,"END",i);else{let t=!1,r=this._active.length-1,s=!1;if(this._stack.paused&&(r=this._stack.loopPosition-1,t=e,s=this._stack.fallThrough,this._stack.paused=!1),!s&&t===!1){for(;r>=0&&(t=this._active[r].end(i),t!==!0);r--)if(t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!1,t;r--}for(;r>=0;r--)if(t=this._active[r].end(!1),t instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=r,this._stack.fallThrough=!0,t}this._active=ci,this._ident=0}},pr=class pr{constructor(i){this._handler=i;this._data=new We(pr._payloadLimit);this._hitLimit=!1}start(){this._data.reset(),this._hitLimit=!1}put(i,e,t){this._hitLimit||this._data.append(ye(i,e,t))&&(this._hitLimit=!0)}end(i){let e=!1;if(this._hitLimit)e=!1;else if(i&&(e=this._handler(this._data.toString()),e instanceof Promise))return e.then(t=>(this._data.reset(),this._hitLimit=!1,t));return this._data.reset(),this._hitLimit=!1,e}};pr._payloadLimit=1e7;var _r=pr;var Cs=class{constructor(i){this.table=new Uint16Array(i)}setDefault(i,e){this.table.fill(i<<8|e)}add(i,e,t,r){this.table[e<<8|i]=t<<8|r}addMany(i,e,t,r){for(let s=0;sl),t=(a,l)=>e.slice(a,l),r=t(32,127),s=t(0,24);s.push(25),s.push.apply(s,t(28,32));let o=t(0,17);n.setDefault(1,0),n.addMany(r,0,2,0);for(let a of o)n.addMany([24,26,153,154],a,3,0),n.addMany(t(128,144),a,3,0),n.addMany(t(144,152),a,3,0),n.add(156,a,0,0),n.add(27,a,11,1),n.add(157,a,4,8),n.addMany([152,158],a,0,7),n.add(159,a,11,14),n.add(155,a,11,3),n.add(144,a,11,9);return n.addMany(s,0,3,0),n.addMany(s,1,3,1),n.add(127,1,0,1),n.addMany(s,8,0,8),n.addMany(s,3,3,3),n.add(127,3,0,3),n.addMany(s,4,3,4),n.add(127,4,0,4),n.addMany(s,6,3,6),n.addMany(s,5,3,5),n.add(127,5,0,5),n.addMany(s,2,3,2),n.add(127,2,0,2),n.add(93,1,4,8),n.addMany(r,8,5,8),n.add(127,8,5,8),n.addMany([156,27,24,26,7],8,6,0),n.addMany(t(28,32),8,0,8),n.addMany([88,94],1,0,7),n.addMany(r,7,0,7),n.addMany(s,7,0,7),n.add(156,7,0,0),n.add(127,7,0,7),n.add(95,1,11,14),n.addMany(s,14,0,14),n.add(127,14,0,14),n.addMany(t(32,48),14,9,15),n.addMany(t(48,127),14,15,16),n.addMany(t(48,127),15,15,16),n.addMany(s,15,0,15),n.addMany(t(32,48),15,9,15),n.add(127,15,0,15),n.addMany(r,16,16,16),n.addMany(s,16,0,16),n.addMany(t(8,14),16,16,16),n.add(127,16,0,16),n.addMany([27,156,24,26],16,17,0),n.add(91,1,11,3),n.addMany(t(64,127),3,7,0),n.addMany(t(48,60),3,8,4),n.addMany([60,61,62,63],3,9,4),n.addMany(t(48,60),4,8,4),n.addMany(t(64,127),4,7,0),n.addMany([60,61,62,63],4,0,6),n.addMany(t(32,64),6,0,6),n.add(127,6,0,6),n.addMany(t(64,127),6,0,0),n.addMany(t(32,48),3,9,5),n.addMany(t(32,48),5,9,5),n.addMany(t(48,64),5,0,6),n.addMany(t(64,127),5,7,0),n.addMany(t(32,48),4,9,5),n.addMany(t(32,48),1,9,2),n.addMany(t(32,48),2,9,2),n.addMany(t(48,127),2,10,0),n.addMany(t(48,80),1,10,0),n.addMany(t(81,88),1,10,0),n.addMany([89,90,92],1,10,0),n.addMany(t(96,127),1,10,0),n.add(80,1,11,9),n.addMany(s,9,0,9),n.add(127,9,0,9),n.addMany(t(32,48),9,9,12),n.addMany(t(48,60),9,8,10),n.addMany([60,61,62,63],9,9,10),n.addMany(s,11,0,11),n.addMany(t(32,128),11,0,11),n.addMany(s,10,0,10),n.add(127,10,0,10),n.addMany(t(48,60),10,8,10),n.addMany([60,61,62,63],10,0,11),n.addMany(t(32,48),10,9,12),n.addMany(s,12,0,12),n.add(127,12,0,12),n.addMany(t(32,48),12,9,12),n.addMany(t(48,64),12,0,11),n.addMany(t(64,127),12,12,13),n.addMany(t(64,127),10,12,13),n.addMany(t(64,127),9,12,13),n.addMany(s,13,13,13),n.addMany(r,13,13,13),n.add(127,13,0,13),n.addMany([27,156,24,26],13,14,0),n.add(oe,0,2,0),n.add(oe,8,5,8),n.add(oe,6,0,6),n.add(oe,11,0,11),n.add(oe,13,13,13),n.add(oe,16,16,16),n})(),mr=class extends g{constructor(e=So){super();this._transitions=e;this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0};this.initialState=0,this.currentState=this.initialState,this._params=new At,this._params.addParam(0),this._collect=0,this.precedingJoinState=0,this._printHandlerFb=(t,r,s)=>{},this._executeHandlerFb=t=>{},this._csiHandlerFb=(t,r)=>{},this._escHandlerFb=t=>{},this._errorHandlerFb=t=>t,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this._register(E(()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._executeHandlersArr=new Array(24).fill(void 0),this._escHandlers=Object.create(null)})),this._oscParser=this._register(new cr),this._dcsParser=this._register(new dr),this._apcParser=this._register(new fr),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:"\\"},()=>!0)}_identifier(e,t=[64,126]){let r=0;if(e.prefix){if(e.prefix.length>1)throw new Error("only one byte as prefix supported");if(r=e.prefix.charCodeAt(0),r<60||r>63)throw new Error("prefix must be in range 0x3c .. 0x3f")}if(e.intermediates){if(e.intermediates.length>2)throw new Error("only two bytes as intermediates are supported");for(let o=0;oa||a>47)throw new Error("intermediate must be in range 0x20 .. 0x2f");r<<=8,r|=a}}if(e.final.length!==1)throw new Error("final must be a single byte");let s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return r<<=8,r|=s,r}identToString(e){let t=[];for(;e;)t.push(String.fromCharCode(e&255)),e>>=8;return t.reverse().join("")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){let r=this._identifier(e,[48,126]);this._escHandlers[r]??=[];let s=this._escHandlers[r];return s.push(t),{dispose:()=>{let o=s.indexOf(t);o!==-1&&s.splice(o,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){let r=e.charCodeAt(0);this._executeHandlers[r]=t,r<24&&(this._executeHandlersArr[r]=t)}clearExecuteHandler(e){let t=e.charCodeAt(0);this._executeHandlers[t]&&delete this._executeHandlers[t],t<24&&(this._executeHandlersArr[t]=void 0)}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){let r=this._identifier(e);this._csiHandlers[r]??=[];let s=this._csiHandlers[r];return s.push(t),{dispose:()=>{let o=s.indexOf(t);o!==-1&&s.splice(o,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}registerApcHandler(e,t){return e.prefix=void 0,this._apcParser.registerHandler(this._identifier(e,[48,126]),t)}clearApcHandler(e){e.prefix=void 0,this._apcParser.clearHandler(this._identifier(e,[48,126]))}setApcHandlerFallback(e){this._apcParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._apcParser.reset(),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0,this._parseStack.state!==0&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,r,s,o){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=r,this._parseStack.transition=s,this._parseStack.chunkPos=o}parse(e,t,r){let s,o,a=0,l;if(this._parseStack.state)if(this._parseStack.state===2)this._parseStack.state=0,a=this._parseStack.chunkPos+1;else{if(r===void 0||this._parseStack.state===1)throw this._parseStack.state=1,new Error("improper continuation due to previous async handler, giving up parsing");let h=this._parseStack.handlers,d=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(r===!1&&d>-1){for(;d>=0&&(l=h[d](this._params),l!==!0);d--)if(l instanceof Promise)return this._parseStack.handlerPos=d,l}this._parseStack.handlers=[];break;case 4:if(r===!1&&d>-1){for(;d>=0&&(l=h[d](),l!==!0);d--)if(l instanceof Promise)return this._parseStack.handlerPos=d,l}this._parseStack.handlers=[];break;case 6:if(s=e[this._parseStack.chunkPos],l=this._dcsParser.unhook(s!==24&&s!==26,r),l)return l;s===27&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 5:if(s=e[this._parseStack.chunkPos],l=this._oscParser.end(s!==24&&s!==26,r),l)return l;s===27&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break;case 7:if(s=e[this._parseStack.chunkPos],l=this._apcParser.end(s!==24&&s!==26,r),l)return l;s===27&&(this._parseStack.transition|=1),this._params.resetZdm(),this._collect=0;break}this._parseStack.state=0,a=this._parseStack.chunkPos+1,this.precedingJoinState=0,this.currentState=this._parseStack.transition&255}for(let h=a;h=60&&c<=63&&(this._collect=c,d++);let u=!1;for(;d=48&&c<=57)this._params.addDigit(c-48);else if(c===59)this._params.addParam(0);else if(c===58)this._params.addSubParam(-1);else if(c>=64&&c<=126){let _=this._csiHandlers[this._collect<<8|c],p=_?_.length-1:-1;for(;p>=0&&(l=_[p](this._params),l!==!0);p--)if(l instanceof Promise)return o=1792,this._preserveStack(3,_,p,o,d),l;p<0&&this._csiHandlerFb(this._collect<<8|c,this._params),this.precedingJoinState=0,h=d,this.currentState=0,u=!0;break}else break;u||(h=d-1,this.currentState=4);continue}switch(o=this._transitions.table[this.currentState<<8|(s>8){case 2:let d=h,c=t-4;for(;d=32&&(e[d]<=126||e[d]>=oe)&&e[++d]>=32&&(e[d]<=126||e[d]>=oe)&&e[++d]>=32&&(e[d]<=126||e[d]>=oe)&&e[++d]>=32&&(e[d]<=126||e[d]>=oe););if(d>=c)for(;d=32&&(e[d]<=126||e[d]>=oe);)d++;this._printHandler(e,h,d),h=d-1;break;case 3:this._executeHandlers[s]?this._executeHandlers[s]():this._executeHandlerFb(s),this.precedingJoinState=0;break;case 0:break;case 1:if(this._errorHandler({position:h,code:s,currentState:this.currentState,collect:this._collect,params:this._params,abort:!1}).abort)return;break;case 7:let _=this._csiHandlers[this._collect<<8|s],p=_?_.length-1:-1;for(;p>=0&&(l=_[p](this._params),l!==!0);p--)if(l instanceof Promise)return this._preserveStack(3,_,p,o,h),l;p<0&&this._csiHandlerFb(this._collect<<8|s,this._params),this.precedingJoinState=0;break;case 8:do switch(s){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(s-48)}while(++h47&&s<60);h--;break;case 9:this._collect<<=8,this._collect|=s;break;case 10:let v=this._escHandlers[this._collect<<8|s],f=v?v.length-1:-1;for(;f>=0&&(l=v[f](),l!==!0);f--)if(l instanceof Promise)return this._preserveStack(4,v,f,o,h),l;f<0&&this._escHandlerFb(this._collect<<8|s),this.precedingJoinState=0;break;case 11:this._params.resetZdm(),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|s,this._params);break;case 13:for(let S=h+1;;++S)if(S>=t||(s=e[S])===24||s===26||s===27||s>127&&s=t||(s=e[S])<32||s>127&&s=32&&e[S]<127||e[S]>=8&&e[S]<14||e[S]>=oe))){this._apcParser.put(e,h,S),h=S-1;break}break;case 17:if(l=this._apcParser.end(s!==24&&s!==26),l)return this._preserveStack(7,[],0,o,h),l;s===27&&(o|=1),this._params.resetZdm(),this._collect=0,this.precedingJoinState=0;break}this.currentState=o&255}}};var go=/^([\da-f])\/([\da-f])\/([\da-f])$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/,Io=/^[\da-f]+$/;function ys(n){if(!n)return;let i=n.toLowerCase();if(i.startsWith("rgb:")){i=i.slice(4);let e=go.exec(i);if(e){let t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(i.startsWith("#")&&(i=i.slice(1),Io.exec(i)&&[3,6,9,12].includes(i.length))){let e=i.length/3,t=[0,0,0];for(let r=0;r<3;++r){let s=parseInt(i.slice(e*r,e*r+e),16);t[r]=e===1?s<<4:e===2?s:e===3?s>>4:s>>8}return t}}function Es(n,i){let e=n.toString(16),t=e.length<2?"0"+e:e;switch(i){case 4:return e[0];case 8:return t;case 12:return(t+t).slice(0,3);default:return t+t}}function En(n,i=16){let[e,t,r]=n;return`rgb:${Es(e,i)}/${Es(t,i)}/${Es(r,i)}`}var yn="6.1.0-beta.287";var Eo={"(":0,")":1,"*":2,"+":3,"-":1,".":2};function xn(n,i){if(n>24)return i.setWinLines||!1;switch(n){case 1:return!!i.restoreWin;case 2:return!!i.minimizeWin;case 3:return!!i.setWinPosition;case 4:return!!i.setWinSizePixels;case 5:return!!i.raiseWin;case 6:return!!i.lowerWin;case 7:return!!i.refreshWin;case 8:return!!i.setWinSizeChars;case 9:return!!i.maximizeWin;case 10:return!!i.fullscreenWin;case 11:return!!i.getWinState;case 13:return!!i.getWinPosition;case 14:return!!i.getWinSizePixels;case 15:return!!i.getScreenSizePixels;case 16:return!!i.getCellSizePixels;case 18:return!!i.getWinSizeChars;case 19:return!!i.getScreenSizeChars;case 20:return!!i.getIconTitle;case 21:return!!i.getWinTitle;case 22:return!!i.pushTitle;case 23:return!!i.popTitle;case 24:return!!i.setWinLines}return!1}var wn=0,br=class extends g{constructor(e,t,r,s,o,a,l,h,d=new mr){super();this._bufferService=e;this._charsetService=t;this._coreService=r;this._logService=s;this._optionsService=o;this._oscLinkService=a;this._mouseStateService=l;this._unicodeService=h;this._parser=d;this._parseBuffer=new Uint32Array(4096);this._stringDecoder=new mi;this._utf8Decoder=new bi;this._windowTitle="";this._iconName="";this._windowTitleStack=[];this._iconNameStack=[];this._curAttrData=U.clone();this._eraseAttrDataInternal=U.clone();this._onRequestBell=this._register(new b);this.onRequestBell=this._onRequestBell.event;this._onRequestRefreshRows=this._register(new b);this.onRequestRefreshRows=this._onRequestRefreshRows.event;this._onRequestReset=this._register(new b);this.onRequestReset=this._onRequestReset.event;this._onRequestSendFocus=this._register(new b);this.onRequestSendFocus=this._onRequestSendFocus.event;this._onRequestSyncScrollBar=this._register(new b);this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event;this._onRequestWindowsOptionsReport=this._register(new b);this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event;this._onA11yChar=this._register(new b);this.onA11yChar=this._onA11yChar.event;this._onA11yTab=this._register(new b);this.onA11yTab=this._onA11yTab.event;this._onCursorMove=this._register(new b);this.onCursorMove=this._onCursorMove.event;this._onLineFeed=this._register(new b);this.onLineFeed=this._onLineFeed.event;this._onScroll=this._register(new b);this.onScroll=this._onScroll.event;this._onTitleChange=this._register(new b);this.onTitleChange=this._onTitleChange.event;this._onColor=this._register(new b);this.onColor=this._onColor.event;this._onRequestColorSchemeQuery=this._register(new b);this.onRequestColorSchemeQuery=this._onRequestColorSchemeQuery.event;this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0};this._specialColors=[256,257,258];this._register(this._parser),this._dirtyRowTracker=new hi(this._bufferService),this._activeBuffer=this._bufferService.buffer,this._register(this._bufferService.buffers.onBufferActivate(c=>this._activeBuffer=c.activeBuffer)),this._parser.setCsiHandlerFallback((c,u)=>{this._logService.debug("Unknown CSI code: ",{identifier:this._parser.identToString(c),params:u.toArray()})}),this._parser.setEscHandlerFallback(c=>{this._logService.debug("Unknown ESC code: ",{identifier:this._parser.identToString(c)})}),this._parser.setExecuteHandlerFallback(c=>{this._logService.debug("Unknown EXECUTE code: ",{code:c})}),this._parser.setOscHandlerFallback((c,u,_)=>{this._logService.debug("Unknown OSC code: ",{identifier:c,action:u,data:_})}),this._parser.setDcsHandlerFallback((c,u,_)=>{u==="HOOK"&&(_=_.toArray()),this._logService.debug("Unknown DCS code: ",{identifier:this._parser.identToString(c),action:u,payload:_})}),this._parser.setApcHandlerFallback((c,u,_)=>{this._logService.debug("Unknown APC code: ",{identifier:this._parser.identToString(c),action:u,payload:_})}),this._parser.setPrintHandler((c,u,_)=>this.print(c,u,_)),this._parser.registerCsiHandler({final:"@"},c=>this.insertChars(c)),this._parser.registerCsiHandler({intermediates:" ",final:"@"},c=>this.scrollLeft(c)),this._parser.registerCsiHandler({final:"A"},c=>this.cursorUp(c)),this._parser.registerCsiHandler({intermediates:" ",final:"A"},c=>this.scrollRight(c)),this._parser.registerCsiHandler({final:"B"},c=>this.cursorDown(c)),this._parser.registerCsiHandler({final:"C"},c=>this.cursorForward(c)),this._parser.registerCsiHandler({final:"D"},c=>this.cursorBackward(c)),this._parser.registerCsiHandler({final:"E"},c=>this.cursorNextLine(c)),this._parser.registerCsiHandler({final:"F"},c=>this.cursorPrecedingLine(c)),this._parser.registerCsiHandler({final:"G"},c=>this.cursorCharAbsolute(c)),this._parser.registerCsiHandler({final:"H"},c=>this.cursorPosition(c)),this._parser.registerCsiHandler({final:"I"},c=>this.cursorForwardTab(c)),this._parser.registerCsiHandler({final:"J"},c=>this.eraseInDisplay(c,!1)),this._parser.registerCsiHandler({prefix:"?",final:"J"},c=>this.eraseInDisplay(c,!0)),this._parser.registerCsiHandler({final:"K"},c=>this.eraseInLine(c,!1)),this._parser.registerCsiHandler({prefix:"?",final:"K"},c=>this.eraseInLine(c,!0)),this._parser.registerCsiHandler({final:"L"},c=>this.insertLines(c)),this._parser.registerCsiHandler({final:"M"},c=>this.deleteLines(c)),this._parser.registerCsiHandler({final:"P"},c=>this.deleteChars(c)),this._parser.registerCsiHandler({final:"S"},c=>this.scrollUp(c)),this._parser.registerCsiHandler({final:"T"},c=>this.scrollDown(c)),this._parser.registerCsiHandler({final:"X"},c=>this.eraseChars(c)),this._parser.registerCsiHandler({final:"Z"},c=>this.cursorBackwardTab(c)),this._parser.registerCsiHandler({final:"^"},c=>this.scrollDown(c)),this._parser.registerCsiHandler({final:"`"},c=>this.charPosAbsolute(c)),this._parser.registerCsiHandler({final:"a"},c=>this.hPositionRelative(c)),this._parser.registerCsiHandler({final:"b"},c=>this.repeatPrecedingCharacter(c)),this._parser.registerCsiHandler({final:"c"},c=>this.sendDeviceAttributesPrimary(c)),this._parser.registerCsiHandler({prefix:">",final:"c"},c=>this.sendDeviceAttributesSecondary(c)),this._parser.registerCsiHandler({final:"d"},c=>this.linePosAbsolute(c)),this._parser.registerCsiHandler({final:"e"},c=>this.vPositionRelative(c)),this._parser.registerCsiHandler({final:"f"},c=>this.hVPosition(c)),this._parser.registerCsiHandler({final:"g"},c=>this.tabClear(c)),this._parser.registerCsiHandler({final:"h"},c=>this.setMode(c)),this._parser.registerCsiHandler({prefix:"?",final:"h"},c=>this.setModePrivate(c)),this._parser.registerCsiHandler({final:"l"},c=>this.resetMode(c)),this._parser.registerCsiHandler({prefix:"?",final:"l"},c=>this.resetModePrivate(c)),this._parser.registerCsiHandler({final:"m"},c=>this.charAttributes(c)),this._parser.registerCsiHandler({final:"n"},c=>this.deviceStatus(c)),this._parser.registerCsiHandler({prefix:"?",final:"n"},c=>this.deviceStatusPrivate(c)),this._parser.registerCsiHandler({intermediates:"!",final:"p"},c=>this.softReset(c)),this._parser.registerCsiHandler({prefix:">",final:"q"},c=>this.sendXtVersion(c)),this._parser.registerCsiHandler({intermediates:" ",final:"q"},c=>this.setCursorStyle(c)),this._parser.registerCsiHandler({final:"r"},c=>this.setScrollRegion(c)),this._parser.registerCsiHandler({final:"s"},c=>this.saveCursor(c)),this._parser.registerCsiHandler({final:"t"},c=>this.windowOptions(c)),this._parser.registerCsiHandler({final:"u"},c=>this.restoreCursor(c)),this._parser.registerCsiHandler({intermediates:"'",final:"}"},c=>this.insertColumns(c)),this._parser.registerCsiHandler({intermediates:"'",final:"~"},c=>this.deleteColumns(c)),this._parser.registerCsiHandler({intermediates:'"',final:"q"},c=>this.selectProtected(c)),this._parser.registerCsiHandler({intermediates:"$",final:"p"},c=>this.requestMode(c,!0)),this._parser.registerCsiHandler({prefix:"?",intermediates:"$",final:"p"},c=>this.requestMode(c,!1)),this._parser.registerCsiHandler({prefix:"=",final:"u"},c=>this.kittyKeyboardSet(c)),this._parser.registerCsiHandler({prefix:"?",final:"u"},c=>this.kittyKeyboardQuery(c)),this._parser.registerCsiHandler({prefix:">",final:"u"},c=>this.kittyKeyboardPush(c)),this._parser.registerCsiHandler({prefix:"<",final:"u"},c=>this.kittyKeyboardPop(c)),this._parser.setExecuteHandler("\x07",()=>this.bell()),this._parser.setExecuteHandler(` -`,()=>this.lineFeed()),this._parser.setExecuteHandler("\v",()=>this.lineFeed()),this._parser.setExecuteHandler("\f",()=>this.lineFeed()),this._parser.setExecuteHandler("\r",()=>this.carriageReturn()),this._parser.setExecuteHandler("\b",()=>this.backspace()),this._parser.setExecuteHandler(" ",()=>this.tab()),this._parser.setExecuteHandler("",()=>this.shiftOut()),this._parser.setExecuteHandler("",()=>this.shiftIn()),this._parser.setExecuteHandler("\x84",()=>this.index()),this._parser.setExecuteHandler("\x85",()=>this.nextLine()),this._parser.setExecuteHandler("\x88",()=>this.tabSet()),this._parser.registerOscHandler(0,new ne(c=>(this.setTitle(c),this.setIconName(c),!0))),this._parser.registerOscHandler(1,new ne(c=>this.setIconName(c))),this._parser.registerOscHandler(2,new ne(c=>this.setTitle(c))),this._parser.registerOscHandler(4,new ne(c=>this.setOrReportIndexedColor(c))),this._parser.registerOscHandler(8,new ne(c=>this.setHyperlink(c))),this._parser.registerOscHandler(10,new ne(c=>this.setOrReportFgColor(c))),this._parser.registerOscHandler(11,new ne(c=>this.setOrReportBgColor(c))),this._parser.registerOscHandler(12,new ne(c=>this.setOrReportCursorColor(c))),this._parser.registerOscHandler(104,new ne(c=>this.restoreIndexedColor(c))),this._parser.registerOscHandler(110,new ne(c=>this.restoreFgColor(c))),this._parser.registerOscHandler(111,new ne(c=>this.restoreBgColor(c))),this._parser.registerOscHandler(112,new ne(c=>this.restoreCursorColor(c))),this._parser.registerEscHandler({final:"7"},()=>this.saveCursor()),this._parser.registerEscHandler({final:"8"},()=>this.restoreCursor()),this._parser.registerEscHandler({final:"D"},()=>this.index()),this._parser.registerEscHandler({final:"E"},()=>this.nextLine()),this._parser.registerEscHandler({final:"H"},()=>this.tabSet()),this._parser.registerEscHandler({final:"M"},()=>this.reverseIndex()),this._parser.registerEscHandler({final:"="},()=>this.keypadApplicationMode()),this._parser.registerEscHandler({final:">"},()=>this.keypadNumericMode()),this._parser.registerEscHandler({final:"c"},()=>this.fullReset()),this._parser.registerEscHandler({final:"n"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"o"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"|"},()=>this.setgLevel(3)),this._parser.registerEscHandler({final:"}"},()=>this.setgLevel(2)),this._parser.registerEscHandler({final:"~"},()=>this.setgLevel(1)),this._parser.registerEscHandler({intermediates:"%",final:"@"},()=>this.selectDefaultCharset()),this._parser.registerEscHandler({intermediates:"%",final:"G"},()=>this.selectDefaultCharset());for(let c in q)this._parser.registerEscHandler({intermediates:"(",final:c},()=>this.selectCharset("("+c)),this._parser.registerEscHandler({intermediates:")",final:c},()=>this.selectCharset(")"+c)),this._parser.registerEscHandler({intermediates:"*",final:c},()=>this.selectCharset("*"+c)),this._parser.registerEscHandler({intermediates:"+",final:c},()=>this.selectCharset("+"+c)),this._parser.registerEscHandler({intermediates:"-",final:c},()=>this.selectCharset("-"+c)),this._parser.registerEscHandler({intermediates:".",final:c},()=>this.selectCharset("."+c)),this._parser.registerEscHandler({intermediates:"/",final:c},()=>this.selectCharset("/"+c));this._parser.registerEscHandler({intermediates:"#",final:"8"},()=>this.screenAlignmentPattern()),this._parser.setErrorHandler(c=>(this._logService.error("Parsing error: ",c),c)),this._parser.registerDcsHandler({intermediates:"$",final:"q"},new li((c,u)=>this.requestStatusString(c,u)))}getAttrData(){return this._curAttrData}_preserveStack(e,t,r,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=r,this._parseStack.position=s}_logSlowResolvingAsync(e){if(this._logService.logLevel<=3){let t,r=new Promise((s,o)=>{t=setTimeout(()=>o("#SLOW_TIMEOUT"),5e3)});Promise.race([e,r]).then(()=>{t!==void 0&&clearTimeout(t)},s=>{if(t!==void 0&&clearTimeout(t),s!=="#SLOW_TIMEOUT")throw s;console.warn("async parser handler taking longer than 5000 ms")})}}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let r,s=this._activeBuffer.x,o=this._activeBuffer.y,a=0,l=this._parseStack.paused;if(l){if(r=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(r),r;s=this._parseStack.cursorStartX,o=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>131072&&(a=this._parseStack.position+131072)}if(this._logService.logLevel<=1&&this._logService.debug(`parsing data ${typeof e=="string"?` "${e}"`:` "${Array.prototype.map.call(e,c=>String.fromCharCode(c)).join("")}"`}`),this._logService.logLevel===0&&this._logService.trace("parsing data (codes)",typeof e=="string"?e.split("").map(c=>c.charCodeAt(0)):e),this._parseBuffer.length131072)for(let c=a;c0&&_.getWidth(this._activeBuffer.x-1)===2&&_.setCellFromCodepoint(this._activeBuffer.x-1,0,1,u);let p=this._parser.precedingJoinState;for(let v=t;vh){if(d){let L=_,T=this._activeBuffer.x-I;if(this._activeBuffer.x=I,this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData(),!0)):(this._activeBuffer.y>=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),_=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y),!_)return;for(I>0&&_ instanceof De&&_.copyCellsFrom(L,T,0,I,!1);T=0;)_.setCellFromCodepoint(this._activeBuffer.x++,0,0,u);continue}if(c&&(_.insertCells(this._activeBuffer.x,o-I,this._activeBuffer.getNullCell(u)),_.getWidth(h-1)===2&&_.setCellFromCodepoint(h-1,0,1,u)),_.setCellFromCodepoint(this._activeBuffer.x++,s,o,u),o>0)for(;--o;)_.setCellFromCodepoint(this._activeBuffer.x++,0,0,u)}this._parser.precedingJoinState=p,this._activeBuffer.x0&&_.getWidth(this._activeBuffer.x)===0&&!_.hasContent(this._activeBuffer.x)&&_.setCellFromCodepoint(this._activeBuffer.x,0,1,u),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return e.final==="t"&&!e.prefix&&!e.intermediates?this._parser.registerCsiHandler(e,r=>xn(r.params[0],this._optionsService.rawOptions.windowOptions)?t(r):!0):this._parser.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new li(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new ne(t))}registerApcHandler(e,t){return this._parser.registerApcHandler(e,new _r(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(this._activeBuffer.x===0&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)?.isWrapped){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;let e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){let t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){let t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){let t=e.params[0];return t===0?delete this._activeBuffer.tabs[this._activeBuffer.x]:t===3&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){let t=e.params[0];return t===1&&(this._curAttrData.bg|=536870912),(t===2||t===0)&&(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,r,s=!1,o=!1){let a=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);a&&(a.replaceCells(t,r,this._activeBuffer.getNullCell(this._eraseAttrData()),o),s&&(a.isWrapped=!1))}_resetBufferLine(e,t=!1){let r=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);r&&(r.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),r.isWrapped=!1)}eraseInDisplay(e,t=!1){this._restrictCursor(this._bufferService.cols);let r;switch(e.params[0]){case 0:for(r=this._activeBuffer.y,this._dirtyRowTracker.markDirty(r),this._eraseInBufferLine(r++,this._activeBuffer.x,this._bufferService.cols,this._activeBuffer.x===0,t);r=this._bufferService.cols){let o=this._activeBuffer.lines.get(r+1);o&&(o.isWrapped=!1)}for(;r--;)this._resetBufferLine(r,t);this._dirtyRowTracker.markDirty(0);break;case 2:if(this._optionsService.rawOptions.scrollOnEraseInDisplay){for(r=this._bufferService.rows,this._dirtyRowTracker.markRangeDirty(0,r-1);r--&&!this._activeBuffer.lines.get(this._activeBuffer.ybase+r)?.getTrimmedLength(););for(;r>=0;r--)this._bufferService.scroll(this._eraseAttrData())}else{for(r=this._bufferService.rows,this._dirtyRowTracker.markDirty(r-1);r--;)this._resetBufferLine(r,t);this._dirtyRowTracker.markDirty(0)}break;case 3:let s=this._activeBuffer.lines.length-this._bufferService.rows;s>0&&(this._activeBuffer.lines.trimStart(s),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-s,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-s,0),this._onScroll.fire(0));break}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,this._activeBuffer.x===0,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t);break}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y65535?2:1}let c=d;for(let u=1;u0||(this._is("xterm")||this._is("rxvt-unicode")||this._is("screen")?this._coreService.triggerDataEvent("\x1B[?1;2c"):this._is("linux")&&this._coreService.triggerDataEvent("\x1B[?6c")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is("xterm")?this._coreService.triggerDataEvent("\x1B[>0;276;0c"):this._is("rxvt-unicode")?this._coreService.triggerDataEvent("\x1B[>85;95;0c"):this._is("linux")?this._coreService.triggerDataEvent(e.params[0]+"c"):this._is("screen")&&this._coreService.triggerDataEvent("\x1B[>83;40003;0c")),!0}sendXtVersion(e){return e.params[0]>0||this._coreService.triggerDataEvent(`\x1BP>|xterm.js(${yn})\x1B\\`),!0}_is(e){return(this._optionsService.rawOptions.termName+"").startsWith(e)}setMode(e){for(let t=0;t(te[te.NOT_RECOGNIZED=0]="NOT_RECOGNIZED",te[te.SET=1]="SET",te[te.RESET=2]="RESET",te[te.PERMANENTLY_SET=3]="PERMANENTLY_SET",te[te.PERMANENTLY_RESET=4]="PERMANENTLY_RESET"))(r||={});let s=this._coreService.decPrivateModes,{activeProtocol:o,activeEncoding:a}=this._mouseStateService,l=this._coreService,{buffers:h,cols:d}=this._bufferService,{active:c,alt:u}=h,_=this._optionsService.rawOptions,p=(S,I)=>(l.triggerDataEvent(`\x1B[${t?"":"?"}${S};${I}$y`),!0),v=S=>S?1:2,f=e.params[0];return t?f===2?p(f,4):f===4?p(f,v(l.modes.insertMode)):f===12?p(f,3):f===20?p(f,v(_.convertEol)):p(f,0):f===1?p(f,v(s.applicationCursorKeys)):f===3?p(f,_.windowOptions.setWinLines?d===80?2:d===132?1:0:0):f===6?p(f,v(s.origin)):f===7?p(f,v(s.wraparound)):f===8?p(f,3):f===9?p(f,v(o==="X10")):f===12?p(f,v(_.cursorBlink)):f===25?p(f,v(!l.isCursorHidden)):f===45?p(f,v(s.reverseWraparound)):f===66?p(f,v(s.applicationKeypad)):f===67?p(f,4):f===1e3?p(f,v(o==="VT200")):f===1002?p(f,v(o==="DRAG")):f===1003?p(f,v(o==="ANY")):f===1004?p(f,v(s.sendFocus)):f===1005?p(f,4):f===1006?p(f,v(a==="SGR")):f===1015?p(f,4):f===1016?p(f,v(a==="SGR_PIXELS")):f===1048?p(f,1):f===47||f===1047||f===1049?p(f,v(c===u)):f===2004?p(f,v(s.bracketedPasteMode)):f===2026?p(f,v(s.synchronizedOutput)):f===9001&&this._optionsService.rawOptions.vtExtensions?.win32InputMode?p(f,v(s.win32InputMode)):p(f,0)}_updateAttrColor(e,t,r,s,o){return t===2?(e|=50331648,e&=-16777216,e|=ue.fromColorRGB([r,s,o])):t===5&&(e&=-67108864,e|=33554432|r&255),e}_extractColor(e,t,r){let s=[0,0,-1,0,0,0],o=0,a=0;do{if(s[a+o]=e.params[t+a],e.hasSubParams(t+a)){let l=e.getSubParams(t+a),h=0;do s[1]===5&&(o=1),s[a+h+1+o]=l[h];while(++h=2||s[1]===2&&a+o>=5)break;s[1]&&(o=1)}while(++a+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,e===0&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=U.fg,e.bg=U.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(e.length===1&&e.params[0]===0)return this._processSGR0(this._curAttrData),!0;let t=e.length,r,s=this._curAttrData;for(let o=0;o=30&&r<=37?(s.fg&=-67108864,s.fg|=16777216|r-30):r>=40&&r<=47?(s.bg&=-67108864,s.bg|=16777216|r-40):r>=90&&r<=97?(s.fg&=-67108864,s.fg|=16777216|r-90|8):r>=100&&r<=107?(s.bg&=-67108864,s.bg|=16777216|r-100|8):r===0?this._processSGR0(s):r===1?s.fg|=134217728:r===3?s.bg|=67108864:r===4?(s.fg|=268435456,this._processUnderline(e.hasSubParams(o)?e.getSubParams(o)[0]:1,s)):r===5?s.fg|=536870912:r===7?s.fg|=67108864:r===8?s.fg|=1073741824:r===9?s.fg|=2147483648:r===2?s.bg|=134217728:r===21?this._processUnderline(2,s):r===22?(s.fg&=-134217729,s.bg&=-134217729):r===23?s.bg&=-67108865:r===24?(s.fg&=-268435457,this._processUnderline(0,s)):r===25?s.fg&=-536870913:r===27?s.fg&=-67108865:r===28?s.fg&=-1073741825:r===29?s.fg&=2147483647:r===39?(s.fg&=-67108864,s.fg|=U.fg&16777215):r===49?(s.bg&=-67108864,s.bg|=U.bg&16777215):r===38||r===48||r===58?o+=this._extractColor(e,o,s):r===53?s.bg|=1073741824:r===55?s.bg&=-1073741825:r===221&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??!0)?s.fg&=-134217729:r===222&&(this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl??!0)?s.bg&=-134217729:r===59?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):this._logService.debug("Unknown SGR attribute: %d.",r);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent("\x1B[0n");break;case 6:let t=this._activeBuffer.y+1,r=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`\x1B[${t};${r}R`);break}return!0}deviceStatusPrivate(e){switch(e.params[0]){case 6:let t=this._activeBuffer.y+1,r=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`\x1B[?${t};${r}R`);break;case 15:break;case 25:break;case 26:break;case 53:break;case 996:(this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery??!0)&&this._onRequestColorSchemeQuery.fire();break}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=U.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){let t=e.length===0?1:e.params[0];if(t===0)this._coreService.decPrivateModes.cursorStyle=void 0,this._coreService.decPrivateModes.cursorBlink=void 0;else{switch(t){case 1:case 2:this._coreService.decPrivateModes.cursorStyle="block";break;case 3:case 4:this._coreService.decPrivateModes.cursorStyle="underline";break;case 5:case 6:this._coreService.decPrivateModes.cursorStyle="bar";break}let r=t%2===1;this._coreService.decPrivateModes.cursorBlink=r}return!0}setScrollRegion(e){let t=e.params[0]||1,r;return(e.length<2||(r=e.params[1])>this._bufferService.rows||r===0)&&(r=this._bufferService.rows),r>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=r-1,this._setCursor(0,0)),!0}windowOptions(e){if(!xn(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;let t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:t!==2&&this._onRequestWindowsOptionsReport.fire(0);break;case 16:this._onRequestWindowsOptionsReport.fire(1);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`\x1B[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:(t===0||t===2)&&(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),(t===0||t===1)&&(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:(t===0||t===2)&&this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),(t===0||t===1)&&this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop());break}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._activeBuffer.savedCharsets=this._charsetService.charsets.slice(),this._activeBuffer.savedGlevel=this._charsetService.glevel,this._activeBuffer.savedOriginMode=this._coreService.decPrivateModes.origin,this._activeBuffer.savedWraparoundMode=this._coreService.decPrivateModes.wraparound,!0}restoreCursor(e){this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg;for(let t=0;t1;){let s=r.shift(),o=r.shift();if(/^\d+$/.exec(s)){let a=parseInt(s,10);if(Tn(a))if(o==="?")t.push({type:0,index:a});else{let l=ys(o);l&&t.push({type:1,index:a,color:l})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){let t=e.indexOf(";");if(t===-1)return!0;let r=e.slice(0,t).trim(),s=e.slice(t+1);return s?this._createHyperlink(r,s):r.trim()?!1:this._finishHyperlink()}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();let r=e.split(":"),s,o=r.findIndex(a=>a.startsWith("id="));return o!==-1&&(s=r[o].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){let r=e.split(";");for(let s=0;s=this._specialColors.length);++s,++t)if(r[s]==="?")this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{let o=ys(r[s]);o&&this._onColor.fire([{type:1,index:this._specialColors[t],color:o}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;let t=[],r=e.split(";");for(let s=0;s=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){let e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=U.clone(),this._eraseAttrDataInternal=U.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=this._curAttrData.bg&67108863,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){let e=new F;e.content=1<<22|69,e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`\x1B${l}\x1B\\`),!0),s=this._bufferService.buffer,o=this._optionsService.rawOptions,a={block:2,underline:4,bar:6};return r(e==='"q'?`P1$r${this._curAttrData.isProtected()?1:0}"q`:e==='"p'?'P1$r61;1"p':e==="r"?`P1$r${s.scrollTop+1};${s.scrollBottom+1}r`:e==="m"?"P1$r0m":e===" q"?`P1$r${a[o.cursorStyle]-(o.cursorBlink?1:0)} q`:"P0$r")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}kittyKeyboardSet(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;let t=e.params[0]||0,r=e.length>1&&e.params[1]||1,s=this._coreService.kittyKeyboard;switch(r){case 1:s.flags=t;break;case 2:s.flags|=t;break;case 3:s.flags&=~t;break}return!0}kittyKeyboardQuery(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;let t=this._coreService.kittyKeyboard.flags;return this._coreService.triggerDataEvent(`\x1B[?${t}u`),!0}kittyKeyboardPush(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;let t=e.params[0]||0,r=this._coreService.kittyKeyboard,o=this._bufferService.buffer===this._bufferService.buffers.alt?r.altStack:r.mainStack;return o.length>=16&&o.shift(),o.push(r.flags),r.flags=t,!0}kittyKeyboardPop(e){if(!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard)return!0;let t=Math.max(1,e.params[0]||1),r=this._coreService.kittyKeyboard,o=this._bufferService.buffer===this._bufferService.buffers.alt?r.altStack:r.mainStack;for(let a=0;a0;a++)r.flags=o.pop();return o.length===0&&t>0&&(r.flags=0),!0}},hi=class{constructor(i){this._bufferService=i;this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(i){ithis.end&&(this.end=i)}markRangeDirty(i,e){i>e&&(wn=i,i=e,e=wn),ithis.end&&(this.end=e)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};hi=y([m(0,D)],hi);function Tn(n){return 0<=n&&n<256}var vr=class extends g{constructor(e){super();this._action=e;this._writeBuffer=[];this._callbacks=[];this._pendingData=0;this._bufferOffset=0;this._isSyncWriting=!1;this._syncCalls=0;this._didUserInput=!1;this._innerWriteTimer=this._register(new Ie);this._onWriteParsed=this._register(new b);this.onWriteParsed=this._onWriteParsed.event;this._register(E(()=>{this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0}))}handleUserInput(){this._didUserInput=!0}flushSync(){if(this._store.isDisposed||this._isSyncWriting)return;this._isSyncWriting=!0;let e,t=!1;for(;e=this._writeBuffer.shift();){t=!0,this._action(e);let r=this._callbacks.shift();r&&r()}this._pendingData=0,this._bufferOffset=2147483647,this._writeBuffer.length=0,this._callbacks.length=0,this._isSyncWriting=!1,t&&this._onWriteParsed.fire()}writeSync(e,t){if(this._store.isDisposed)return;if(t!==void 0&&this._syncCalls>t){this._syncCalls=0;return}if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;this._isSyncWriting=!0;let r;for(;r=this._writeBuffer.shift();){this._action(r);let s=this._callbacks.shift();s&&s()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(!this._store.isDisposed){if(this._pendingData>5e7)throw new Error("write data discarded, use flow control to avoid losing data");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput){this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),this._innerWrite();return}this._scheduleInnerWrite()}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}}_scheduleInnerWrite(e=0,t=!0){this._store.isDisposed||this._innerWriteTimer.cancelAndSet(()=>this._innerWrite(e,t),0)}_innerWrite(e=0,t=!0){if(this._store.isDisposed)return;let r=e||performance.now();for(;this._writeBuffer.length>this._bufferOffset;){let s=this._writeBuffer[this._bufferOffset],o=this._action(s,t);if(o){let l=h=>{this._store.isDisposed||(performance.now()-r>=12?this._scheduleInnerWrite(0,h):this._innerWrite(r,h))};o.catch(h=>(queueMicrotask(()=>{throw h}),Promise.resolve(!1))).then(l);return}let a=this._callbacks[this._bufferOffset];if(a&&a(),this._bufferOffset++,this._pendingData-=s.length,performance.now()-r>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),this._scheduleInnerWrite()):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}};var kt=class{constructor(i){this._bufferService=i;this._nextId=1;this._entriesWithId=new Map;this._dataByLinkId=new Map}registerLink(i){let e=this._bufferService.buffer;if(i.id===void 0){let l=e.addMarker(e.ybase+e.y),h={data:i,id:this._nextId++,lines:[l]};return l.onDispose(()=>this._removeMarkerFromLink(h,l)),this._dataByLinkId.set(h.id,h),h.id}let t=i,r=this._getEntryIdKey(t),s=this._entriesWithId.get(r);if(s)return this.addLineToLink(s.id,e.ybase+e.y),s.id;let o=e.addMarker(e.ybase+e.y),a={id:this._nextId++,key:this._getEntryIdKey(t),data:t,lines:[o]};return o.onDispose(()=>this._removeMarkerFromLink(a,o)),this._entriesWithId.set(a.key,a),this._dataByLinkId.set(a.id,a),a.id}addLineToLink(i,e){let t=this._dataByLinkId.get(i);if(t&&t.lines.every(r=>r.line!==e)){let r=this._bufferService.buffer.addMarker(e);t.lines.push(r),r.onDispose(()=>this._removeMarkerFromLink(t,r))}}getLinkData(i){return this._dataByLinkId.get(i)?.data}_getEntryIdKey(i){return`${i.id};;${i.uri}`}_removeMarkerFromLink(i,e){let t=i.lines.indexOf(e);t!==-1&&(i.lines.splice(t,1),i.lines.length===0&&(i.data.id!==void 0&&this._entriesWithId.delete(i.key),this._dataByLinkId.delete(i.id)))}};kt=y([m(0,D)],kt);var Dn=!1,Sr=class extends g{constructor(e){super();this._windowsWrappingHeuristics=this._register(new P);this._onBinary=this._register(new b);this.onBinary=this._onBinary.event;this._onData=this._register(new b);this.onData=this._onData.event;this._onLineFeed=this._register(new b);this.onLineFeed=this._onLineFeed.event;this._onRender=this._register(new b);this.onRender=this._onRender.event;this._onResize=this._register(new b);this.onResize=this._onResize.event;this._onWriteParsed=this._register(new b);this.onWriteParsed=this._onWriteParsed.event;this._onScroll=this._register(new b);this._instantiationService=new Ji,this.optionsService=this._register(new nr(e)),this._instantiationService.setService(R,this.optionsService),this._logService=this._register(this._instantiationService.createInstance(wt)),this._instantiationService.setService(fe,this._logService),this._bufferService=this._register(this._instantiationService.createInstance(Dt)),this._instantiationService.setService(D,this._bufferService),this.coreService=this._register(this._instantiationService.createInstance(Lt)),this._instantiationService.setService(Y,this.coreService),this.mouseStateService=this._register(this._instantiationService.createInstance(or)),this._instantiationService.setService(Me,this.mouseStateService),this.unicodeService=this._register(this._instantiationService.createInstance(me)),this.unicodeService.register(new ar),this._instantiationService.setService(Us,this.unicodeService),this._charsetService=this._instantiationService.createInstance(lr),this._instantiationService.setService(Ws,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(kt),this._instantiationService.setService(vi,this._oscLinkService),this._inputHandler=this._register(new br(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.mouseStateService,this.unicodeService)),this._register(j.forward(this._inputHandler.onLineFeed,this._onLineFeed)),this._register(j.forward(this._bufferService.onResize,this._onResize)),this._register(j.forward(this.coreService.onData,this._onData)),this._register(j.forward(this.coreService.onBinary,this._onBinary)),this._register(this.coreService.onRequestScrollToBottom(()=>this.scrollToBottom(!0))),this._register(this.coreService.onUserInput(()=>this._writeBuffer.handleUserInput())),this._register(this.optionsService.onMultipleOptionChange(["windowsPty"],()=>this._handleWindowsPtyOptionChange())),this._register(this._bufferService.onScroll(()=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)})),this._writeBuffer=this._register(new vr((t,r)=>this._inputHandler.parse(t,r))),this._register(j.forward(this._writeBuffer.onWriteParsed,this._onWriteParsed))}get onScroll(){return this._onScrollApi||(this._onScrollApi=this._register(new b),this._onScroll.event(e=>{this._onScrollApi?.fire(e.position)})),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(let t in e)this.optionsService.options[t]=e[t]}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=3&&!Dn&&(this._logService.warn("writeSync is unreliable and will be removed soon."),Dn=!0),this._writeBuffer.writeSync(e,t)}input(e,t=!0){this.coreService.triggerDataEvent(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,2),t=Math.max(t,1),this._writeBuffer.flushSync(),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t){this._bufferService.scrollLines(e,t)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){let t=e-this._bufferService.buffer.ydisp;t!==0&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}registerApcHandler(e,t){return this._inputHandler.registerApcHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.mouseStateService.reset()}_handleWindowsPtyOptionChange(){let e=!1,t=this.optionsService.rawOptions.windowsPty;t&&t.backend!==void 0&&t.buildNumber!==void 0&&(e=t.backend==="conpty"&&t.buildNumber<21376),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){let e=[];e.push(this.onLineFeed(Is.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:"H"},()=>(Is(this._bufferService),!1))),this._windowsWrappingHeuristics.value=E(()=>{for(let t of e)t.dispose()})}}};var z=0,gr=class{constructor(i,e){this._getKey=i;this._array=[];this._insertedValues=[];this._isFlushingInserted=!1;this._deletedIndices=[];this._isFlushingDeleted=!1;this._flushInsertedTask=new It(e),this._flushDeletedTask=new It(e)}clear(){this._array.length=0,this._insertedValues.length=0,this._flushInsertedTask.clear(),this._isFlushingInserted=!1,this._deletedIndices.length=0,this._flushDeletedTask.clear(),this._isFlushingDeleted=!1}insert(i){this._flushCleanupDeleted(),this._insertedValues.length===0&&this._flushInsertedTask.enqueue(()=>this._flushInserted()),this._insertedValues.push(i)}_flushInserted(){let i=this._insertedValues.sort((s,o)=>this._getKey(s)-this._getKey(o)),e=0,t=0,r=new Array(this._array.length+this._insertedValues.length);for(let s=0;s=this._array.length||this._getKey(i[e])<=this._getKey(this._array[t])?(r[s]=i[e],e++):r[s]=this._array[t++];this._array=r,this._insertedValues.length=0}_flushCleanupInserted(){!this._isFlushingInserted&&this._insertedValues.length>0&&this._flushInsertedTask.flush()}delete(i){if(this._flushCleanupInserted(),this._array.length===0)return!1;let e=this._getKey(i);if(e===void 0||(z=this._search(e),z===-1)||this._getKey(this._array[z])!==e)return!1;do if(this._array[z]===i)return this._deletedIndices.length===0&&this._flushDeletedTask.enqueue(()=>this._flushDeleted()),this._deletedIndices.push(z),!0;while(++zs-o),e=0,t=new Array(this._array.length-i.length),r=0;for(let s=0;s0&&this._flushDeletedTask.flush()}*getKeyIterator(i){if(this._flushCleanupInserted(),this._flushCleanupDeleted(),this._array.length!==0&&(z=this._search(i),!(z<0||z>=this._array.length)&&this._getKey(this._array[z])===i))do yield this._array[z];while(++z=this._array.length)&&this._getKey(this._array[z])===i))do e(this._array[z]);while(++z=e;){let r=e+t>>1,s=this._getKey(this._array[r]);if(s>i)t=r-1;else if(s0&&this._getKey(this._array[r-1])===i;)r--;return r}}return e}};var Mt=0,Ir=0,Bt=class extends g{constructor(e,t){super();this._logService=e;this._bufferService=t;this._lineCache=this._register(new xs);this._onDecorationRegistered=this._register(new b);this.onDecorationRegistered=this._onDecorationRegistered.event;this._onDecorationRemoved=this._register(new b);this.onDecorationRemoved=this._onDecorationRemoved.event;this._decorations=new gr(r=>r?.marker.line,this._logService),this._register(E(()=>this.reset())),this._register(this._bufferService.buffers.onBufferActivate(()=>{this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)})),this._lineCache.attachToBufferLines(this._bufferService.buffer.lines)}get decorations(){return this._decorations.values()}registerDecoration(e){if(e.marker.isDisposed)return;let t=new ws(e);if(t){let r=t.marker.onDispose(()=>t.dispose()),s=t.onDispose(()=>{s.dispose(),t&&(this._decorations.delete(t)&&(this._lineCache.remove(t),this._onDecorationRemoved.fire(t)),r.dispose())});this._decorations.insert(t),this._lineCache.add(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(let e of this._decorations.values())e.dispose();this._decorations.clear(),this._lineCache.clear()}*getDecorationsAtCell(e,t,r){let s=this._lineCache.getDecorationsOnLine(t);if(s)for(let o of s)Mt=o.options.x??0,Ir=Mt+(o.options.width??1),e>=Mt&&e=Mt&&ethis._handleBufferLinesTrim(r))),t.add(e.onInsert(r=>this._handleBufferLinesInsert(r))),t.add(e.onDelete(r=>this._handleBufferLinesDelete(r)))}_getDecorationHeight(e){return e.options.height??1}_addToLineBuckets(e){let t=e.marker.line;if(t<0)return;e._indexedStartLine=t;let r=this._getDecorationHeight(e);for(let s=t;s=0&&this._addToLineBuckets(e)}_scheduleLineIndexSync(e){this._lineIndexSyncCallbacks.push(e),this._lineIndexSyncTimer.set(()=>{let t=this._lineIndexSyncCallbacks;this._lineIndexSyncCallbacks=[];for(let r of t)r()})}_handleBufferLinesTrim(e){if(e<=0)return;let t=new Map;for(let[r,s]of this._decorationsByLine){let o=r-e;o<0||this._mergeLineBucket(t,o,s)}this._decorationsByLine.clear();for(let[r,s]of t)this._decorationsByLine.set(r,s);for(let r of this._decorations)r.marker.isDisposed||(r._indexedStartLine-=e)}_handleBufferLinesInsert(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesInsert(e))}_handleBufferLinesDelete(e){this._scheduleLineIndexSync(()=>this._applyBufferLinesDelete(e))}_mergeLineBucket(e,t,r){let s=e.get(t);if(s)for(let o=0,a=r.length;ot&&(s.push(a),this._removeFromLineBuckets(a))}let o=new Map;for(let[a,l]of this._decorationsByLine){let h=a>=t?a+r:a;this._mergeLineBucket(o,h,l)}this._decorationsByLine.clear();for(let[a,l]of o)this._decorationsByLine.set(a,l);for(let a of this._decorations)a.marker.isDisposed||a._indexedStartLine>=t&&(a._indexedStartLine=a.marker.line);for(let a of s)this._addToLineBuckets(a)}_applyBufferLinesDelete(e){let t=e.index+e.amount,r=new Map;for(let[o,a]of this._decorationsByLine){if(o>=e.index&&o=t?o-e.amount:o;this._mergeLineBucket(r,l,a)}this._decorationsByLine.clear();for(let[o,a]of r)this._decorationsByLine.set(o,a);let s=[];for(let o of this._decorations){if(o.marker.isDisposed)continue;let a=o._indexedStartLine,l=this._getDecorationHeight(o);a>=t?o._indexedStartLine=o.marker.line:at&&s.push(o)}for(let o of s)this._reindexDecoration(o)}},ws=class extends pe{constructor(e){super();this.options=e;this.onRenderEmitter=this.add(new b);this.onRender=this.onRenderEmitter.event;this._onDispose=this.add(new b);this.onDispose=this._onDispose.event;this._cachedBg=null;this._cachedFg=null;this.marker=e.marker,this._indexedStartLine=e.marker.line,this.options.overviewRulerOptions&&!this.options.overviewRulerOptions.position&&(this.options.overviewRulerOptions.position="full")}get backgroundColorRGB(){return this._cachedBg===null&&(this.options.backgroundColor?this._cachedBg=B.toColor(this.options.backgroundColor):this._cachedBg=void 0),this._cachedBg}get foregroundColorRGB(){return this._cachedFg===null&&(this.options.foregroundColor?this._cachedFg=B.toColor(this.options.foregroundColor):this._cachedFg=void 0),this._cachedFg}dispose(){this._onDispose.fire(),super.dispose()}};var yo=1e3,Cr=class{constructor(i,e=yo){this._renderCallback=i;this._debounceThresholdMS=e;this._lastRefreshMs=0;this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0),this._additionalRefreshRequested=!1}refresh(i,e,t){this._rowCount=t,i=i??0,e=e??this._rowCount-1,this._rowStart=this._rowStart!==void 0?Math.min(this._rowStart,i):i,this._rowEnd=this._rowEnd!==void 0?Math.max(this._rowEnd,e):e;let r=performance.now();if(r-this._lastRefreshMs>=this._debounceThresholdMS)this._refreshTimeoutID!==void 0&&(clearTimeout(this._refreshTimeoutID),this._refreshTimeoutID=void 0,this._additionalRefreshRequested=!1),this._lastRefreshMs=r,this._innerRefresh();else if(!this._additionalRefreshRequested){let s=r-this._lastRefreshMs,o=this._debounceThresholdMS-s;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout(()=>{this._lastRefreshMs=performance.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0},o)}}_innerRefresh(){if(this._rowStart===void 0||this._rowEnd===void 0||this._rowCount===void 0)return;let i=Math.max(this._rowStart,0),e=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(i,e)}};var Rn=!1,Ye=class extends g{constructor(e,t,r,s){super();this._terminal=e;this._coreBrowserService=r;this._renderService=s;this._rowColumns=new WeakMap;this._liveRegionLineCount=0;this._charsToConsume=[];this._charsToAnnounce="";let o=this._coreBrowserService.mainDocument;this._accessibilityContainer=o.createElement("div"),this._accessibilityContainer.classList.add("xterm-accessibility"),this._rowContainer=o.createElement("div"),this._rowContainer.setAttribute("role","list"),this._rowContainer.classList.add("xterm-accessibility-tree"),this._rowElements=[];for(let a=0;athis._handleBoundaryFocus(a,0),this._bottomBoundaryFocusListener=a=>this._handleBoundaryFocus(a,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=o.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this._register(new Cr(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");Rn?(this._accessibilityContainer.classList.add("debug"),this._rowContainer.classList.add("debug"),this._debugRootContainer=o.createElement("div"),this._debugRootContainer.classList.add("xterm"),this._debugRootContainer.appendChild(o.createTextNode("------start a11y------")),this._debugRootContainer.appendChild(this._accessibilityContainer),this._debugRootContainer.appendChild(o.createTextNode("------end a11y------")),this._terminal.element.insertAdjacentElement("afterend",this._debugRootContainer)):this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this._register(this._terminal.onResize(a=>this._handleResize(a.rows))),this._register(this._terminal.onRender(a=>this._refreshRows(a.start,a.end))),this._register(this._terminal.onScroll(()=>this._refreshRows())),this._register(this._terminal.onA11yChar(a=>this._handleChar(a))),this._register(this._terminal.onLineFeed(()=>this._handleChar(` @@ -48,7 +44,7 @@ index 9bc5087a0729e74e20b59eddf5d8259e056de338..e0b619f0c891730125cbb9625a6296bf +`,e)}paste(i){this._core.paste(i)}refresh(i,e){this._verifyIntegers(i,e),this._core.refresh(i,e)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(i){this._addonManager.loadAddon(this,i)}static get strings(){return{get promptLabel(){return Ut.get()},set promptLabel(i){Ut.set(i)},get tooMuchOutput(){return Je.get()},set tooMuchOutput(i){Je.set(i)}}}_verifyIntegers(...i){for(ye of i)if(ye===1/0||isNaN(ye)||ye%1!==0)throw new Error("This API only accepts integers")}_verifyPositiveIntegers(...i){for(ye of i)if(ye&&(ye===1/0||isNaN(ye)||ye%1!==0||ye<0))throw new Error("This API only accepts positive integers")}};export{An as Terminal}; //# sourceMappingURL=xterm.mjs.map diff --git a/lib/xterm.mjs.map b/lib/xterm.mjs.map -index 008be242620e5d914b4313743a98afbd95449852..304bfa84bdaab17ecbb19922b97d740c0ecfc2b9 100644 +index 008be242620e5d914b4313743a98afbd95449852..cc56edc362899629960bb1454f60fded3795159b 100644 --- a/lib/xterm.mjs.map +++ b/lib/xterm.mjs.map @@ -1,7 +1,7 @@ @@ -58,18 +54,15 @@ index 008be242620e5d914b4313743a98afbd95449852..304bfa84bdaab17ecbb19922b97d740c - "sourcesContent": ["/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (\u241B).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private _isSendingComposition: boolean;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isSendingComposition = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._isComposing = true;\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data}\\u200E`;\n this.updateCompositionElements();\n setTimeout(() => {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max( this._compositionPosition.start, end);\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(): void {\n this._finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._isComposing || this._isSendingComposition) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean): void {\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n\n if (!waitForPropagation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this._isSendingComposition = false;\n const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);\n this._coreService.triggerDataEvent(input, true);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n };\n const currentCompositionSuffix = this._compositionSuffix;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this._isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this._isSendingComposition) {\n this._isSendingComposition = false;\n let input;\n // Add length of data already sent due to keydown event,\n // otherwise input characters can be duplicated. (Issue #3191)\n currentCompositionPosition.start += this._dataAlreadySent.length;\n if (this._isComposing) {\n // Use the start position of the new composition to get the string\n // if a new composition has started.\n input = this._textarea.value.substring(currentCompositionPosition.start, this._compositionPosition.start);\n } else {\n // Keep support for non-composition characters typed immediately after composition end\n // while avoiding re-sending the trailing text that was already present\n // before composition started.\n const value = this._textarea.value;\n const valueEnd = currentCompositionSuffix.length > 0 && value.endsWith(currentCompositionSuffix)\n ? value.length - currentCompositionSuffix.length\n : value.length;\n input = value.substring(currentCompositionPosition.start, Math.max(currentCompositionPosition.start, valueEnd));\n }\n if (input.length > 0) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n", "/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n", "/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n", "import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec \u00A7 \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" \u2014 i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n\u00B2) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '\u25C6'\n 'a': '\\u2592', // '\u2592'\n 'b': '\\u2409', // '\u2409' (HT)\n 'c': '\\u240c', // '\u240C' (FF)\n 'd': '\\u240d', // '\u240D' (CR)\n 'e': '\\u240a', // '\u240A' (LF)\n 'f': '\\u00b0', // '\u00B0'\n 'g': '\\u00b1', // '\u00B1'\n 'h': '\\u2424', // '\u2424' (NL)\n 'i': '\\u240b', // '\u240B' (VT)\n 'j': '\\u2518', // '\u2518'\n 'k': '\\u2510', // '\u2510'\n 'l': '\\u250c', // '\u250C'\n 'm': '\\u2514', // '\u2514'\n 'n': '\\u253c', // '\u253C'\n 'o': '\\u23ba', // '\u23BA'\n 'p': '\\u23bb', // '\u23BB'\n 'q': '\\u2500', // '\u2500'\n 'r': '\\u23bc', // '\u23BC'\n 's': '\\u23bd', // '\u23BD'\n 't': '\\u251c', // '\u251C'\n 'u': '\\u2524', // '\u2524'\n 'v': '\\u2534', // '\u2534'\n 'w': '\\u252c', // '\u252C'\n 'x': '\\u2502', // '\u2502'\n 'y': '\\u2264', // '\u2264'\n 'z': '\\u2265', // '\u2265'\n '{': '\\u03c0', // '\u03C0'\n '|': '\\u2260', // '\u2260'\n '}': '\\u00a3', // '\u00A3'\n '~': '\\u00b7' // '\u00B7'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '\u00A3'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '\u00A3',\n '@': '\u00BE',\n '[': 'ij',\n '\\\\': '\u00BD',\n ']': '|',\n '{': '\u00A8',\n '|': 'f',\n '}': '\u00BC',\n '~': '\u00B4'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '\u00A3',\n '@': '\u00E0',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00A7',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00A8'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': '\u00E0',\n '[': '\u00E2',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n '`': '\u00F4',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00FB'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '\u00A7',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00DC',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00DF'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00E9',\n '`': '\u00F9',\n '{': '\u00E0',\n '|': '\u00F2',\n '}': '\u00E8',\n '~': '\u00EC'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': '\u00C4',\n '[': '\u00C6',\n '\\\\': '\u00D8',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E4',\n '{': '\u00E6',\n '|': '\u00F8',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00A1',\n '\\\\': '\u00D1',\n ']': '\u00BF',\n '{': '\u00B0',\n '|': '\u00F1',\n '}': '\u00E7'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': '\u00C9',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': '\u00F9',\n '@': '\u00E0',\n '[': '\u00E9',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n\n '_': '\u00E8',\n '`': '\u00F4',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00FB'\n};\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n", "\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n", "/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', () => this._compositionHelper!.compositionend()));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n this.coreService.triggerDataEvent(key, true);\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n"], - "mappings": "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Q,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ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", - "names": ["promptLabelInternal", "promptLabel", "value", "tooMuchOutputInternal", "tooMuchOutput", "prepareTextForTerminal", "text", "bracketTextForPaste", "bracketedPasteMode", "copyHandler", "ev", "selectionService", "handlePasteEvent", "textarea", "coreService", "optionsService", "paste", "moveTextAreaUnderMouseCursor", "screenElement", "pos", "left", "top", "rightClickHandler", "shouldSelectWord", "stringFromCodePoint", "codePoint", "utf32ToString", "data", "start", "end", "result", "i", "codepoint", "StringToUtf32", "input", "target", "length", "size", "startPos", "second", "code", "Utf8ToUtf32", "byte1", "byte2", "byte3", "byte4", "discardInterim", "cp", "pos", "tmp", "type", "missing", "fourStop", "AttributeData", "_AttributeData", "ExtendedAttrs", "value", "newObj", "_ExtendedAttrs", "ext", "urlId", "val", "CellData", "_CellData", "AttributeData", "ExtendedAttrs", "value", "obj", "stringFromCodePoint", "combined", "code", "second", "other", "thisDefault", "otherDefault", "serviceRegistry", "getServiceDependencies", "ctor", "createDecorator", "id", "decorator", "target", "key", "index", "storeServiceDependency", "IBufferService", "createDecorator", "IMouseStateService", "ICoreService", "ICharsetService", "IInstantiationService", "ILogService", "createDecorator", "IOptionsService", "IOscLinkService", "IUnicodeService", "IDecorationService", "OscLinkProvider", "_bufferService", "_optionsService", "_oscLinkService", "CellData", "y", "callback", "line", "result", "linkHandler", "cell", "lineLength", "currentLinkId", "currentStart", "finishLink", "x", "text", "endX", "range", "ignoreLink", "parsed", "e", "defaultActivate", "startX", "linkId", "startY", "finalStartX", "endY", "finalEndX", "previousLine", "previousLineLength", "previousStartX", "currentLine", "currentLineLength", "nextLine", "nextLineLength", "nextEndX", "__decorateClass", "__decorateParam", "IBufferService", "IOptionsService", "IOscLinkService", "uri", "newWindow", "ICharSizeService", "createDecorator", "ICoreBrowserService", "IMouseCoordsService", "IMouseService", "IRenderService", "ISelectionService", "ICharacterJoinerService", "IThemeService", "ILinkProviderService", "IKeyboardService", "toDisposable", "fn", "dispose", "arg", "d", "DisposableStore", "o", "d", "Disposable", "MutableDisposable", "value", "disposableTimeout", "handler", "timeout", "store", "timer", "disposable", "toDisposable", "TimeoutTimer", "runner", "MicrotaskTimer", "IntervalTimer", "interval", "context", "handle", "getWindow", "e", "candidateNode", "candidateEvent", "DomListener", "node", "type", "handler", "options", "addDisposableListener", "useCaptureOrOptions", "addStandardDisposableListener", "useCapture", "eventType", "getDomNodePagePosition", "domNode", "bb", "win", "AnimationFrameQueueItem", "_runner", "priority", "a", "b", "animationFrameState", "getAnimationFrameState", "targetWindow", "state", "animationFrameRunner", "scheduleAtNextAnimationFrame", "runner", "item", "WindowIntervalTimer", "IntervalTimer", "interval", "FastDomNode", "domNode", "_width", "width", "numberAsPixels", "_height", "height", "_top", "top", "_left", "left", "_bottom", "bottom", "_right", "right", "className", "shouldHaveIt", "position", "layerHint", "contain", "name", "value", "Platform_exports", "__export", "getSafariVersion", "getZoomFactor", "isChrome", "isChromeOS", "isFirefox", "isLegacyEdge", "isLinux", "isMac", "isNode", "isSafari", "isWindows", "userAgent", "platform", "_targetWindow", "majorVersion", "sameOriginWindowChainCache", "getParentWindowIfSameOrigin", "w", "location", "parentLocation", "IframeUtils", "targetWindow", "windowChainCache", "parent", "childWindow", "ancestorWindow", "top", "left", "windowChain", "windowChainEl", "windowInChain", "boundingRect", "StandardMouseEvent", "iframeOffsets", "StandardWheelEvent", "e", "deltaX", "deltaY", "shouldFactorDPR", "isChrome", "chromeVersionMatch", "e1", "e2", "devicePixelRatio", "ev", "isFirefox", "isMac", "isSafari", "isWindows", "GlobalPointerMoveMonitor", "DisposableStore", "invokeStopCallback", "onStopCallback", "initialElement", "pointerId", "initialButtons", "pointerMoveCallback", "eventSource", "toDisposable", "getWindow", "addDisposableListener", "eventType", "e", "Widget", "Disposable", "domNode", "listener", "addDisposableListener", "eventType", "e", "StandardMouseEvent", "getWindow", "ScrollbarArrow", "Widget", "opts", "arrowSize", "GlobalPointerMoveMonitor", "addStandardDisposableListener", "eventType", "e", "WindowIntervalTimer", "TimeoutTimer", "scheduleRepeater", "getWindow", "pointerMoveData", "Emitter", "listener", "thisArgs", "disposables", "toDisposable", "entry", "result", "idx", "event", "fn", "listeners", "EventUtils", "forward", "from", "to", "e", "map", "i", "any", "events", "store", "DisposableStore", "runAndSubscribe", "handler", "initial", "ScrollState", "_ScrollState", "_forceIntegerValues", "width", "scrollWidth", "scrollLeft", "height", "scrollHeight", "scrollTop", "other", "update", "useRawScrollPositions", "previous", "inSmoothScrolling", "widthChanged", "scrollWidthChanged", "scrollLeftChanged", "heightChanged", "scrollHeightChanged", "scrollTopChanged", "Scrollable", "Disposable", "options", "Emitter", "smoothScrollDuration", "scrollPosition", "dimensions", "newState", "reuseAnimation", "validTarget", "newSmoothScrolling", "SmoothScrollingOperation", "oldState", "SmoothScrollingUpdate", "isDone", "createEaseOutCubic", "from", "to", "delta", "completion", "easeOutCubic", "createComposed", "a", "b", "cut", "_SmoothScrollingOperation", "startTime", "duration", "viewportSize", "stop1", "stop2", "state", "now", "newScrollLeft", "newScrollTop", "easeInCubic", "t", "ScrollbarVisibilityController", "Disposable", "visibility", "visibleClassName", "invisibleClassName", "TimeoutTimer", "rawShouldBeVisible", "shouldBeVisible", "isNeeded", "domNode", "withFadeAway", "POINTER_DRAG_RESET_DISTANCE", "AbstractScrollbar", "Widget", "opts", "ScrollbarVisibilityController", "GlobalPointerMoveMonitor", "FastDomNode", "addDisposableListener", "eventType", "arrow", "ScrollbarArrow", "top", "left", "width", "height", "e", "visibleSize", "elementScrollSize", "elementScrollPosition", "domTop", "sliderStart", "sliderStop", "pointerPos", "offsetX", "offsetY", "domNodePosition", "getDomNodePagePosition", "offset", "initialPointerPosition", "initialPointerOrthogonalPosition", "initialScrollbarState", "pointerMoveData", "pointerOrthogonalPosition", "pointerOrthogonalDelta", "isWindows", "pointerDelta", "_desiredScrollPosition", "desiredScrollPosition", "scrollbarSize", "ScrollbarState", "_ScrollbarState", "arrowSize", "scrollbarSize", "oppositeScrollbarSize", "visibleSize", "scrollSize", "scrollPosition", "iVisibleSize", "iScrollSize", "iScrollPosition", "iArrowSize", "computedAvailableSize", "computedRepresentableSize", "computedIsNeeded", "computedSliderSize", "computedSliderRatio", "computedSliderPosition", "r", "offset", "desiredSliderPosition", "correctedOffset", "desiredScrollPosition", "delta", "HorizontalScrollbar", "AbstractScrollbar", "scrollable", "options", "host", "scrollDimensions", "scrollPosition", "ScrollbarState", "sliderSize", "sliderPosition", "largeSize", "smallSize", "e", "offsetX", "offsetY", "size", "target", "VerticalScrollbar", "AbstractScrollbar", "scrollable", "options", "host", "scrollDimensions", "scrollPosition", "hasArrows", "ScrollbarState", "sliderSize", "sliderPosition", "largeSize", "smallSize", "offsetX", "offsetY", "size", "target", "delta", "currentPosition", "showArrows", "display", "arrow", "arrowSize", "MouseWheelClassifierItem", "timestamp", "deltaX", "deltaY", "_MouseWheelClassifier", "remainingInfluence", "score", "iteration", "index", "influence", "e", "isChrome", "targetWindow", "getWindow", "pageZoomFactor", "getZoomFactor", "previousItem", "item", "absDeltaX", "absDeltaY", "absPreviousDeltaX", "absPreviousDeltaY", "minDeltaX", "minDeltaY", "maxDeltaX", "maxDeltaY", "value", "MouseWheelClassifier", "SmoothScrollableElement", "Widget", "element", "options", "scrollable", "Emitter", "resolvedScrollable", "ownsScrollable", "Scrollable", "callback", "scheduleAtNextAnimationFrame", "resolveOptions", "scrollbarHost", "mouseWheelEvent", "VerticalScrollbar", "HorizontalScrollbar", "FastDomNode", "TimeoutTimer", "dispose", "dimensions", "update", "newClassName", "isMac", "newOptions", "browserEvent", "StandardWheelEvent", "shouldListen", "onMouseWheel", "addDisposableListener", "eventType", "classifier", "didScroll", "shiftConvert", "futureScrollPosition", "desiredScrollPosition", "deltaScrollTop", "desiredScrollTop", "deltaScrollLeft", "desiredScrollLeft", "consumeMouseWheel", "scrollState", "enableTop", "enableLeft", "leftClassName", "topClassName", "topLeftClassName", "opts", "result", "Viewport", "Disposable", "element", "screenElement", "_bufferService", "coreBrowserService", "_coreService", "mouseStateService", "themeService", "_optionsService", "_renderService", "Emitter", "scrollable", "Scrollable", "cb", "scheduleAtNextAnimationFrame", "SmoothScrollableElement", "type", "EventUtils", "toDisposable", "e", "disp", "pos", "line", "disableSmoothScroll", "showScrollbar", "showArrows", "verticalScrollbarSize", "ydisp", "newRow", "diff", "translationY", "__decorateClass", "__decorateParam", "IBufferService", "ICoreBrowserService", "ICoreService", "IMouseStateService", "IThemeService", "IOptionsService", "IRenderService", "BufferDecorationRenderer", "Disposable", "_screenElement", "_bufferService", "_coreBrowserService", "_decorationService", "_renderService", "decoration", "toDisposable", "element", "x", "line", "__decorateClass", "__decorateParam", "IBufferService", "ICoreBrowserService", "IDecorationService", "IRenderService", "ColorZoneStore", "decoration", "z", "padding", "zone", "line", "position", "drawHeight", "drawWidth", "drawX", "OverviewRulerRenderer", "Disposable", "_viewportElement", "_screenElement", "_bufferService", "_decorationService", "_renderService", "_optionsService", "_themeService", "_coreBrowserService", "ColorZoneStore", "toDisposable", "ctx", "scrollbar", "outerWidth", "innerWidth", "pixelsPerLine", "nonFullHeight", "cssCanvasHeight", "deviceCanvasHeight", "decoration", "zones", "zone", "updateCanvasDimensions", "updateAnchor", "__decorateClass", "__decorateParam", "IBufferService", "IDecorationService", "IRenderService", "IOptionsService", "IThemeService", "ICoreBrowserService", "CompositionHelper", "_textarea", "_compositionView", "_bufferService", "_optionsService", "_coreService", "_renderService", "start", "end", "ev", "waitForPropagation", "currentCompositionPosition", "currentCompositionSuffix", "input", "value", "valueEnd", "oldValue", "newValue", "diff", "dontRecurse", "cursorX", "cellHeight", "cursorTop", "cursorLeft", "maxWidth", "compositionViewBounds", "__decorateClass", "__decorateParam", "IBufferService", "IOptionsService", "ICoreService", "IRenderService", "$r", "$g", "$b", "$a", "NULL_COLOR", "channels", "toCss", "g", "b", "toPaddedHex", "toRgba", "toColor", "color", "blend", "bg", "fg", "fgR", "fgG", "fgB", "bgR", "bgG", "bgB", "css", "rgba", "isOpaque", "ensureContrastRatio", "ratio", "result", "opaque", "rgbaColor", "opacity", "multiplyOpacity", "factor", "toColorRGB", "$ctx", "$litmusColor", "canvas", "ctx", "rgbaMatch", "rgb", "relativeLuminance", "relativeLuminance2", "r", "rs", "gs", "bs", "rr", "rg", "rb", "bgRgba", "fgRgba", "bgL", "fgL", "contrastRatio", "resultA", "reduceLuminance", "resultARatio", "resultB", "increaseLuminance", "resultBRatio", "cr", "toChannels", "value", "c", "s", "l1", "l2", "JoinedCellData", "AttributeData", "firstCell", "chars", "width", "value", "CharacterJoinerService", "_bufferService", "CellData", "handler", "joiner", "joinerId", "i", "row", "line", "ranges", "lineStr", "trimmedLength", "rangeStartColumn", "currentStringIndex", "rangeStartStringIndex", "rangeAttrFG", "rangeAttrBG", "x", "joinedRanges", "startIndex", "endIndex", "lineData", "startCol", "text", "allJoinedRanges", "error", "joinerRanges", "j", "currentRangeIndex", "currentRangeStarted", "currentRange", "length", "newRange", "inRange", "range", "__decorateClass", "__decorateParam", "IBufferService", "throwIfFalsy", "value", "isPowerlineGlyph", "codepoint", "isBoxOrBlockGlyph", "codepoint", "treatGlyphAsBackgroundColor", "codepoint", "isPowerlineGlyph", "isBoxOrBlockGlyph", "createRenderDimensions", "createDimension", "DomRendererRowFactory", "_document", "_characterJoinerService", "_optionsService", "_coreBrowserService", "_coreService", "_decorationService", "_themeService", "CellData", "start", "end", "columnSelectMode", "lineData", "row", "isCursorRow", "cursorStyle", "cursorInactiveStyle", "cursorX", "cursorBlink", "blinkOn", "cellWidth", "widthCache", "linkStart", "linkEnd", "rowInfo", "elements", "joinedRanges", "colors", "lineLength", "charElement", "cellAmount", "text", "i", "oldBg", "oldFg", "oldExt", "oldLinkHover", "oldSpacing", "oldIsInSelection", "spacing", "skipJoinedCheckUntilX", "classes", "hasHover", "x", "width", "isJoined", "isValidJoinRange", "lastCharX", "cell", "range", "firstSelectionState", "JoinedCellData", "isInSelection", "isCursorCell", "isLinkHover", "isDecorated", "d", "chars", "AttributeData", "fg", "fgColorMode", "bg", "bgColorMode", "isInverse", "temp", "temp2", "bgOverride", "fgOverride", "isTop", "resolvedBg", "channels", "color", "element", "treatGlyphAsBackgroundColor", "cache", "adjustedColor", "ratio", "style", "y", "__decorateClass", "__decorateParam", "ICharacterJoinerService", "IOptionsService", "ICoreBrowserService", "ICoreService", "IDecorationService", "IThemeService", "WidthCache", "canvasFactory", "WidthCacheFontVariantCanvas", "font", "fontSize", "weight", "weightBold", "c", "bold", "italic", "cp", "width", "key", "variant", "throwIfFalsy", "fontFamily", "fontWeight", "fontStyle", "SelectionRenderModel", "terminal", "start", "end", "columnSelectMode", "viewportY", "viewportStartRow", "viewportEndRow", "viewportCappedStartRow", "viewportCappedEndRow", "x", "y", "createSelectionRenderModel", "TextBlinkStateManager", "Disposable", "_renderCallback", "_coreBrowserService", "_optionsService", "duration", "toDisposable", "needsBlinkInViewport", "isVisible", "wasBlinkOn", "nextTerminalId", "DomRenderer", "Disposable", "_terminal", "_document", "_element", "_screenElement", "_viewportElement", "_helperContainer", "_linkifier2", "instantiationService", "_charSizeService", "_optionsService", "_bufferService", "_coreService", "_coreBrowserService", "_themeService", "createSelectionRenderModel", "Emitter", "createRenderDimensions", "e", "DomRendererRowFactory", "CursorBlinkStateManager", "addDisposableListener", "toDisposable", "TextBlinkStateManager", "WidthCache", "dpr", "element", "styles", "colors", "color", "blinkAnimationUnderlineId", "blinkAnimationBarId", "blinkAnimationBlockId", "i", "c", "spacing", "cols", "rows", "row", "isVisible", "start", "end", "columnSelectMode", "oldViewportStart", "oldViewportEnd", "newViewportStart", "newViewportEnd", "viewportStartRow", "viewportEndRow", "viewportCappedStartRow", "viewportCappedEndRow", "documentFragment", "isXFlipped", "startCol", "endCol", "middleRowsCount", "finalEndCol", "renderStartRow", "renderEndRow", "cursorViewportRow", "colStart", "colEnd", "rowCount", "left", "width", "buffer", "cursorAbsoluteY", "cursorX", "cursorBlink", "cursorStyle", "cursorInactiveStyle", "rowInfo", "y", "rowElement", "lineData", "x", "x2", "y2", "enabled", "maxY", "bufferline", "hasBlinkingCells", "__decorateClass", "__decorateParam", "IInstantiationService", "ICharSizeService", "IOptionsService", "IBufferService", "ICoreService", "ICoreBrowserService", "IThemeService", "_rowContainer", "CharSizeService", "Disposable", "document", "parentElement", "_optionsService", "Emitter", "TextMetricsMeasureStrategy", "DomMeasureStrategy", "result", "__decorateClass", "__decorateParam", "IOptionsService", "BaseMeasureStategy", "Disposable", "width", "height", "DomMeasureStrategy", "_document", "_parentElement", "_optionsService", "TextMetricsMeasureStrategy", "a", "metrics", "CoreBrowserService", "Disposable", "_textarea", "_window", "mainDocument", "Emitter", "ScreenDprMonitor", "w", "EventUtils", "addDisposableListener", "value", "_parentWindow", "MutableDisposable", "toDisposable", "parentWindow", "LinkProviderService", "Disposable", "toDisposable", "linkProvider", "providerIndex", "getCoordsRelativeToElement", "window", "event", "element", "rect", "elementStyle", "leftPadding", "topPadding", "getCoords", "colCount", "rowCount", "hasValidCharSize", "cssCellWidth", "cssCellHeight", "isSelection", "coords", "MouseCoordsService", "_charSizeService", "_renderService", "event", "element", "colCount", "rowCount", "isSelection", "getCoords", "getWindow", "coords", "getCoordsRelativeToElement", "__decorateClass", "__decorateParam", "ICharSizeService", "IRenderService", "mainWindow", "tail", "array", "n", "memoize", "_target", "key", "descriptor", "fnKey", "fn", "memoizeKey", "descriptorAny", "args", "_LinkedListNode", "element", "LinkedListNode", "LinkedList", "atTheEnd", "newNode", "oldLast", "oldFirst", "didRemove", "node", "anchor", "EventType", "_Gesture", "Disposable", "targetWindow", "addDisposableListener", "e", "remove", "toDisposable", "timestamp", "i", "len", "touch", "evt", "activeTouchCount", "data", "holdTime", "finalX", "finalY", "deltaT", "deltaX", "deltaY", "dispatchTo", "t", "type", "initialTarget", "event", "currentTime", "setTapCount", "ignoreTarget", "targets", "target", "depth", "now", "a", "b", "t1", "vX", "dirX", "x", "vY", "dirY", "y", "scheduleAtNextAnimationFrame", "deltaPosX", "deltaPosY", "stopped", "d", "__decorateClass", "Gesture", "MouseService", "_renderService", "_mouseCoordsService", "_mouseStateService", "_coreService", "_bufferService", "_optionsService", "_selectionService", "_logService", "_coreBrowserService", "target", "register", "focus", "element", "document", "requestedEvents", "ctx", "eventListeners", "ev", "AltMouseCursorController", "events", "toDisposable", "addDisposableListener", "Gesture", "EventType", "e", "pos", "but", "action", "deltaY", "stripAltFromReport", "sequence", "cellHeight", "lines", "i", "amount", "dpr", "targetWheelEventPixels", "report", "e1", "e2", "pixels", "__decorateClass", "__decorateParam", "IRenderService", "IMouseCoordsService", "IMouseStateService", "ICoreService", "IBufferService", "IOptionsService", "ISelectionService", "ILogService", "ICoreBrowserService", "_element", "_document", "_isActive", "MutableDisposable", "store", "DisposableStore", "syncFromModifier", "targetWindow", "altHeld", "RenderDebouncer", "_renderCallback", "_coreBrowserService", "callback", "rowStart", "rowEnd", "rowCount", "start", "end", "TaskQueue", "logService", "task", "deadline", "taskDuration", "longestTask", "lastDeadlineRemaining", "deadlineRemaining", "PriorityTaskQueue", "callback", "identifier", "duration", "end", "IdleTaskQueueInternal", "IdleTaskQueue", "DebouncedIdleTask", "RenderService", "Disposable", "_rowCount", "screenElement", "_optionsService", "_logService", "_charSizeService", "_coreService", "decorationService", "bufferService", "_coreBrowserService", "themeService", "MutableDisposable", "Emitter", "DebouncedIdleTask", "RenderDebouncer", "start", "end", "SynchronizedOutputHandler", "toDisposable", "w", "observer", "e", "entry", "sync", "isRedrawOnly", "buffered", "cols", "rows", "renderer", "callback", "columnSelectMode", "__decorateClass", "__decorateParam", "IOptionsService", "ILogService", "ICharSizeService", "ICoreService", "IDecorationService", "IBufferService", "ICoreBrowserService", "IThemeService", "_onTimeout", "result", "moveToCellSequence", "targetX", "targetY", "bufferService", "applicationCursor", "startX", "startY", "resetStartingRow", "moveToRequestedRow", "moveToRequestedCol", "direction", "repeat", "sequence", "rowDifference", "cellsToMove", "colsFromRowEnd", "colsFromRowBeginning", "currX", "bufferLine", "wrappedRowsForRow", "startRow", "endRow", "rowsToMove", "wrappedRowsCount", "verticalDirection", "horizontalDirection", "wrappedRows", "i", "currentRow", "rowCount", "line", "lineWraps", "startCol", "endCol", "forward", "currentCol", "bufferStr", "mod", "count", "str", "rpt", "SelectionModel", "_bufferService", "startPlusLength", "start", "end", "amount", "getRangeLength", "range", "bufferCols", "NON_BREAKING_SPACE_CHAR", "ALL_NON_BREAKING_SPACE_REGEX", "SelectionService", "Disposable", "_element", "_screenElement", "_linkifier", "_bufferService", "_coreService", "_mouseCoordsService", "_optionsService", "_mouseStateService", "_renderService", "_coreBrowserService", "MutableDisposable", "CellData", "Emitter", "event", "amount", "e", "SelectionModel", "toDisposable", "start", "end", "buffer", "result", "startCol", "endCol", "i", "lineText", "startRowEndCol", "bufferLine", "line", "ALL_NON_BREAKING_SPACE_REGEX", "isWindows", "isLinuxMouseSelection", "isLinux", "coords", "x", "y", "allowWhitespaceOnlySelection", "range", "getRangeLength", "offset", "getCoordsRelativeToElement", "terminalHeight", "isMac", "hadSelection", "previousSelectionEnd", "timeElapsed", "coordinates", "sequence", "moveToCellSequence", "hasSelection", "charIndex", "length", "col", "row", "ev", "followWrappedLinesAbove", "followWrappedLinesBelow", "startIndex", "endIndex", "charOffset", "leftWideCharCount", "rightWideCharCount", "leftLongCharOffset", "rightLongCharOffset", "previousBufferLine", "previousLineWordPosition", "nextBufferLine", "nextLineWordPosition", "wordPosition", "endRow", "cell", "wrappedRange", "__decorateClass", "__decorateParam", "IBufferService", "ICoreService", "IMouseCoordsService", "IOptionsService", "IMouseStateService", "IRenderService", "ICoreBrowserService", "TwoKeyMap", "first", "second", "value", "ColorContrastCache", "TwoKeyMap", "bg", "fg", "value", "DEFAULT_ANSI_COLORS", "colors", "css", "v", "i", "r", "g", "b", "channels", "c", "DEFAULT_FOREGROUND", "css", "DEFAULT_BACKGROUND", "DEFAULT_CURSOR", "DEFAULT_CURSOR_ACCENT", "DEFAULT_SELECTION", "DEFAULT_OVERVIEW_RULER_BORDER", "ThemeService", "Disposable", "_optionsService", "ColorContrastCache", "Emitter", "color", "DEFAULT_ANSI_COLORS", "theme", "colors", "parseColor", "NULL_COLOR", "colorCount", "i", "slot", "callback", "__decorateClass", "__decorateParam", "IOptionsService", "cssString", "fallback", "KEYCODE_KEY_MAPPINGS", "evaluateKeyboardEvent", "ev", "applicationCursorMode", "isMac", "macOptionIsMeta", "result", "modifiers", "key", "keyCode", "keyString", "KittyKeyboard", "ev", "suffix", "mods", "macOptionAsAlt", "numpadCode", "modifierCode", "funcCode", "digit", "code", "letter", "modifiers", "eventType", "reportEventTypes", "needsEventType", "seq", "number", "keyCode", "flags", "isFunc", "isMod", "reportAlternateKeys", "shiftedKey", "textCode", "result", "csiLetter", "ss3Letter", "tildeCode", "specialKey", "legacyByte", "Win32InputMode", "ev", "vk", "controlChar", "codePoint", "state", "isKeyDown", "sc", "uc", "kd", "cs", "KeyboardService", "_coreService", "_optionsService", "Win32InputMode", "KittyKeyboard", "event", "kittyFlags", "isMac", "evaluateKeyboardEvent", "__decorateClass", "__decorateParam", "ICoreService", "IOptionsService", "ServiceCollection", "entries", "id", "service", "instance", "result", "callback", "key", "value", "InstantiationService", "IInstantiationService", "ctor", "args", "serviceDependencies", "getServiceDependencies", "a", "b", "serviceArgs", "dependency", "firstServiceArgPos", "optionsKeyToLogLevel", "LOG_PREFIX", "LogService", "Disposable", "_optionsService", "optionalParams", "i", "type", "message", "__decorateClass", "__decorateParam", "IOptionsService", "CircularList", "Disposable", "_maxLength", "Emitter", "newMaxLength", "newArray", "i", "newLength", "index", "value", "start", "deleteCount", "items", "countToTrim", "count", "offset", "expandListBy", "StringBuilder", "chunk", "LimitedStringBuilder", "_limit", "DEFAULT_ATTR_DATA", "AttributeData", "$startIndex", "$workCell", "CellData", "$translateToStringBuilder", "StringBuilder", "BufferLine", "_BufferLine", "_stringCache", "cols", "fillCellData", "isWrapped", "cell", "i", "index", "content", "cp", "stringFromCodePoint", "value", "codePoint", "width", "attrs", "pos", "n", "start", "end", "respectProtect", "uint32Cells", "data", "keys", "key", "extKeys", "line", "newLine", "src", "srcCol", "destCol", "length", "applyInReverse", "srcData", "trimRight", "startCol", "endCol", "outColumns", "isCanonicalRequest", "stringCacheEntry", "chars", "result", "cacheEntry", "createIfNeeded", "cachedEntry", "srcStart", "BufferLineStringCache", "Disposable", "MutableDisposable", "toDisposable", "entry", "timeoutMs", "disposableTimeout", "elapsed", "reflowLargerGetLinesToRemove", "lines", "oldCols", "newCols", "bufferAbsoluteY", "nullCell", "reflowCursorLine", "toRemove", "y", "i", "nextLine", "wrappedLines", "destLineIndex", "destCol", "getWrappedLineTrimmedLength", "srcLineIndex", "srcCol", "srcTrimmedTineLength", "srcRemainingCells", "destRemainingCells", "cellsToCopy", "countToRemove", "reflowLargerCreateNewLayout", "layout", "nextToRemoveIndex", "nextToRemoveStart", "countRemovedSoFar", "reflowLargerApplyNewLayout", "newLayout", "newLayoutLines", "reflowSmallerGetNewLineLengths", "newLineLengths", "cellsNeeded", "srcLine", "cellsAvailable", "oldTrimmedLength", "endsWithWide", "lineLength", "cols", "endsInNull", "followingLineStartsWithWide", "_Marker", "line", "Emitter", "dispose", "disposable", "Marker", "CHARSETS", "DEFAULT_CHARSET", "MAX_BUFFER_SIZE", "Buffer", "Disposable", "_hasScrollback", "_optionsService", "_bufferService", "_logService", "DEFAULT_ATTR_DATA", "DEFAULT_CHARSET", "CellData", "CircularList", "IdleTaskQueue", "toDisposable", "BufferLineStringCache", "attr", "ExtendedAttrs", "isWrapped", "BufferLine", "relativeY", "rows", "correctBufferLength", "fillAttr", "i", "newCols", "newRows", "nullCell", "dirtyMemoryLines", "newMaxLength", "addToY", "y", "amountToTrim", "maxY", "normalRun", "counted", "windowsPty", "reflowCursorLine", "toRemove", "reflowLargerGetLinesToRemove", "newLayoutResult", "reflowLargerCreateNewLayout", "reflowLargerApplyNewLayout", "countRemoved", "viewportAdjustments", "toInsert", "countToInsert", "nextLine", "wrappedLines", "absoluteY", "lastLineLength", "destLineLengths", "reflowSmallerGetNewLineLengths", "linesToAdd", "trimmedLines", "newLines", "newLine", "destLineIndex", "destCol", "srcLineIndex", "srcCol", "cellsToCopy", "wrappedLinesIndex", "getWrappedLineTrimmedLength", "insertEvents", "originalLines", "originalLinesLength", "originalLineIndex", "nextToInsertIndex", "nextToInsert", "countInsertedSoFar", "nextI", "insertCountEmitted", "lineIndex", "trimRight", "startCol", "endCol", "line", "first", "last", "x", "marker", "Marker", "amount", "event", "BufferSet", "Disposable", "_optionsService", "_bufferService", "_logService", "MutableDisposable", "Emitter", "Buffer", "fillAttr", "newCols", "newRows", "i", "BufferService", "Disposable", "optionsService", "logService", "Emitter", "BufferSet", "e", "cols", "rows", "colsChanged", "rowsChanged", "eraseAttr", "isWrapped", "buffer", "newLine", "topRow", "bottomRow", "willBufferBeTrimmed", "scrollRegionHeight", "disp", "suppressScrollEvent", "oldYdisp", "__decorateClass", "__decorateParam", "IOptionsService", "ILogService", "DEFAULT_OPTIONS", "isMac", "FONT_WEIGHT_OPTIONS", "OptionsService", "Disposable", "options", "Emitter", "defaultOptions", "key", "newValue", "e", "toDisposable", "listener", "eventKey", "keys", "getter", "propName", "setter", "value", "desc", "isCursorStyle", "DEFAULT_MODES", "DEFAULT_DEC_PRIVATE_MODES", "DEFAULT_KITTY_KEYBOARD_STATE", "CoreService", "Disposable", "_bufferService", "_logService", "_optionsService", "Emitter", "data", "wasUserInput", "buffer", "e", "__decorateClass", "__decorateParam", "IBufferService", "ILogService", "IOptionsService", "DEFAULT_PROTOCOLS", "e", "eventCode", "e", "isSGR", "code", "S", "DEFAULT_ENCODINGS", "params", "final", "MouseStateService", "Disposable", "Emitter", "name", "DEFAULT_PROTOCOLS", "protocol", "encoding", "customWheelEventHandler", "ev", "UnicodeService", "_UnicodeService", "Emitter", "value", "state", "width", "shouldJoin", "version", "provider", "num", "s", "result", "precedingInfo", "length", "i", "code", "second", "currentInfo", "chWidth", "codepoint", "preceding", "BMP_COMBINING", "HIGH_COMBINING", "table", "bisearch", "ucs", "data", "min", "max", "mid", "UnicodeV6", "r", "num", "codepoint", "preceding", "width", "shouldJoin", "oldWidth", "UnicodeService", "CharsetService", "g", "charset", "updateWindowsModeWrappedState", "bufferService", "lastChar", "nextLine", "Params", "_Params", "maxLength", "maxSubParamsLength", "values", "params", "i", "value", "k", "newParams", "res", "start", "end", "idx", "result", "length", "store", "cur", "EMPTY_HANDLERS", "OscParser", "ident", "handler", "handlerList", "handlerIndex", "j", "data", "start", "end", "utf32ToString", "code", "success", "promiseResult", "handlerResult", "fallThrough", "_OscHandler", "_handler", "LimitedStringBuilder", "ret", "res", "OscHandler", "EMPTY_HANDLERS", "DcsParser", "ident", "handler", "handlerList", "handlerIndex", "j", "params", "data", "start", "end", "utf32ToString", "success", "promiseResult", "handlerResult", "fallThrough", "EMPTY_PARAMS", "Params", "_DcsHandler", "_handler", "LimitedStringBuilder", "ret", "res", "DcsHandler", "EMPTY_HANDLERS", "ApcParser", "ident", "handler", "handlerList", "handlerIndex", "j", "data", "start", "end", "utf32ToString", "success", "promiseResult", "handlerResult", "fallThrough", "_ApcHandler", "_handler", "LimitedStringBuilder", "ret", "res", "ApcHandler", "TransitionTable", "length", "action", "next", "code", "state", "codes", "i", "NON_ASCII_PRINTABLE", "VT500_TRANSITION_TABLE", "table", "blueprint", "unused", "r", "start", "end", "PRINTABLES", "EXECUTABLES", "states", "EscapeSequenceParser", "Disposable", "_transitions", "Params", "data", "ident", "params", "toDisposable", "OscParser", "DcsParser", "ApcParser", "id", "finalRange", "res", "intermediate", "finalCode", "handler", "handlerList", "handlerIndex", "flag", "callback", "handlers", "handlerPos", "transition", "chunkPos", "promiseResult", "handlerResult", "k", "ch", "csiDone", "j", "c", "l4", "handlersEsc", "jj", "RGB_REX", "HASH_REX", "parseColor", "data", "low", "m", "base", "adv", "result", "i", "c", "pad", "bits", "s", "s2", "toRgbString", "color", "r", "g", "b", "XTERM_VERSION", "GLEVEL", "paramToWindowOption", "opts", "$temp", "InputHandler", "Disposable", "_bufferService", "_charsetService", "_coreService", "_logService", "_optionsService", "_oscLinkService", "_mouseStateService", "_unicodeService", "_parser", "EscapeSequenceParser", "StringToUtf32", "Utf8ToUtf32", "DEFAULT_ATTR_DATA", "Emitter", "DirtyRowTracker", "e", "ident", "params", "code", "identifier", "action", "data", "payload", "start", "end", "OscHandler", "flag", "CHARSETS", "state", "DcsHandler", "cursorStartX", "cursorStartY", "decodedLength", "position", "p", "slowTimeout", "slowPromise", "_res", "rej", "err", "promiseResult", "result", "wasPaused", "i", "len", "viewportEnd", "viewportStart", "chWidth", "charset", "screenReaderMode", "cols", "wraparoundMode", "insertMode", "curAttr", "bufferRow", "precedingJoinState", "pos", "ch", "currentInfo", "UnicodeService", "shouldJoin", "oldWidth", "stringFromCodePoint", "linkId", "oldRow", "oldCol", "BufferLine", "offset", "delta", "id", "callback", "paramToWindowOption", "ApcHandler", "line", "originalX", "maxCol", "x", "y", "diffToTop", "diffToBottom", "param", "clearWrap", "respectProtect", "j", "nextLine", "scrollBackSize", "row", "scrollBottomRowsOffset", "scrollBottomAbsolute", "joinState", "length", "text", "idata", "itext", "tlength", "XTERM_VERSION", "term", "DEFAULT_CHARSET", "ansi", "V", "dm", "mouseProtocol", "mouseEncoding", "cs", "buffers", "active", "alt", "opts", "f", "m", "v", "b2v", "value", "color", "mode", "c1", "c2", "c3", "AttributeData", "attr", "accu", "cSpace", "advance", "subparams", "style", "l", "isBlinking", "top", "bottom", "second", "event", "slots", "idx", "spec", "index", "isValidColorIndex", "parseColor", "uri", "parsedParams", "idParamIndex", "collectAndFlag", "GLEVEL", "scrollRegionHeight", "level", "cell", "CellData", "yOffset", "s", "b", "STYLES", "y1", "y2", "flags", "stack", "count", "__decorateClass", "__decorateParam", "IBufferService", "WriteBuffer", "Disposable", "_action", "TimeoutTimer", "Emitter", "toDisposable", "chunk", "didProcess", "cb", "data", "maxSubsequentCalls", "callback", "lastTime", "promiseResult", "startTime", "result", "continuation", "r", "err", "OscLinkService", "_bufferService", "data", "buffer", "marker", "entry", "castData", "key", "match", "linkId", "y", "e", "linkData", "index", "__decorateClass", "__decorateParam", "IBufferService", "hasWriteSyncWarnHappened", "CoreTerminal", "Disposable", "options", "MutableDisposable", "Emitter", "InstantiationService", "OptionsService", "IOptionsService", "LogService", "ILogService", "BufferService", "IBufferService", "CoreService", "ICoreService", "MouseStateService", "IMouseStateService", "UnicodeService", "UnicodeV6", "IUnicodeService", "CharsetService", "ICharsetService", "OscLinkService", "IOscLinkService", "InputHandler", "EventUtils", "WriteBuffer", "data", "promiseResult", "ev", "key", "callback", "maxSubsequentCalls", "wasUserInput", "x", "y", "eraseAttr", "isWrapped", "disp", "suppressScrollEvent", "pageCount", "disableSmoothScroll", "line", "scrollAmount", "id", "ident", "value", "windowsPty", "disposables", "updateWindowsModeWrappedState", "toDisposable", "d", "i", "SortedList", "_getKey", "logService", "IdleTaskQueue", "value", "sortedAddedValues", "a", "b", "sortedAddedValuesIndex", "arrayIndex", "newArray", "newArrayIndex", "key", "sortedDeletedIndices", "sortedDeletedIndicesIndex", "callback", "min", "max", "mid", "midKey", "$xmin", "$xmax", "DecorationService", "Disposable", "_logService", "_bufferService", "DecorationLineCache", "Emitter", "SortedList", "e", "toDisposable", "options", "decoration", "Decoration", "markerDispose", "listener", "d", "x", "line", "layer", "bucket", "callback", "__decorateClass", "__decorateParam", "ILogService", "IBufferService", "MutableDisposable", "MicrotaskTimer", "lines", "store", "DisposableStore", "amount", "event", "start", "height", "index", "callbacks", "cb", "newMap", "newLine", "existing", "i", "len", "spanCrossers", "deleteEnd", "toReindex", "css", "RENDER_DEBOUNCE_THRESHOLD_MS", "TimeBasedDebouncer", "_renderCallback", "_debounceThresholdMS", "rowStart", "rowEnd", "rowCount", "refreshRequestTime", "elapsed", "waitPeriodBeforeTrailingRefresh", "start", "end", "DEBUG", "AccessibilityManager", "Disposable", "_terminal", "instantiationService", "_coreBrowserService", "_renderService", "doc", "i", "e", "TimeBasedDebouncer", "char", "spaceCount", "addDisposableListener", "toDisposable", "tooMuchOutput", "keyChar", "start", "end", "buffer", "setSize", "line", "columns", "lineData", "posInSet", "element", "position", "boundaryElement", "beforeBoundaryElement", "lastRowPos", "topBoundaryElement", "bottomBoundaryElement", "newElement", "selection", "begin", "lastRowElement", "toRowColumn", "node", "offset", "rowElement", "row", "column", "beginRowColumn", "endRowColumn", "rows", "width", "lastColumn", "targetWidth", "__decorateClass", "__decorateParam", "IInstantiationService", "ICoreBrowserService", "IRenderService", "Linkifier", "Disposable", "_element", "_mouseCoordsService", "_renderService", "_bufferService", "_linkProviderService", "Emitter", "toDisposable", "dispose", "addDisposableListener", "event", "position", "composedPath", "i", "target", "useLineCache", "reply", "linkWithState", "linkProvided", "linkProvider", "links", "linksWithState", "link", "y", "replies", "occupiedCells", "providerReply", "startX", "endX", "x", "index", "hasLinkBefore", "j", "linkAtPosition", "currentLink", "linkEquals", "startRow", "endRow", "v", "e", "start", "end", "element", "showEvent", "range", "scrollOffset", "lower", "upper", "current", "coords", "x1", "y1", "x2", "y2", "fg", "__decorateClass", "__decorateParam", "IMouseCoordsService", "IRenderService", "IBufferService", "ILinkProviderService", "a", "b", "CoreBrowserTerminal", "CoreTerminal", "options", "MutableDisposable", "Platform_exports", "Emitter", "DecorationService", "IDecorationService", "KeyboardService", "IKeyboardService", "LinkProviderService", "ILinkProviderService", "OscLinkProvider", "e", "type", "event", "EventUtils", "toDisposable", "dimensions", "req", "acc", "ident", "colorRgb", "color", "toRgbString", "colors", "channels", "narrowedAcc", "bgLuminance", "rgb", "fgLuminance", "colorSchemeMode", "value", "AccessibilityManager", "ev", "cursorY", "bufferLine", "cursorX", "cellHeight", "width", "cellWidth", "cursorTop", "cursorLeft", "addDisposableListener", "copyHandler", "pasteHandlerWrapper", "handlePasteEvent", "isFirefox", "rightClickHandler", "isLinux", "moveTextAreaUnderMouseCursor", "parent", "fragment", "textarea", "promptLabel", "isChromeOS", "CoreBrowserService", "ICoreBrowserService", "CharSizeService", "ICharSizeService", "ThemeService", "IThemeService", "CharacterJoinerService", "ICharacterJoinerService", "RenderService", "IRenderService", "CompositionHelper", "MouseCoordsService", "IMouseCoordsService", "linkifier", "Linkifier", "Viewport", "SelectionService", "ISelectionService", "MouseService", "IMouseService", "text", "BufferDecorationRenderer", "showScrollbar", "overviewRulerWidth", "OverviewRulerRenderer", "shouldShow", "amount", "disposable", "DomRenderer", "start", "end", "sync", "disp", "suppressScrollEvent", "pageCount", "disableSmoothScroll", "line", "scrollAmount", "data", "paste", "customKeyEventHandler", "customWheelEventHandler", "linkProvider", "handler", "joinerId", "cursorYOffset", "decorationOptions", "column", "row", "length", "shouldIgnoreComposition", "result", "scrollCount", "wasModifierOnly", "wasModifierKeyOnlyEvent", "browser", "thirdLevelKey", "key", "x", "y", "i", "DEFAULT_ATTR_DATA", "canvasWidth", "canvasHeight", "AddonManager", "terminal", "instance", "loadedAddon", "index", "i", "BufferLineApiView", "_line", "x", "cell", "CellData", "trimRight", "startColumn", "endColumn", "BufferApiView", "_buffer", "type", "buffer", "y", "line", "BufferLineApiView", "CellData", "BufferNamespaceApi", "Disposable", "_core", "Emitter", "BufferApiView", "ParserApi", "_core", "id", "callback", "params", "data", "handler", "ident", "UnicodeApi", "_core", "provider", "version", "CONSTRUCTOR_ONLY_OPTIONS", "$value", "Terminal", "Disposable", "options", "CoreBrowserTerminal", "AddonManager", "getter", "propName", "setter", "value", "desc", "ParserApi", "UnicodeApi", "BufferNamespaceApi", "m", "mouseTrackingMode", "data", "wasUserInput", "columns", "rows", "parent", "customKeyEventHandler", "customWheelEventHandler", "linkProvider", "handler", "joinerId", "cursorYOffset", "decorationOptions", "column", "row", "length", "start", "end", "amount", "pageCount", "line", "callback", "addon", "promptLabel", "tooMuchOutput", "values"] -+ "sourcesContent": ["/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (\u241B).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\ninterface IPendingComposition {\n transactionId: number;\n finalizerTimer?: ReturnType;\n lifecycleSettled: boolean;\n sessionEnded: boolean;\n position: IPosition;\n suffix: string;\n dataAlreadySent: string;\n compositionData: string;\n endData: string;\n inputData: string;\n keypressData: string;\n keypressMayOverlapComposition: boolean;\n expectsPostCompositionInput: boolean;\n nextCompositionStart?: number;\n}\n\nconst XTERM_COMPOSITION_SESSION_START_EVENT = 'xterm-composition-session-start';\nconst XTERM_COMPOSITION_SESSION_END_EVENT = 'xterm-composition-session-end';\nconst XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT =\n 'xterm-composition-transaction-accepted';\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n public get hasPendingCompositionFinalization(): boolean {\n return this._pendingComposition !== undefined;\n }\n public get _isSendingComposition(): boolean {\n return this.hasPendingCompositionFinalization;\n }\n public get _pendingKeypressData(): string {\n return this._pendingComposition?.keypressData ?? '';\n }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n private _pendingComposition?: IPendingComposition;\n\n private _isAwaitingCompositionEnd: boolean;\n\n private _compositionInputData: string;\n\n private _lastCompositionData: string;\n\n private _compositionStartValue: string;\n\n private _compositionStartSelection: IPosition;\n\n private _compositionHasObservedProgress: boolean;\n\n private _canceledKey?: Pick;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n /**\n * Identifies the composition transaction that owns deferred work.\n */\n private _compositionTransactionId: number;\n\n /**\n * Timers that still own deferred composition state.\n */\n private _compositionTimers: Set>;\n\n private _compositionPositionTimer?: ReturnType;\n\n private _compositionViewTimer?: ReturnType;\n\n private _compositionEndTimer?: ReturnType;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isAwaitingCompositionEnd = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionStartValue = '';\n this._compositionStartSelection = { start: 0, end: 0 };\n this._compositionHasObservedProgress = false;\n this._compositionTransactionId = 0;\n this._compositionTimers = new Set();\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = undefined;\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = undefined;\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._pendingComposition) {\n this._cancelPendingFinalizer(this._pendingComposition);\n this._endPendingCompositionSession(this._pendingComposition);\n this._settlePendingComposition(this._pendingComposition);\n }\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionStartValue = this._textarea.value;\n this._compositionStartSelection = { start, end };\n this._compositionHasObservedProgress = false;\n if (this._pendingComposition) {\n this._pendingComposition.nextCompositionStart = this._compositionPosition.start;\n }\n this._compositionTransactionId++;\n this._isComposing = true;\n this._isAwaitingCompositionEnd = true;\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionView.classList.add('active');\n this._dispatchCompositionSessionEvent(new CustomEvent(XTERM_COMPOSITION_SESSION_START_EVENT, {\n bubbles: true,\n detail: { id: this._compositionTransactionId }\n }));\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (ev.data?.length > 0) {\n this._lastCompositionData = ev.data;\n }\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data ?? ''}\\u200E`;\n this.updateCompositionElements();\n const transactionId = this._compositionTransactionId;\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = this._defer(() => {\n if (this._isComposing && this._compositionTransactionId === transactionId) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n });\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(ev?: Pick): boolean {\n if (!this._isAwaitingCompositionEnd) {\n return false;\n }\n if (!this._isComposing) {\n const pending = this._pendingComposition;\n if (pending?.transactionId === this._compositionTransactionId) {\n pending.endData = ev?.data ?? '';\n this._updatePostCompositionInputExpectation(pending);\n }\n return false;\n }\n const endData = ev?.data ?? '';\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (!this._compositionEndBelongsToCurrentTransaction(endData)) {\n const pending = this._pendingComposition;\n if (pending && pending.transactionId !== this._compositionTransactionId) {\n this._sendPendingComposition(pending);\n }\n this._deferCompositionEnd(endData);\n return false;\n }\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n return true;\n }\n\n public blur(): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._isComposing) {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n this._finalizeComposition(false);\n }\n }\n\n public dispose(): void {\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n for (const timer of this._compositionTimers) {\n clearTimeout(timer);\n }\n this._compositionTimers.clear();\n this._compositionPositionTimer = undefined;\n this._compositionViewTimer = undefined;\n this._compositionEndTimer = undefined;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionTransactionId++;\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._canceledKey?.code === ev.code && this._canceledKey.timeStamp === ev.timeStamp) {\n this._canceledKey = undefined;\n return false;\n }\n if (ev.key === 'Escape' && (this._isComposing || this.hasPendingCompositionFinalization)) {\n this._canceledKey = { code: ev.code, timeStamp: ev.timeStamp };\n this._cancelComposition();\n return false;\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Defers keypress text while a composition finalizer is pending so all input is emitted once\n * after reconciliation with the final textarea candidate.\n */\n public keypress(text: string): boolean {\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.keypressMayOverlapComposition) {\n pending.keypressData += text;\n return true;\n }\n if (pending.expectsPostCompositionInput && pending.keypressData.length === 0) {\n pending.keypressData = text;\n return true;\n }\n this._sendPendingComposition(pending);\n return false;\n }\n\n public input(text: string): boolean {\n if (this._isComposing) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n this._compositionInputData += text;\n return true;\n }\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.expectsPostCompositionInput) {\n pending.inputData += text;\n pending.expectsPostCompositionInput = false;\n this._sendPendingComposition(pending);\n return true;\n }\n const repeatsPendingTextareaInput =\n text.length > 0 &&\n this._getPendingTextareaInput(pending) === text &&\n this._getPendingTextareaInput(pending, true) === text;\n this._sendPendingComposition(pending);\n if (!repeatsPendingTextareaInput) {\n this._coreService.triggerDataEvent(text, true);\n }\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean, endData: string = ''): void {\n const wasComposing = this._isComposing;\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n if (waitForPropagation && !wasComposing) {\n return;\n }\n\n if (!waitForPropagation) {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition, true);\n }\n if (wasComposing) {\n const input = this._getCompositionInput(\n this._compositionPosition.start + this._dataAlreadySent.length,\n this._compositionSuffix\n );\n this._sendCompositionInput(this._compositionTransactionId, input);\n }\n } else {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition);\n }\n const pending: IPendingComposition = {\n transactionId: this._compositionTransactionId,\n lifecycleSettled: false,\n sessionEnded: false,\n position: {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n },\n suffix: this._compositionSuffix,\n dataAlreadySent: this._dataAlreadySent,\n compositionData: this._lastCompositionData,\n endData,\n inputData: this._compositionInputData,\n keypressData: '',\n keypressMayOverlapComposition:\n this._lastCompositionData.length === 0 && endData.length === 0,\n expectsPostCompositionInput: false\n };\n this._updatePostCompositionInputExpectation(pending);\n this._pendingComposition = pending;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n pending.finalizerTimer = this._defer(() => {\n pending.finalizerTimer = undefined;\n if (this._compositionTransactionId === pending.transactionId) {\n this._isAwaitingCompositionEnd = false;\n }\n if (this._pendingComposition === pending) {\n this._sendPendingComposition(pending, true);\n }\n });\n }\n }\n\n private _sendPendingComposition(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): void {\n this._cancelPendingFinalizer(pending);\n if (this._pendingComposition === pending) {\n this._pendingComposition = undefined;\n }\n const textareaInput = this._getPendingTextareaInput(pending, includeFollowingInput);\n const observedInput = this._removeAlreadySentData(\n pending.inputData || pending.keypressData,\n pending.dataAlreadySent\n );\n const input = this._mergeTextObservations(\n textareaInput || pending.endData || pending.compositionData,\n observedInput,\n pending.keypressMayOverlapComposition\n );\n this._sendCompositionInput(pending.transactionId, input, !pending.sessionEnded);\n this._settlePendingComposition(pending);\n }\n\n private _cancelPendingFinalizer(pending: IPendingComposition): void {\n if (pending.finalizerTimer === undefined) {\n return;\n }\n clearTimeout(pending.finalizerTimer);\n this._compositionTimers.delete(pending.finalizerTimer);\n pending.finalizerTimer = undefined;\n }\n\n private _settlePendingComposition(pending: IPendingComposition): void {\n if (pending.lifecycleSettled) {\n return;\n }\n pending.lifecycleSettled = true;\n this._dispatchCompositionTransactionSettled();\n }\n\n private _mergeTextObservations(\n candidate: string,\n observed: string,\n findShortestOrder: boolean\n ): string {\n if (!observed || candidate.includes(observed)) {\n return candidate;\n }\n if (!candidate || observed.includes(candidate)) {\n return observed;\n }\n if (findShortestOrder) {\n let candidateFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n candidateFirstOverlap > 0 &&\n !candidate.endsWith(observed.substring(0, candidateFirstOverlap))\n ) {\n candidateFirstOverlap--;\n }\n let observedFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n observedFirstOverlap > 0 &&\n !observed.endsWith(candidate.substring(0, observedFirstOverlap))\n ) {\n observedFirstOverlap--;\n }\n return candidateFirstOverlap > observedFirstOverlap\n ? candidate + observed.substring(candidateFirstOverlap)\n : observed + candidate.substring(observedFirstOverlap);\n }\n let overlap = Math.min(candidate.length, observed.length);\n while (overlap > 0 && !candidate.endsWith(observed.substring(0, overlap))) {\n overlap--;\n }\n return candidate + observed.substring(overlap);\n }\n\n private _updatePostCompositionInputExpectation(pending: IPendingComposition): void {\n pending.expectsPostCompositionInput =\n (pending.endData.length > 0 || pending.compositionData.length > 0) &&\n pending.inputData.length === 0 &&\n this._getPendingTextareaInput(pending).length === 0;\n }\n\n private _getPendingTextareaInput(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): string {\n const value = this._textarea.value;\n const start = pending.position.start + pending.dataAlreadySent.length;\n if (pending.nextCompositionStart !== undefined) {\n return value.substring(start, Math.max(start, pending.nextCompositionStart));\n }\n const suffixEnd =\n pending.suffix.length > 0 && value.endsWith(pending.suffix)\n ? value.length - pending.suffix.length\n : value.length;\n const compositionLength = (pending.endData || pending.compositionData).length;\n const observedEnd = includeFollowingInput\n ? suffixEnd\n : Math.max(pending.position.end, start + compositionLength);\n return value.substring(start, Math.max(start, Math.min(suffixEnd, observedEnd)));\n }\n\n private _getCompositionInput(start: number, suffix: string): string {\n const value = this._textarea.value;\n const valueEnd =\n suffix.length > 0 && value.endsWith(suffix) ? value.length - suffix.length : value.length;\n return value.substring(start, Math.max(start, valueEnd));\n }\n\n private _removeAlreadySentData(input: string, dataAlreadySent: string): string {\n if (dataAlreadySent.length === 0) {\n return input;\n }\n if (input.startsWith(dataAlreadySent)) {\n return input.substring(dataAlreadySent.length);\n }\n return dataAlreadySent.includes(input) ? '' : input;\n }\n\n private _cancelComposition(): void {\n const pending = this._pendingComposition;\n if (\n pending &&\n this._isComposing &&\n pending.transactionId !== this._compositionTransactionId\n ) {\n this._sendPendingComposition(pending);\n }\n const transactionId = this._isComposing\n ? this._compositionTransactionId\n : this._pendingComposition?.transactionId ?? 0;\n const settlesPending = pending !== undefined && this._pendingComposition === pending;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionView.classList.remove('active');\n this._textarea.value =\n this._textarea.value.substring(0, this._compositionPosition.start) + this._compositionSuffix;\n this._sendCompositionInput(transactionId, '');\n if (settlesPending && pending) {\n this._settlePendingComposition(pending);\n }\n }\n\n private _sendCompositionInput(\n transactionId: number,\n input: string,\n dispatchSessionEnd: boolean = true\n ): void {\n let prevented = false;\n if (dispatchSessionEnd) {\n const event = new CustomEvent(XTERM_COMPOSITION_SESSION_END_EVENT, {\n bubbles: true,\n cancelable: true,\n detail: { id: transactionId, data: input }\n });\n this._dispatchCompositionSessionEvent(event);\n prevented = event.defaultPrevented;\n }\n if (input.length > 0 && !prevented) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n\n private _endPendingCompositionSession(pending: IPendingComposition): void {\n if (pending.sessionEnded) {\n return;\n }\n pending.sessionEnded = true;\n const input =\n this._getPendingTextareaInput(pending) ||\n pending.endData ||\n pending.compositionData;\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_SESSION_END_EVENT,\n {\n bubbles: true,\n cancelable: true,\n detail: {\n id: pending.transactionId,\n data: input,\n dataPendingReconciliation: true\n }\n }\n ));\n }\n\n private _dispatchCompositionSessionEvent(event: CustomEvent): void {\n if (typeof this._textarea.dispatchEvent === 'function') {\n this._textarea.dispatchEvent(event);\n }\n }\n\n private _dispatchCompositionTransactionSettled(): void {\n this._dispatchCompositionSessionEvent(new CustomEvent(\n 'xterm-composition-transaction-settled',\n { bubbles: true }\n ));\n }\n\n private _deferCompositionEnd(endData: string): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n const transactionId = this._compositionTransactionId;\n const timer = this._defer(() => {\n if (\n this._compositionEndTimer !== timer ||\n !this._isComposing ||\n this._compositionTransactionId !== transactionId ||\n !this._compositionEndBelongsToCurrentTransaction(endData)\n ) {\n return;\n }\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT,\n { bubbles: true }\n ));\n const pending = this._pendingComposition;\n if (pending?.transactionId === transactionId) {\n this._sendPendingComposition(pending, true);\n }\n });\n this._compositionEndTimer = timer;\n }\n\n private _hasCompositionProgress(): boolean {\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n return this._compositionHasObservedProgress || (\n this._textarea.value !== this._compositionStartValue ||\n start !== this._compositionStartSelection.start ||\n end !== this._compositionStartSelection.end\n );\n }\n\n private _compositionEndBelongsToCurrentTransaction(endData: string): boolean {\n return (\n this._hasCompositionProgress() ||\n (endData.length > 0 && endData === this._lastCompositionData)\n );\n }\n\n private _defer(callback: () => void): ReturnType {\n const timer = setTimeout(() => {\n this._compositionTimers.delete(timer);\n callback();\n }, 0);\n this._compositionTimers.add(timer);\n return timer;\n }\n\n private _cancelDeferredTimer(timer?: ReturnType): void {\n if (timer === undefined) {\n return;\n }\n clearTimeout(timer);\n this._compositionTimers.delete(timer);\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = this._defer(() => this.updateCompositionElements(true));\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n", "/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n", "/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n", "import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): boolean | void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n keypress?(text: string): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec \u00A7 \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" \u2014 i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n\u00B2) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '\u25C6'\n 'a': '\\u2592', // '\u2592'\n 'b': '\\u2409', // '\u2409' (HT)\n 'c': '\\u240c', // '\u240C' (FF)\n 'd': '\\u240d', // '\u240D' (CR)\n 'e': '\\u240a', // '\u240A' (LF)\n 'f': '\\u00b0', // '\u00B0'\n 'g': '\\u00b1', // '\u00B1'\n 'h': '\\u2424', // '\u2424' (NL)\n 'i': '\\u240b', // '\u240B' (VT)\n 'j': '\\u2518', // '\u2518'\n 'k': '\\u2510', // '\u2510'\n 'l': '\\u250c', // '\u250C'\n 'm': '\\u2514', // '\u2514'\n 'n': '\\u253c', // '\u253C'\n 'o': '\\u23ba', // '\u23BA'\n 'p': '\\u23bb', // '\u23BB'\n 'q': '\\u2500', // '\u2500'\n 'r': '\\u23bc', // '\u23BC'\n 's': '\\u23bd', // '\u23BD'\n 't': '\\u251c', // '\u251C'\n 'u': '\\u2524', // '\u2524'\n 'v': '\\u2534', // '\u2534'\n 'w': '\\u252c', // '\u252C'\n 'x': '\\u2502', // '\u2502'\n 'y': '\\u2264', // '\u2264'\n 'z': '\\u2265', // '\u2265'\n '{': '\\u03c0', // '\u03C0'\n '|': '\\u2260', // '\u2260'\n '}': '\\u00a3', // '\u00A3'\n '~': '\\u00b7' // '\u00B7'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '\u00A3'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '\u00A3',\n '@': '\u00BE',\n '[': 'ij',\n '\\\\': '\u00BD',\n ']': '|',\n '{': '\u00A8',\n '|': 'f',\n '}': '\u00BC',\n '~': '\u00B4'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '\u00A3',\n '@': '\u00E0',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00A7',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00A8'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': '\u00E0',\n '[': '\u00E2',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n '`': '\u00F4',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00FB'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '\u00A7',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00DC',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00DF'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00E9',\n '`': '\u00F9',\n '{': '\u00E0',\n '|': '\u00F2',\n '}': '\u00E8',\n '~': '\u00EC'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': '\u00C4',\n '[': '\u00C6',\n '\\\\': '\u00D8',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E4',\n '{': '\u00E6',\n '|': '\u00F8',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00A1',\n '\\\\': '\u00D1',\n ']': '\u00BF',\n '{': '\u00B0',\n '|': '\u00F1',\n '}': '\u00E7'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': '\u00C9',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': '\u00F9',\n '@': '\u00E0',\n '[': '\u00E9',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n\n '_': '\u00E8',\n '`': '\u00F4',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00FB'\n};\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n", "\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n", "/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n if (this._deleteAtKey(value, key)) {\n return true;\n }\n // A pending deletion whose key mutated after `delete()` (disposing a marker\n // resets `line` to -1, and `line` is the sort key) leaves `_array` out of\n // order, so the binary search above can miss a value that is present.\n // Compacting those entries out restores the order; retry before reporting\n // the value absent, else its `onDecorationRemoved` never fires and the\n // decoration paints forever. Miss path only, so the common bulk delete\n // keeps its O(log n) search and deferred-compaction batching.\n if (this._deletedIndices.length === 0) {\n return false;\n }\n this._flushCleanupDeleted();\n return this._deleteAtKey(value, key);\n }\n\n private _deleteAtKey(value: T, key: number): boolean {\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.blur();\n }\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', (e: CompositionEvent) => {\n if (this._compositionHelper instanceof CompositionHelper) {\n if (this._compositionHelper.compositionend(e)) {\n this.textarea!.dispatchEvent(new CustomEvent(\n 'xterm-composition-transaction-accepted',\n { bubbles: true }\n ));\n }\n } else {\n this._compositionHelper!.compositionend();\n }\n }));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._register(toDisposable(() => {\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.dispose();\n }\n }));\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n if (!this._compositionHelper!.keypress?.(key)) {\n this.coreService.triggerDataEvent(key, true);\n }\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n if (\n ev.data &&\n ev.inputType === 'insertText' &&\n !this.optionsService.rawOptions.screenReaderMode &&\n this._compositionHelper instanceof CompositionHelper &&\n this._compositionHelper.input(ev.data)\n ) {\n return true;\n }\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n"], -+ "mappings": "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,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM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", ++ "sourcesContent": ["/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// This file contains strings that get exported in the API so they can be localized\n\nlet promptLabelInternal = 'Terminal input';\nconst promptLabel = {\n get: () => promptLabelInternal,\n set: (value: string) => promptLabelInternal = value\n};\n\nlet tooMuchOutputInternal = 'Too much output to announce, navigate to rows manually to read';\nconst tooMuchOutput = {\n get: () => tooMuchOutputInternal,\n set: (value: string) => tooMuchOutputInternal = value\n};\n\nexport {\n promptLabel,\n tooMuchOutput\n};\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ISelectionService } from './services/Services';\nimport { ICoreService, IOptionsService } from '../common/services/Services';\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (!bracketedPasteMode) {\n return text;\n }\n // Sanitize pasted text to prevent injected escape sequences (e.g. exiting bracketed paste)\n // by replacing ESC (\\x1b) with its visible representation U+241B (\u241B).\n const sanitizedText = text.replace(/\\x1b/g, '\\u241b');\n return `\\x1b[200~${sanitizedText}\\x1b[201~`;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, selectionService: ISelectionService): void {\n if (ev.clipboardData) {\n ev.clipboardData.setData('text/plain', selectionService.selectionText);\n }\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n */\nexport function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n ev.stopPropagation();\n if (ev.clipboardData) {\n const text = ev.clipboardData.getData('text/plain');\n paste(text, textarea, coreService, optionsService);\n }\n}\n\nexport function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService, optionsService: IOptionsService): void {\n text = prepareTextForTerminal(text);\n text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode && optionsService.rawOptions.ignoreBracketedPasteMode !== true);\n coreService.triggerDataEvent(text, true);\n textarea.value = '';\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement): void {\n\n // Calculate textarea position relative to the screen element\n const pos = screenElement.getBoundingClientRect();\n const left = ev.clientX - pos.left - 10;\n const top = ev.clientY - pos.top - 10;\n\n // Bring textarea at the cursor position\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = `${left}px`;\n textarea.style.top = `${top}px`;\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, screenElement: HTMLElement, selectionService: ISelectionService, shouldSelectWord: boolean): void {\n moveTextAreaUnderMouseCursor(ev, textarea, screenElement);\n\n if (shouldSelectWord) {\n selectionService.rightClickSelect(ev);\n }\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionService.selectionText;\n textarea.select();\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Polyfill - Convert UTF32 codepoint into JS string.\n * Note: The built-in String.fromCodePoint happens to be much slower\n * due to additional sanity checks. We can avoid them since\n * we always operate on legal UTF32 (granted by the input decoders)\n * and use this faster version instead.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n if (codePoint > 0xFFFF) {\n codePoint -= 0x10000;\n return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n }\n return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n let result = '';\n for (let i = start; i < end; ++i) {\n let codepoint = data[i];\n if (codepoint > 0xFFFF) {\n // JS strings are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate\n // pair conversion rules:\n // - subtract 0x10000 from code point, leaving a 20 bit number\n // - add high 10 bits to 0xD800 --> first surrogate\n // - add low 10 bits to 0xDC00 --> second surrogate\n codepoint -= 0x10000;\n result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n } else {\n result += String.fromCharCode(codepoint);\n }\n }\n return result;\n}\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n private _interim: number = 0;\n\n /**\n * Clears interim and resets decoder to clean state.\n */\n public clear(): void {\n this._interim = 0;\n }\n\n /**\n * Decode JS string to UTF32 codepoints.\n * The methods assumes stream input and will store partly transmitted\n * surrogate pairs and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided input data does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: string, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let startPos = 0;\n\n // handle leftover surrogate high\n if (this._interim) {\n const second = input.charCodeAt(startPos++);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = this._interim;\n target[size++] = second;\n }\n this._interim = 0;\n }\n\n for (let i = startPos; i < length; ++i) {\n const code = input.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n this._interim = code;\n return size;\n }\n const second = input.charCodeAt(i);\n if (0xDC00 <= second && second <= 0xDFFF) {\n target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n // illegal codepoint (USC2 handling)\n target[size++] = code;\n target[size++] = second;\n }\n continue;\n }\n if (code === 0xFEFF) {\n // BOM\n continue;\n }\n target[size++] = code;\n }\n return size;\n }\n}\n\n/**\n * Utf8Decoder - decodes UTF8 byte sequences into UTF32 codepoints.\n */\nexport class Utf8ToUtf32 {\n public interim: Uint8Array = new Uint8Array(3);\n\n /**\n * Clears interim bytes and resets decoder to clean state.\n */\n public clear(): void {\n this.interim.fill(0);\n }\n\n /**\n * Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`.\n * The methods assumes stream input and will store partly transmitted bytes\n * and decode them with the next data chunk.\n * Note: The method does no bound checks for target, therefore make sure\n * the provided data chunk does not exceed the size of `target`.\n * Returns the number of written codepoints in `target`.\n */\n public decode(input: Uint8Array, target: Uint32Array): number {\n const length = input.length;\n\n if (!length) {\n return 0;\n }\n\n let size = 0;\n let byte1: number;\n let byte2: number;\n let byte3: number;\n let byte4: number;\n let codepoint;\n let startPos = 0;\n\n // handle leftover bytes\n if (this.interim[0]) {\n let discardInterim = false;\n let cp = this.interim[0];\n cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07);\n let pos = 0;\n let tmp: number;\n while ((tmp = this.interim[++pos]) && pos < 4) {\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n // missing bytes - read ahead from input\n const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4;\n const missing = type - pos;\n while (startPos < missing) {\n if (startPos >= length) {\n return 0;\n }\n tmp = input[startPos++];\n if ((tmp & 0xC0) !== 0x80) {\n // wrong continuation, discard interim bytes completely\n startPos--;\n discardInterim = true;\n break;\n } else {\n // need to save so we can continue short inputs in next call\n this.interim[pos++] = tmp;\n cp <<= 6;\n cp |= tmp & 0x3F;\n }\n }\n if (!discardInterim) {\n // final test is type dependent\n if (type === 2) {\n if (cp < 0x80) {\n // wrong starter byte\n startPos--;\n } else {\n target[size++] = cp;\n }\n } else if (type === 3) {\n if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) {\n // illegal codepoint or BOM\n } else {\n target[size++] = cp;\n }\n } else {\n if (cp < 0x010000 || cp > 0x10FFFF) {\n // illegal codepoint\n } else {\n target[size++] = cp;\n }\n }\n }\n this.interim.fill(0);\n }\n\n // loop through input\n const fourStop = length - 4;\n let i = startPos;\n while (i < length) {\n /**\n * ASCII shortcut with loop unrolled to 4 consecutive ASCII chars.\n * This is a compromise between speed gain for ASCII\n * and penalty for non ASCII:\n * For best ASCII performance the char should be stored directly into target,\n * but even a single attempt to write to target and compare afterwards\n * penalizes non ASCII really bad (-50%), thus we load the char into byteX first,\n * which reduces ASCII performance by ~15%.\n * This trial for ASCII reduces non ASCII performance by ~10% which seems acceptible\n * compared to the gains.\n * Note that this optimization only takes place for 4 consecutive ASCII chars,\n * for any shorter it bails out. Worst case - all 4 bytes being read but\n * thrown away due to the last being a non ASCII char (-10% performance).\n */\n while (i < fourStop\n && !((byte1 = input[i]) & 0x80)\n && !((byte2 = input[i + 1]) & 0x80)\n && !((byte3 = input[i + 2]) & 0x80)\n && !((byte4 = input[i + 3]) & 0x80))\n {\n target[size++] = byte1;\n target[size++] = byte2;\n target[size++] = byte3;\n target[size++] = byte4;\n i += 4;\n }\n\n // reread byte1\n byte1 = input[i++];\n\n // 1 byte\n if (byte1 < 0x80) {\n target[size++] = byte1;\n\n // 2 bytes\n } else if ((byte1 & 0xE0) === 0xC0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x1F) << 6 | (byte2 & 0x3F);\n if (codepoint < 0x80) {\n // wrong starter byte\n i--;\n continue;\n }\n target[size++] = codepoint;\n\n // 3 bytes\n } else if ((byte1 & 0xF0) === 0xE0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F);\n if (codepoint < 0x0800 || (codepoint >= 0xD800 && codepoint <= 0xDFFF) || codepoint === 0xFEFF) {\n // illegal codepoint or BOM, no i-- here\n continue;\n }\n target[size++] = codepoint;\n\n // 4 bytes\n } else if ((byte1 & 0xF8) === 0xF0) {\n if (i >= length) {\n this.interim[0] = byte1;\n return size;\n }\n byte2 = input[i++];\n if ((byte2 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n return size;\n }\n byte3 = input[i++];\n if ((byte3 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n if (i >= length) {\n this.interim[0] = byte1;\n this.interim[1] = byte2;\n this.interim[2] = byte3;\n return size;\n }\n byte4 = input[i++];\n if ((byte4 & 0xC0) !== 0x80) {\n // wrong continuation\n i--;\n continue;\n }\n codepoint = (byte1 & 0x07) << 18 | (byte2 & 0x3F) << 12 | (byte3 & 0x3F) << 6 | (byte4 & 0x3F);\n if (codepoint < 0x010000 || codepoint > 0x10FFFF) {\n // illegal codepoint, no i-- here\n continue;\n }\n target[size++] = codepoint;\n } else {\n // illegal byte, just skip\n }\n }\n return size;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorRGB } from '../Types';\nimport { IAttributeData, IExtendedAttrs } from './Types';\nimport { Attributes, FgFlags, BgFlags, UnderlineStyle, ExtFlags } from './Constants';\n\nexport class AttributeData implements IAttributeData {\n public static toColorRGB(value: number): IColorRGB {\n return [\n value >>> Attributes.RED_SHIFT & 255,\n value >>> Attributes.GREEN_SHIFT & 255,\n value & 255\n ];\n }\n\n public static fromColorRGB(value: IColorRGB): number {\n return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n }\n\n public clone(): IAttributeData {\n const newObj = new AttributeData();\n newObj.fg = this.fg;\n newObj.bg = this.bg;\n newObj.extended = this.extended.clone();\n return newObj;\n }\n\n // data\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n\n // flags\n public isInverse(): number { return this.fg & FgFlags.INVERSE; }\n public isBold(): number { return this.fg & FgFlags.BOLD; }\n public isUnderline(): number {\n if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {\n return 1;\n }\n return this.fg & FgFlags.UNDERLINE;\n }\n public isBlink(): number { return this.fg & FgFlags.BLINK; }\n public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n public isItalic(): number { return this.bg & BgFlags.ITALIC; }\n public isDim(): number { return this.bg & BgFlags.DIM; }\n public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }\n public isProtected(): number { return this.bg & BgFlags.PROTECTED; }\n public isOverline(): number { return this.bg & BgFlags.OVERLINE; }\n\n // color modes\n public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }\n public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }\n public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }\n\n // colors\n public getFgColor(): number {\n switch (this.fg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.fg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.fg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n public getBgColor(): number {\n switch (this.bg & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.bg & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.bg & Attributes.RGB_MASK;\n default: return -1; // CM_DEFAULT defaults to -1\n }\n }\n\n // extended attrs\n public hasExtendedAttrs(): number {\n return this.bg & BgFlags.HAS_EXTENDED;\n }\n public updateExtended(): void {\n if (this.extended.isEmpty()) {\n this.bg &= ~BgFlags.HAS_EXTENDED;\n } else {\n this.bg |= BgFlags.HAS_EXTENDED;\n }\n }\n public getUnderlineColor(): number {\n if ((this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor) {\n switch (this.extended.underlineColor & Attributes.CM_MASK) {\n case Attributes.CM_P16:\n case Attributes.CM_P256: return this.extended.underlineColor & Attributes.PCOLOR_MASK;\n case Attributes.CM_RGB: return this.extended.underlineColor & Attributes.RGB_MASK;\n default: return this.getFgColor();\n }\n }\n return this.getFgColor();\n }\n public getUnderlineColorMode(): number {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? this.extended.underlineColor & Attributes.CM_MASK\n : this.getFgColorMode();\n }\n public isUnderlineColorRGB(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_RGB\n : this.isFgRGB();\n }\n public isUnderlineColorPalette(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P16\n || (this.extended.underlineColor & Attributes.CM_MASK) === Attributes.CM_P256\n : this.isFgPalette();\n }\n public isUnderlineColorDefault(): boolean {\n return (this.bg & BgFlags.HAS_EXTENDED) && ~this.extended.underlineColor\n ? (this.extended.underlineColor & Attributes.CM_MASK) === 0\n : this.isFgDefault();\n }\n public getUnderlineStyle(): UnderlineStyle {\n return this.fg & FgFlags.UNDERLINE\n ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE)\n : UnderlineStyle.NONE;\n }\n public getUnderlineVariantOffset(): number {\n return this.extended.underlineVariantOffset;\n }\n}\n\n\n/**\n * Extended attributes for a cell.\n * Holds information about different underline styles and color.\n */\nexport class ExtendedAttrs implements IExtendedAttrs {\n private _ext: number = 0;\n public get ext(): number {\n if (this._urlId) {\n return (\n (this._ext & ~ExtFlags.UNDERLINE_STYLE) |\n (this.underlineStyle << 26)\n );\n }\n return this._ext;\n }\n public set ext(value: number) { this._ext = value; }\n\n public get underlineStyle(): UnderlineStyle {\n // Always return the URL style if it has one\n if (this._urlId) {\n return UnderlineStyle.DASHED;\n }\n return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;\n }\n public set underlineStyle(value: UnderlineStyle) {\n this._ext &= ~ExtFlags.UNDERLINE_STYLE;\n this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;\n }\n\n public get underlineColor(): number {\n return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n public set underlineColor(value: number) {\n this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);\n }\n\n private _urlId: number = 0;\n public get urlId(): number {\n return this._urlId;\n }\n public set urlId(value: number) {\n this._urlId = value;\n }\n\n public get underlineVariantOffset(): number {\n const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;\n if (val < 0) {\n return val ^ 0xFFFFFFF8;\n }\n return val;\n }\n public set underlineVariantOffset(value: number) {\n this._ext &= ~ExtFlags.VARIANT_OFFSET;\n this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;\n }\n\n constructor(\n ext: number = 0,\n urlId: number = 0\n ) {\n this._ext = ext;\n this._urlId = urlId;\n }\n\n public clone(): IExtendedAttrs {\n return new ExtendedAttrs(this._ext, this._urlId);\n }\n\n /**\n * Convenient method to indicate whether the object holds no additional information,\n * that needs to be persistant in the buffer.\n */\n public isEmpty(): boolean {\n return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, ICellData, IExtendedAttrs } from './Types';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from './Constants';\nimport { AttributeData, ExtendedAttrs } from './AttributeData';\nimport type { IBufferCell as IBufferCellApi } from '@xterm/xterm';\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n /** Helper to create CellData from CharData. */\n public static fromCharData(value: CharData): CellData {\n const obj = new CellData();\n obj.setFromCharData(value);\n return obj;\n }\n /** Primitives from terminal buffer. */\n public content = 0;\n public fg = 0;\n public bg = 0;\n public extended: IExtendedAttrs = new ExtendedAttrs();\n public combinedData = '';\n /** Whether cell contains a combined string. */\n public isCombined(): number {\n return this.content & Content.IS_COMBINED_MASK;\n }\n /** Width of the cell. */\n public getWidth(): number {\n return this.content >> Content.WIDTH_SHIFT;\n }\n /** JS string of the content. */\n public getChars(): string {\n if (this.content & Content.IS_COMBINED_MASK) {\n return this.combinedData;\n }\n if (this.content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n }\n return '';\n }\n /**\n * Codepoint of cell\n * Note this returns the UTF32 codepoint of single chars,\n * if content is a combined string it returns the codepoint\n * of the last char in string to be in line with code in CharData.\n */\n public getCode(): number {\n return (this.isCombined())\n ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n : this.content & Content.CODEPOINT_MASK;\n }\n /** Set data from CharData */\n public setFromCharData(value: CharData): void {\n this.fg = value[CHAR_DATA_ATTR_INDEX];\n this.bg = 0;\n let combined = false;\n // surrogates and combined strings need special treatment\n if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n combined = true;\n }\n else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n // if the 2-char string is a surrogate create single codepoint\n // everything else is combined\n if (0xD800 <= code && code <= 0xDBFF) {\n const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n if (0xDC00 <= second && second <= 0xDFFF) {\n this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n else {\n combined = true;\n }\n }\n else {\n combined = true;\n }\n }\n else {\n this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n if (combined) {\n this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n /** Get data as CharData. */\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n\n public attributesEquals(other: IBufferCellApi): boolean {\n if (this.getFgColorMode() !== other.getFgColorMode() || this.getFgColor() !== other.getFgColor()) {\n return false;\n }\n if (this.getBgColorMode() !== other.getBgColorMode() || this.getBgColor() !== other.getBgColor()) {\n return false;\n }\n if (this.isInverse() !== other.isInverse()) {\n return false;\n }\n if (this.isBold() !== other.isBold()) {\n return false;\n }\n if (this.isUnderline() !== other.isUnderline()) {\n return false;\n }\n if (this.isUnderline()) {\n if (this.getUnderlineStyle() !== other.getUnderlineStyle()) {\n return false;\n }\n const thisDefault = this.isUnderlineColorDefault();\n const otherDefault = other.isUnderlineColorDefault();\n if (!(thisDefault && otherDefault)) {\n if (thisDefault !== otherDefault) {\n return false;\n }\n if (this.getUnderlineColor() !== other.getUnderlineColor()) {\n return false;\n }\n if (this.getUnderlineColorMode() !== other.getUnderlineColorMode()) {\n return false;\n }\n }\n }\n if (this.isOverline() !== other.isOverline()) {\n return false;\n }\n if (this.isBlink() !== other.isBlink()) {\n return false;\n }\n if (this.isInvisible() !== other.isInvisible()) {\n return false;\n }\n if (this.isItalic() !== other.isItalic()) {\n return false;\n }\n if (this.isDim() !== other.isDim()) {\n return false;\n }\n if (this.isStrikethrough() !== other.isStrikethrough()) {\n return false;\n }\n return true;\n }\n\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport interface IServiceIdentifier {\n (...args: any[]): void;\n type: T;\n _id: string;\n}\n\nconst enum Constants {\n DI_TARGET = 'di$target',\n DI_DEPENDENCIES = 'di$dependencies'\n}\n\nexport const serviceRegistry: Map> = new Map();\n\nexport function getServiceDependencies(ctor: any): { id: IServiceIdentifier, index: number, optional: boolean }[] {\n return ctor[Constants.DI_DEPENDENCIES] || [];\n}\n\nexport function createDecorator(id: string): IServiceIdentifier {\n if (serviceRegistry.has(id)) {\n return serviceRegistry.get(id)!;\n }\n\n const decorator: any = function (target: Function, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n\n storeServiceDependency(decorator, target, index);\n };\n\n decorator._id = id;\n\n serviceRegistry.set(id, decorator);\n return decorator;\n}\n\nfunction storeServiceDependency(id: Function, target: Function, index: number): void {\n if ((target as any)[Constants.DI_TARGET] === target) {\n (target as any)[Constants.DI_DEPENDENCIES].push({ id, index });\n } else {\n (target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];\n (target as any)[Constants.DI_TARGET] = target;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IDecoration, IDecorationOptions, ILinkHandler, ILogger, IWindowsPty, IOverviewRulerOptions } from '@xterm/xterm';\nimport { CoreMouseEncoding, CoreMouseEventType, CursorInactiveStyle, CursorStyle, ICharset, IColor, ICoreMouseEvent, ICoreMouseProtocol, IDecPrivateModes, IDisposable, IKittyKeyboardState, IModes, IOscLinkData, IWindowOptions } from '../Types';\nimport { IAttributeData, IBuffer, IBufferSet } from '../buffer/Types';\nimport { createDecorator, IServiceIdentifier } from './ServiceRegistry';\nimport type { Emitter, IEvent } from '../Event';\n\nexport const IBufferService = createDecorator('BufferService');\nexport interface IBufferService {\n serviceBrand: undefined;\n\n readonly cols: number;\n readonly rows: number;\n readonly buffer: IBuffer;\n readonly buffers: IBufferSet;\n isUserScrolling: boolean;\n onResize: IEvent;\n onScroll: IEvent;\n scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;\n scrollLines(disp: number, suppressScrollEvent?: boolean): void;\n resize(cols: number, rows: number): void;\n reset(): void;\n}\n\nexport interface IBufferResizeEvent {\n cols: number;\n rows: number;\n colsChanged: boolean;\n rowsChanged: boolean;\n}\n\nexport const IMouseStateService = createDecorator('MouseStateService');\nexport interface IMouseStateService {\n serviceBrand: undefined;\n\n activeProtocol: string;\n activeEncoding: string;\n areMouseEventsActive: boolean;\n addProtocol(name: string, protocol: ICoreMouseProtocol): void;\n addEncoding(name: string, encoding: CoreMouseEncoding): void;\n reset(): void;\n setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void;\n allowCustomWheelEvent(ev: WheelEvent): boolean;\n\n /**\n * Event to announce changes in mouse tracking.\n */\n onProtocolChange: IEvent;\n restrictMouseEvent(event: ICoreMouseEvent): boolean;\n encodeMouseEvent(event: ICoreMouseEvent): string;\n readonly isDefaultEncoding: boolean;\n readonly isPixelEncoding: boolean;\n}\n\nexport const ICoreService = createDecorator('CoreService');\nexport interface ICoreService {\n serviceBrand: undefined;\n\n /**\n * Initially the cursor will not be visible until the first time the terminal\n * is focused.\n */\n isCursorInitialized: boolean;\n isCursorHidden: boolean;\n\n readonly modes: IModes;\n readonly decPrivateModes: IDecPrivateModes;\n readonly kittyKeyboard: IKittyKeyboardState;\n\n readonly onData: IEvent;\n readonly onUserInput: IEvent;\n readonly onBinary: IEvent;\n readonly onRequestScrollToBottom: IEvent;\n\n reset(): void;\n\n /**\n * Triggers the onData event in the public API.\n * @param data The data that is being emitted.\n * @param wasUserInput Whether the data originated from the user (as opposed to\n * resulting from parsing incoming data). When true this will also:\n * - Scroll to the bottom of the buffer if option scrollOnUserInput is true.\n * - Fire the `onUserInput` event (so selection can be cleared).\n */\n triggerDataEvent(data: string, wasUserInput?: boolean): void;\n\n /**\n * Triggers the onBinary event in the public API.\n * @param data The data that is being emitted.\n */\n triggerBinaryEvent(data: string): void;\n}\n\nexport const ICharsetService = createDecorator('CharsetService');\nexport interface ICharsetService {\n serviceBrand: undefined;\n\n charset: ICharset | undefined;\n readonly glevel: number;\n readonly charsets: (ICharset | undefined)[];\n\n reset(): void;\n\n /**\n * Set the G level of the terminal.\n * @param g\n */\n setgLevel(g: number): void;\n\n /**\n * Set the charset for the given G level of the terminal.\n * @param g\n * @param charset\n */\n setgCharset(g: number, charset: ICharset | undefined): void;\n}\n\nexport interface IBrandedService {\n serviceBrand: undefined;\n}\n\ntype GetLeadingNonServiceArgs = TArgs extends [] ? []\n : TArgs extends [...infer TFirst, infer TLast] ? TLast extends IBrandedService ? GetLeadingNonServiceArgs : TArgs\n : never;\n\nexport const IInstantiationService = createDecorator('InstantiationService');\nexport interface IInstantiationService {\n serviceBrand: undefined;\n\n setService(id: IServiceIdentifier, instance: T): void;\n getService(id: IServiceIdentifier): T | undefined;\n createInstance any, R extends InstanceType>(t: Ctor, ...args: GetLeadingNonServiceArgs>): R;\n}\n\nexport enum LogLevelEnum {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n OFF = 5\n}\n\nexport const ILogService = createDecorator('LogService');\nexport interface ILogService {\n serviceBrand: undefined;\n\n readonly logLevel: LogLevelEnum;\n\n trace(message: any, ...optionalParams: any[]): void;\n debug(message: any, ...optionalParams: any[]): void;\n info(message: any, ...optionalParams: any[]): void;\n warn(message: any, ...optionalParams: any[]): void;\n error(message: any, ...optionalParams: any[]): void;\n}\n\nexport const IOptionsService = createDecorator('OptionsService');\nexport interface IOptionsService {\n serviceBrand: undefined;\n\n /**\n * Read only access to the raw options object, this is an internal-only fast path for accessing\n * single options without any validation as we trust TypeScript to enforce correct usage\n * internally.\n */\n readonly rawOptions: Required;\n\n /**\n * Options as exposed through the public API, this property uses getters and setters with\n * validation which makes it safer but slower. {@link rawOptions} should be used for pretty much\n * all internal usage for performance reasons.\n */\n readonly options: Required;\n\n /**\n * Adds an event listener for when any option changes.\n */\n readonly onOptionChange: IEvent;\n\n /**\n * Adds an event listener for when a specific option changes, this is a convenience method that is\n * preferred over {@link onOptionChange} when only a single option is being listened to.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable;\n\n /**\n * Adds an event listener for when a set of specific options change, this is a convenience method\n * that is preferred over {@link onOptionChange} when multiple options are being listened to and\n * handled the same way.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable;\n}\n\nexport type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport interface ITerminalOptions {\n allowProposedApi?: boolean;\n allowTransparency?: boolean;\n altClickMovesCursor?: boolean;\n cols?: number;\n convertEol?: boolean;\n cursorBlink?: boolean;\n blinkIntervalDuration?: number;\n cursorStyle?: CursorStyle;\n cursorWidth?: number;\n cursorInactiveStyle?: CursorInactiveStyle;\n disableStdin?: boolean;\n documentOverride?: any | null;\n drawBoldTextInBrightColors?: boolean;\n fastScrollSensitivity?: number;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: FontWeight;\n fontWeightBold?: FontWeight;\n ignoreBracketedPasteMode?: boolean;\n letterSpacing?: number;\n lineHeight?: number;\n linkHandler?: ILinkHandler | null;\n logLevel?: LogLevel;\n logger?: ILogger | null;\n macOptionIsMeta?: boolean;\n macOptionClickForcesSelection?: boolean;\n minimumContrastRatio?: number;\n mouseEventsRequireAlt?: boolean;\n reflowCursorLine?: boolean;\n rescaleOverlappingGlyphs?: boolean;\n rightClickSelectsWord?: boolean;\n rows?: number;\n showCursorImmediately?: boolean;\n screenReaderMode?: boolean;\n scrollback?: number;\n scrollOnUserInput?: boolean;\n scrollSensitivity?: number;\n smoothScrollDuration?: number;\n tabStopWidth?: number;\n theme?: ITheme;\n windowsPty?: IWindowsPty;\n windowOptions?: IWindowOptions;\n wordSeparator?: string;\n quirks?: ITerminalQuirks;\n scrollbar?: IScrollbarOptions;\n scrollOnEraseInDisplay?: boolean;\n vtExtensions?: IVtExtensions;\n\n [key: string]: any;\n termName: string;\n}\n\nexport interface ITheme {\n foreground?: string;\n background?: string;\n cursor?: string;\n cursorAccent?: string;\n selectionForeground?: string;\n selectionBackground?: string;\n selectionInactiveBackground?: string;\n scrollbarSliderBackground?: string;\n scrollbarSliderHoverBackground?: string;\n scrollbarSliderActiveBackground?: string;\n overviewRulerBorder?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n extendedAnsi?: string[];\n}\n\nexport interface ITerminalQuirks {\n allowSetCursorBlink?: boolean;\n}\n\nexport interface IScrollbarOptions {\n showScrollbar?: boolean;\n showArrows?: boolean;\n width?: number;\n overviewRuler?: IOverviewRulerOptions;\n}\n\nexport interface IVtExtensions {\n kittyKeyboard?: boolean;\n kittySgrBoldFaintControl?: boolean;\n win32InputMode?: boolean;\n colorSchemeQuery?: boolean;\n}\n\nexport const IOscLinkService = createDecorator('OscLinkService');\nexport interface IOscLinkService {\n serviceBrand: undefined;\n /**\n * Registers a link to the service, returning the link ID. The link data is managed by this\n * service and will be freed when this current cursor position is trimmed off the buffer.\n */\n registerLink(linkData: IOscLinkData): number;\n /**\n * Adds a line to a link if needed.\n */\n addLineToLink(linkId: number, y: number): void;\n /** Get the link data associated with a link ID. */\n getLinkData(linkId: number): IOscLinkData | undefined;\n}\n\n/*\n * Width and Grapheme_Cluster_Break properties of a character as a bit mask.\n *\n * bit 0: shouldJoin - should combine with preceding character.\n * bit 1..2: wcwidth - see UnicodeCharWidth.\n * bit 3..31: class of character (currently only 4 bits are used).\n * This is used to determined grapheme clustering - i.e. which codepoints\n * are to be combined into a single compound character.\n *\n * Use the UnicodeService static function createPropertyValue to create a\n * UnicodeCharProperties; use extractShouldJoin, extractWidth, and\n * extractCharKind to extract the components.\n */\nexport type UnicodeCharProperties = number;\n\n/**\n * Width in columns of a character.\n * In a CJK context, \"half-width\" characters (such as Latin) are width 1,\n * while \"full-width\" characters (such as Kanji) are 2 columns wide.\n * Combining characters (such as accents) are width 0.\n */\nexport type UnicodeCharWidth = 0 | 1 | 2;\n\nexport const IUnicodeService = createDecorator('UnicodeService');\nexport interface IUnicodeService {\n serviceBrand: undefined;\n /** Register a Unicode version provider. */\n register(provider: IUnicodeVersionProvider): void;\n /** Registered Unicode versions. */\n readonly versions: string[];\n /** Currently active version. */\n activeVersion: string;\n /** Event triggered when the active version changes. */\n readonly onChange: IEvent;\n\n /**\n * Unicode version dependent\n */\n wcwidth(codepoint: number): UnicodeCharWidth;\n getStringCellWidth(s: string): number;\n /**\n * Return character width and type for grapheme clustering.\n * If preceding != 0, it is the return code from the previous character;\n * in that case the result specifies if the characters should be joined.\n */\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport interface IUnicodeVersionProvider {\n readonly version: string;\n wcwidth(ucs: number): UnicodeCharWidth;\n charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties;\n}\n\nexport const IDecorationService = createDecorator('DecorationService');\nexport interface IDecorationService extends IDisposable {\n serviceBrand: undefined;\n readonly decorations: IterableIterator;\n readonly onDecorationRegistered: IEvent;\n readonly onDecorationRemoved: IEvent;\n registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;\n reset(): void;\n /**\n * Trigger a callback over the decoration at a cell (in no particular order). This uses a callback\n * instead of an iterator as it's typically used in hot code paths.\n */\n forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;\n}\nexport interface IInternalDecoration extends IDecoration {\n readonly options: IDecorationOptions;\n readonly backgroundColorRGB: IColor | undefined;\n readonly foregroundColorRGB: IColor | undefined;\n readonly onRenderEmitter: Emitter;\n /** @internal Start line for line-index removal; kept in sync on buffer line shifts. */\n _indexedStartLine: number;\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILink } from './Types';\nimport { ILinkProvider } from './services/Services';\nimport { CellData } from '../common/buffer/CellData';\nimport { IBufferLine } from '../common/buffer/Types';\nimport { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';\n\nexport class OscLinkProvider implements ILinkProvider {\n private readonly _workCell = new CellData();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IOscLinkService private readonly _oscLinkService: IOscLinkService\n ) {\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n const line = this._bufferService.buffer.lines.get(y - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const result: ILink[] = [];\n const linkHandler = this._optionsService.rawOptions.linkHandler;\n const cell = this._workCell;\n const lineLength = line.getTrimmedLength();\n let currentLinkId = -1;\n let currentStart = -1;\n let finishLink = false;\n for (let x = 0; x < lineLength; x++) {\n // Minor optimization, only check for content if there isn't a link in case the link ends with\n // a null cell\n if (currentStart === -1 && !line.hasContent(x)) {\n continue;\n }\n\n line.loadCell(x, cell);\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n if (currentStart === -1) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n continue;\n } else {\n finishLink = cell.extended.urlId !== currentLinkId;\n }\n } else {\n if (currentStart !== -1) {\n finishLink = true;\n }\n }\n\n if (finishLink || (currentStart !== -1 && x === lineLength - 1)) {\n const text = this._oscLinkService.getLinkData(currentLinkId)?.uri;\n if (text) {\n const endX = x + (!finishLink && x === lineLength - 1 ? 1 : 0);\n const range = this._getRangeWithLineWrap(y, currentStart, endX, currentLinkId);\n let ignoreLink = false;\n if (!linkHandler?.allowNonHttpProtocols) {\n try {\n const parsed = new URL(text);\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n ignoreLink = true;\n }\n } catch {\n // Ignore invalid URLs to prevent unexpected behaviors\n ignoreLink = true;\n }\n }\n\n if (!ignoreLink) {\n // OSC links always use underline and pointer decorations\n result.push({\n text,\n range,\n activate: (e, text) => (linkHandler ? linkHandler.activate(e, text, range) : defaultActivate(e, text)),\n hover: (e, text) => linkHandler?.hover?.(e, text, range),\n leave: (e, text) => linkHandler?.leave?.(e, text, range)\n });\n }\n }\n finishLink = false;\n\n // Clear link or start a new link if one starts immediately\n if (cell.hasExtendedAttrs() && cell.extended.urlId) {\n currentStart = x;\n currentLinkId = cell.extended.urlId;\n } else {\n currentStart = -1;\n currentLinkId = -1;\n }\n }\n }\n\n // TODO: Handle fetching and returning other link ranges to underline other links with the same\n // id\n callback(result);\n }\n\n /**\n * Expand a single-line OSC 8 range to a contiguous wrapped range for the same link id.\n */\n private _getRangeWithLineWrap(y: number, startX: number, endX: number, linkId: number): IBufferRange {\n let startY = y;\n let finalStartX = startX;\n let endY = y;\n let finalEndX = endX;\n\n // Expand upward only when this segment starts at column 0 and the current line is wrapped.\n while (finalStartX === 0) {\n const currentLine = this._bufferService.buffer.lines.get(startY - 1);\n if (!currentLine?.isWrapped) {\n break;\n }\n const previousLine = this._bufferService.buffer.lines.get(startY - 2);\n if (!previousLine) {\n break;\n }\n const previousLineLength = previousLine.getTrimmedLength();\n if (previousLineLength === 0 || !this._hasUrlId(previousLine, previousLineLength - 1, linkId)) {\n break;\n }\n let previousStartX = previousLineLength - 1;\n while (previousStartX > 0 && this._hasUrlId(previousLine, previousStartX - 1, linkId)) {\n previousStartX--;\n }\n startY--;\n finalStartX = previousStartX;\n }\n\n // Expand downward only when this segment reaches trimmed EOL and the next line is wrapped.\n while (true) {\n const currentLine = this._bufferService.buffer.lines.get(endY - 1);\n if (!currentLine) {\n break;\n }\n const currentLineLength = currentLine.getTrimmedLength();\n if (finalEndX !== currentLineLength) {\n break;\n }\n const nextLine = this._bufferService.buffer.lines.get(endY);\n if (!nextLine?.isWrapped) {\n break;\n }\n const nextLineLength = nextLine.getTrimmedLength();\n if (nextLineLength === 0 || !this._hasUrlId(nextLine, 0, linkId)) {\n break;\n }\n let nextEndX = 1;\n while (nextEndX < nextLineLength && this._hasUrlId(nextLine, nextEndX, linkId)) {\n nextEndX++;\n }\n endY++;\n finalEndX = nextEndX;\n }\n\n // IBufferRange uses 1-based coordinates.\n return {\n start: {\n x: finalStartX + 1,\n y: startY\n },\n end: {\n x: finalEndX,\n y: endY\n }\n };\n }\n\n private _hasUrlId(line: IBufferLine, x: number, linkId: number): boolean {\n const cell = this._workCell;\n line.loadCell(x, cell);\n return !!cell.hasExtendedAttrs() && cell.extended.urlId === linkId;\n }\n}\n\nfunction defaultActivate(e: MouseEvent, uri: string): void {\n const answer = confirm(`Do you want to navigate to ${uri}?\\n\\nWARNING: This link could potentially be dangerous`);\n if (answer) {\n const newWindow = window.open();\n if (newWindow) {\n try {\n newWindow.opener = null;\n } catch {\n // no-op, Electron can throw\n }\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { IColorSet, ILink, ReadonlyColorSet } from '../Types';\nimport { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { createDecorator } from '../../common/services/ServiceRegistry';\nimport { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';\nimport type { IEvent } from '../../common/Event';\n\nexport const ICharSizeService = createDecorator('CharSizeService');\nexport interface ICharSizeService {\n serviceBrand: undefined;\n\n readonly width: number;\n readonly height: number;\n readonly hasValidSize: boolean;\n\n readonly onCharSizeChange: IEvent;\n\n measure(): void;\n}\n\nexport const ICoreBrowserService = createDecorator('CoreBrowserService');\nexport interface ICoreBrowserService {\n serviceBrand: undefined;\n\n readonly isFocused: boolean;\n\n readonly onDprChange: IEvent;\n readonly onWindowChange: IEvent;\n\n /**\n * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.\n * requestAnimationFrame) should be invoked in the context of this window. This should be set when\n * the window hosting the xterm.js instance changes.\n */\n window: Window & typeof globalThis;\n /**\n * The document of the primary window to be used to create elements when working with multiple\n * windows. This is defined by the documentOverride setting.\n */\n readonly mainDocument: Document;\n /**\n * Helper for getting the devicePixelRatio of the parent window.\n */\n readonly dpr: number;\n}\n\nexport const IMouseCoordsService = createDecorator('MouseCoordsService');\nexport interface IMouseCoordsService {\n serviceBrand: undefined;\n\n getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;\n getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;\n}\n\nexport const IMouseService = createDecorator('MouseService');\nexport interface IMouseService {\n serviceBrand: undefined;\n\n bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;\n reset(): void;\n}\nexport interface IMouseServiceTarget {\n element: HTMLElement;\n screenElement: HTMLElement;\n document: Document;\n handleTouchScroll?(amount: number): void;\n}\n\nexport const IRenderService = createDecorator('RenderService');\nexport interface IRenderService extends IDisposable {\n serviceBrand: undefined;\n\n onDimensionsChange: IEvent;\n /**\n * Fires when buffer changes are rendered. This does not fire when only cursor\n * or selections are rendered.\n */\n onRenderedViewportChange: IEvent<{ start: number, end: number }>;\n /**\n * Fires on render\n */\n onRender: IEvent<{ start: number, end: number }>;\n onRefreshRequest: IEvent<{ start: number, end: number }>;\n\n dimensions: IRenderDimensions;\n\n addRefreshCallback(callback: FrameRequestCallback): number;\n\n refreshRows(start: number, end: number, sync?: boolean): void;\n clearTextureAtlas(): void;\n resize(cols: number, rows: number): void;\n hasRenderer(): boolean;\n setRenderer(renderer: IRenderer): void;\n handleDevicePixelRatioChange(): void;\n handleResize(cols: number, rows: number): void;\n handleCharSizeChanged(): void;\n handleBlur(): void;\n handleFocus(): void;\n handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;\n handleCursorMove(): void;\n clear(): void;\n}\n\nexport const ISelectionService = createDecorator('SelectionService');\nexport interface ISelectionService {\n serviceBrand: undefined;\n\n readonly selectionText: string;\n readonly hasSelection: boolean;\n readonly selectionStart: [number, number] | undefined;\n readonly selectionEnd: [number, number] | undefined;\n\n readonly onLinuxMouseSelection: IEvent;\n readonly onRequestRedraw: IEvent;\n readonly onRequestScrollLines: IEvent;\n readonly onSelectionChange: IEvent;\n\n disable(): void;\n enable(): void;\n reset(): void;\n setSelection(row: number, col: number, length: number): void;\n selectAll(): void;\n selectLines(start: number, end: number): void;\n clearSelection(): void;\n rightClickSelect(event: MouseEvent): void;\n shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean;\n shouldForceSelection(event: MouseEvent): boolean;\n refresh(isLinuxMouseSelection?: boolean): void;\n handleMouseDown(event: MouseEvent): void;\n isCellInSelection(x: number, y: number): boolean;\n}\n\nexport const ICharacterJoinerService = createDecorator('CharacterJoinerService');\nexport interface ICharacterJoinerService {\n serviceBrand: undefined;\n\n register(handler: (text: string) => [number, number][]): number;\n deregister(joinerId: number): boolean;\n getJoinedCharacters(row: number): [number, number][];\n}\n\nexport const IThemeService = createDecorator('ThemeService');\nexport interface IThemeService {\n serviceBrand: undefined;\n\n readonly colors: ReadonlyColorSet;\n\n readonly onChangeColors: IEvent;\n\n restoreColor(slot?: AllColorIndex): void;\n /**\n * Allows external modifying of colors in the theme, this is used instead of {@link colors} to\n * prevent accidental writes.\n */\n modifyColors(callback: (colors: IColorSet) => void): void;\n}\n\n\nexport const ILinkProviderService = createDecorator('LinkProviderService');\nexport interface ILinkProviderService extends IDisposable {\n serviceBrand: undefined;\n readonly linkProviders: ReadonlyArray;\n registerLinkProvider(linkProvider: ILinkProvider): IDisposable;\n}\nexport interface ILinkProvider {\n provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;\n}\n\nexport const IKeyboardService = createDecorator('KeyboardService');\nexport interface IKeyboardService {\n serviceBrand: undefined;\n evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;\n evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;\n readonly useKitty: boolean;\n readonly useWin32InputMode: boolean;\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose(disposable: T): T;\nexport function dispose(disposable: T | undefined): T | undefined;\nexport function dispose(disposables: T[]): T[];\nexport function dispose(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal DOM helpers for xterm.js browser code.\n */\n\nimport { IntervalTimer } from '../common/Async';\nimport { IDisposable } from '../common/Lifecycle';\n\nexport function getWindow(e: Node | UIEvent | undefined | null): Window {\n const candidateNode = e as Node | undefined | null;\n if (candidateNode?.ownerDocument?.defaultView) {\n return candidateNode.ownerDocument.defaultView;\n }\n\n const candidateEvent = e as UIEvent | undefined | null;\n if (candidateEvent?.view) {\n return candidateEvent.view;\n }\n\n return window;\n}\n\nclass DomListener implements IDisposable {\n private _handler: ((e: any) => void) | null;\n private _node: EventTarget | null;\n private readonly _type: string;\n private readonly _options: boolean | AddEventListenerOptions | undefined;\n\n constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) {\n this._node = node;\n this._type = type;\n this._handler = handler;\n this._options = options;\n node.addEventListener(type, handler, options);\n }\n\n public dispose(): void {\n if (!this._node || !this._handler) {\n return;\n }\n this._node.removeEventListener(this._type, this._handler, this._options);\n this._node = null;\n this._handler = null;\n }\n}\n\nexport function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable;\nexport function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable {\n return new DomListener(node, type, handler, useCaptureOrOptions);\n}\n\nexport function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable {\n return addDisposableListener(node, type, handler, useCapture);\n}\n\nexport const eventType = {\n CLICK: 'click',\n MOUSE_DOWN: 'mousedown',\n MOUSE_OVER: 'mouseover',\n MOUSE_LEAVE: 'mouseleave',\n KEY_DOWN: 'keydown',\n KEY_UP: 'keyup',\n INPUT: 'input',\n BLUR: 'blur',\n FOCUS: 'focus',\n CHANGE: 'change',\n POINTER_DOWN: 'pointerdown',\n POINTER_MOVE: 'pointermove',\n POINTER_UP: 'pointerup',\n MOUSE_WHEEL: 'wheel',\n WHEEL: 'wheel'\n} as const;\n\nexport function getDomNodePagePosition(domNode: HTMLElement): { left: number, top: number, width: number, height: number } {\n const bb = domNode.getBoundingClientRect();\n const win = getWindow(domNode);\n return {\n left: bb.left + win.scrollX,\n top: bb.top + win.scrollY,\n width: bb.width,\n height: bb.height\n };\n}\n\nclass AnimationFrameQueueItem implements IDisposable {\n private _canceled = false;\n\n constructor(private readonly _runner: () => void, public priority: number) {\n }\n\n public dispose(): void {\n this._canceled = true;\n }\n\n public execute(): void {\n if (this._canceled) {\n return;\n }\n try {\n this._runner();\n } catch (e) {\n console.error(e);\n }\n }\n\n public static sort(a: AnimationFrameQueueItem, b: AnimationFrameQueueItem): number {\n return b.priority - a.priority;\n }\n}\n\ninterface IWindowAnimationFrameState {\n next: AnimationFrameQueueItem[];\n current: AnimationFrameQueueItem[];\n animFrameRequested: boolean;\n inAnimationFrameRunner: boolean;\n}\n\nconst animationFrameState = new Map();\n\nfunction getAnimationFrameState(targetWindow: Window): IWindowAnimationFrameState {\n let state = animationFrameState.get(targetWindow);\n if (!state) {\n state = {\n next: [],\n current: [],\n animFrameRequested: false,\n inAnimationFrameRunner: false\n };\n animationFrameState.set(targetWindow, state);\n }\n return state;\n}\n\nfunction animationFrameRunner(targetWindow: Window): void {\n const state = getAnimationFrameState(targetWindow);\n state.animFrameRequested = false;\n\n state.current = state.next;\n state.next = [];\n\n state.inAnimationFrameRunner = true;\n while (state.current.length > 0) {\n state.current.sort(AnimationFrameQueueItem.sort);\n const top = state.current.shift()!;\n top.execute();\n }\n state.inAnimationFrameRunner = false;\n}\n\nexport function scheduleAtNextAnimationFrame(targetWindow: Window, runner: () => void, priority: number = 0): IDisposable {\n const state = getAnimationFrameState(targetWindow);\n const item = new AnimationFrameQueueItem(runner, priority);\n state.next.push(item);\n\n if (!state.animFrameRequested) {\n state.animFrameRequested = true;\n targetWindow.requestAnimationFrame(() => animationFrameRunner(targetWindow));\n }\n\n return item;\n}\n\nexport class WindowIntervalTimer extends IntervalTimer {\n private readonly _defaultTarget?: Window;\n\n constructor(node?: Node) {\n super();\n this._defaultTarget = node ? getWindow(node) : undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, targetWindow?: Window): void {\n super.cancelAndSet(runner, interval, targetWindow ?? this._defaultTarget ?? window);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport class FastDomNode {\n\n private _width: string = '';\n private _height: string = '';\n private _top: string = '';\n private _left: string = '';\n private _bottom: string = '';\n private _right: string = '';\n private _className: string = '';\n private _position: string = '';\n private _layerHint: boolean = false;\n private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint' = 'none';\n\n constructor(\n public readonly domNode: T\n ) { }\n\n public setWidth(_width: number | string): void {\n const width = numberAsPixels(_width);\n if (this._width === width) {\n return;\n }\n this._width = width;\n this.domNode.style.width = this._width;\n }\n\n public setHeight(_height: number | string): void {\n const height = numberAsPixels(_height);\n if (this._height === height) {\n return;\n }\n this._height = height;\n this.domNode.style.height = this._height;\n }\n\n public setTop(_top: number | string): void {\n const top = numberAsPixels(_top);\n if (this._top === top) {\n return;\n }\n this._top = top;\n this.domNode.style.top = this._top;\n }\n\n public setLeft(_left: number | string): void {\n const left = numberAsPixels(_left);\n if (this._left === left) {\n return;\n }\n this._left = left;\n this.domNode.style.left = this._left;\n }\n\n public setBottom(_bottom: number | string): void {\n const bottom = numberAsPixels(_bottom);\n if (this._bottom === bottom) {\n return;\n }\n this._bottom = bottom;\n this.domNode.style.bottom = this._bottom;\n }\n\n public setRight(_right: number | string): void {\n const right = numberAsPixels(_right);\n if (this._right === right) {\n return;\n }\n this._right = right;\n this.domNode.style.right = this._right;\n }\n\n public setClassName(className: string): void {\n if (this._className === className) {\n return;\n }\n this._className = className;\n this.domNode.className = this._className;\n }\n\n public toggleClassName(className: string, shouldHaveIt?: boolean): void {\n this.domNode.classList.toggle(className, shouldHaveIt);\n this._className = this.domNode.className;\n }\n\n public setPosition(position: string): void {\n if (this._position === position) {\n return;\n }\n this._position = position;\n this.domNode.style.position = this._position;\n }\n\n public setLayerHinting(layerHint: boolean): void {\n if (this._layerHint === layerHint) {\n return;\n }\n this._layerHint = layerHint;\n if (layerHint) {\n this.domNode.style.transform = 'translate3d(0px, 0px, 0px)';\n } else {\n this.domNode.style.transform = '';\n }\n }\n\n public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {\n if (this._contain === contain) {\n return;\n }\n this._contain = contain;\n this.domNode.style.contain = this._contain;\n }\n\n public setAttribute(name: string, value: string): void {\n this.domNode.setAttribute(name, value);\n }\n\n}\n\nfunction numberAsPixels(value: number | string): string {\n return (typeof value === 'number' ? `${value}px` : value);\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n userAgent: string;\n language: string;\n platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\ndeclare const process: unknown;\n\n// navigator.userAgent is also checked here because bundling with the process module can cause\n// issues otherwise. Note that navigator exists in Node.js 21+ but the userAgent is\n// \"Node.js/\".\nexport const isNode = (typeof process !== 'undefined' && 'title' in (process as any) && (typeof navigator === 'undefined' || navigator.userAgent.startsWith('Node.js/'))) ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = userAgent.includes('Firefox');\nexport const isChrome = userAgent.includes('Chrome');\nexport const isLegacyEdge = userAgent.includes('Edge');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n\ninterface IZoomWindow {\n devicePixelRatio?: number;\n}\n\nexport function getZoomFactor(_targetWindow: IZoomWindow): number {\n return 1;\n}\nexport function getSafariVersion(): number {\n if (!isSafari) {\n return 0;\n }\n const majorVersion = userAgent.match(/Version\\/(\\d+)/);\n if (majorVersion === null || majorVersion.length < 2) {\n return 0;\n }\n return parseInt(majorVersion[1], 10);\n}\n\n// Find the user's platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'].includes(platform);\nexport const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n// Note that when this is true, isLinux will also be true.\nexport const isChromeOS = /\\bCrOS\\b/.test(userAgent);\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as platform from '../../common/Platform';\n\ninterface IWindowChainElement {\n readonly window: WeakRef;\n readonly iframeElement: Element | null;\n}\n\nconst sameOriginWindowChainCache = new WeakMap();\n\nfunction getParentWindowIfSameOrigin(w: Window): Window | null {\n if (!w.parent || w.parent === w) {\n return null;\n }\n\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n return null;\n }\n } catch {\n return null;\n }\n\n return w.parent;\n}\n\nclass IframeUtils {\n\n private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {\n let windowChainCache = sameOriginWindowChainCache.get(targetWindow);\n if (!windowChainCache) {\n windowChainCache = [];\n sameOriginWindowChainCache.set(targetWindow, windowChainCache);\n let w: Window | null = targetWindow;\n let parent: Window | null;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: w.frameElement ?? null\n });\n } else {\n windowChainCache.push({\n window: new WeakRef(w),\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return windowChainCache.slice(0);\n }\n\n public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {\n\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n\n let top = 0;\n let left = 0;\n\n const windowChain = this._getSameOriginWindowChain(childWindow);\n\n for (const windowChainEl of windowChain) {\n const windowInChain = windowChainEl.window.deref();\n top += windowInChain?.scrollY ?? 0;\n left += windowInChain?.scrollX ?? 0;\n\n if (windowInChain === ancestorWindow) {\n break;\n }\n\n if (!windowChainEl.iframeElement) {\n break;\n }\n\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n\n return {\n top: top,\n left: left\n };\n }\n}\n\nexport interface IMouseEvent {\n readonly browserEvent: MouseEvent;\n readonly leftButton: boolean;\n readonly middleButton: boolean;\n readonly rightButton: boolean;\n readonly buttons: number;\n readonly target: HTMLElement;\n readonly detail: number;\n readonly posx: number;\n readonly posy: number;\n readonly ctrlKey: boolean;\n readonly shiftKey: boolean;\n readonly altKey: boolean;\n readonly metaKey: boolean;\n readonly timestamp: number;\n\n preventDefault(): void;\n stopPropagation(): void;\n}\n\nexport class StandardMouseEvent implements IMouseEvent {\n\n public readonly browserEvent: MouseEvent;\n\n public readonly leftButton: boolean;\n public readonly middleButton: boolean;\n public readonly rightButton: boolean;\n public readonly buttons: number;\n public readonly target: HTMLElement;\n public detail: number;\n public readonly posx: number;\n public readonly posy: number;\n public readonly ctrlKey: boolean;\n public readonly shiftKey: boolean;\n public readonly altKey: boolean;\n public readonly metaKey: boolean;\n public readonly timestamp: number;\n\n constructor(targetWindow: Window, e: MouseEvent) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n\n this.target = e.target as HTMLElement;\n\n this.detail = e.detail ?? 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n } else {\n this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;\n this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;\n }\n\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n\n public preventDefault(): void {\n this.browserEvent.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent.stopPropagation();\n }\n}\n\nexport interface IMouseWheelEvent extends MouseEvent {\n readonly wheelDelta: number;\n readonly wheelDeltaX: number;\n readonly wheelDeltaY: number;\n\n readonly deltaX: number;\n readonly deltaY: number;\n readonly deltaZ: number;\n readonly deltaMode: number;\n}\n\ninterface IWebKitMouseWheelEvent {\n wheelDeltaY: number;\n wheelDeltaX: number;\n}\n\ninterface IGeckoMouseWheelEvent {\n HORIZONTAL_AXIS: number;\n VERTICAL_AXIS: number;\n axis: number;\n detail: number;\n}\n\nexport class StandardWheelEvent {\n\n public readonly browserEvent: IMouseWheelEvent | null;\n public readonly deltaY: number;\n public readonly deltaX: number;\n public readonly target: Node | null;\n\n constructor(e: IMouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {\n\n this.browserEvent = e ?? null;\n this.target = e ? (e.target ?? (e as any).targetNode ?? e.srcElement ?? null) : null;\n\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n\n let shouldFactorDPR: boolean = false;\n if (platform.isChrome) {\n const chromeVersionMatch = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1], 10) : 123;\n shouldFactorDPR = chromeMajorVersion <= 122;\n }\n\n if (e) {\n const e1 = e as IWebKitMouseWheelEvent as any;\n const e2 = e as unknown as IGeckoMouseWheelEvent;\n const devicePixelRatio = e.view?.devicePixelRatio ?? 1;\n\n if (typeof e1.wheelDeltaY !== 'undefined') {\n if (shouldFactorDPR) {\n this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);\n } else {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n } else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaY = -e.deltaY / 3;\n } else {\n this.deltaY = -e.deltaY;\n }\n } else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (platform.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n } else if (shouldFactorDPR) {\n this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);\n } else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n } else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n } else if (e.type === 'wheel') {\n const ev = e as unknown as WheelEvent;\n\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n if (platform.isFirefox && !platform.isMac) {\n this.deltaX = -e.deltaX / 3;\n } else {\n this.deltaX = -e.deltaX;\n }\n } else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n if (shouldFactorDPR) {\n this.deltaY = e.wheelDelta / (120 * devicePixelRatio);\n } else {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n }\n\n public preventDefault(): void {\n this.browserEvent?.preventDefault();\n }\n\n public stopPropagation(): void {\n this.browserEvent?.stopPropagation();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';\n\ntype PointerMoveCallback = (event: PointerEvent) => void;\ntype OnStopCallback = () => void;\n\nexport class GlobalPointerMoveMonitor implements IDisposable {\n\n private readonly _hooks = new DisposableStore();\n private _pointerMoveCallback: PointerMoveCallback | null = null;\n private _onStopCallback: OnStopCallback | null = null;\n\n public dispose(): void {\n this.stopMonitoring(false);\n this._hooks.dispose();\n }\n\n public stopMonitoring(invokeStopCallback: boolean): void {\n if (!this.isMonitoring()) {\n return;\n }\n\n this._hooks.clear();\n this._pointerMoveCallback = null;\n const onStopCallback = this._onStopCallback;\n this._onStopCallback = null;\n\n if (invokeStopCallback && onStopCallback) {\n onStopCallback();\n }\n }\n\n public isMonitoring(): boolean {\n return !!this._pointerMoveCallback;\n }\n\n public startMonitoring(\n initialElement: Element,\n pointerId: number,\n initialButtons: number,\n pointerMoveCallback: PointerMoveCallback,\n onStopCallback: OnStopCallback\n ): void {\n if (this.isMonitoring()) {\n this.stopMonitoring(false);\n }\n this._pointerMoveCallback = pointerMoveCallback;\n this._onStopCallback = onStopCallback;\n\n let eventSource: Element | Window = initialElement;\n\n try {\n initialElement.setPointerCapture(pointerId);\n this._hooks.add(toDisposable(() => {\n try {\n initialElement.releasePointerCapture(pointerId);\n } catch {\n // ignore\n }\n }));\n } catch {\n eventSource = dom.getWindow(initialElement);\n }\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_MOVE,\n (e) => {\n if (e.buttons !== initialButtons) {\n this.stopMonitoring(true);\n return;\n }\n\n e.preventDefault();\n this._pointerMoveCallback!(e);\n }\n ));\n\n this._hooks.add(dom.addDisposableListener(\n eventSource,\n dom.eventType.POINTER_UP,\n (e: PointerEvent) => this.stopMonitoring(true)\n ));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { IMouseEvent, StandardMouseEvent } from './mouseEvent';\nimport { Disposable } from '../../common/Lifecycle';\n\nexport abstract class Widget extends Disposable {\n\n protected _onclick(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.CLICK, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseover(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n\n protected _onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void {\n this._register(dom.addDisposableListener(domNode, dom.eventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(dom.getWindow(domNode), e))));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport * as dom from '../Dom';\n\nexport interface IScrollbarArrowOptions {\n handleActivate: () => void;\n className: string;\n // icon: ThemeIcon;\n\n bgWidth: number;\n bgHeight: number;\n\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\nexport class ScrollbarArrow extends Widget {\n\n private _handleActivate: () => void;\n public bgDomNode: HTMLElement;\n public domNode: HTMLElement;\n private _pointerdownRepeatTimer: dom.WindowIntervalTimer;\n private _pointerdownScheduleRepeatTimer: TimeoutTimer;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n constructor(opts: IScrollbarArrowOptions) {\n super();\n this._handleActivate = opts.handleActivate;\n\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'xterm-arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n\n this.domNode.style.position = 'absolute';\n const arrowSize = Math.min(opts.bgWidth, opts.bgHeight);\n this.domNode.style.width = arrowSize + 'px';\n this.domNode.style.height = arrowSize + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.eventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n\n this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n\n private _arrowPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = (): void => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._handleActivate(), 1000 / 24, dom.getWindow(e));\n };\n\n this._handleActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData) => { /* Intentional empty */ },\n () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n }\n );\n\n e.preventDefault();\n }\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent | undefined;\n\n public get event(): IEvent {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed) {\n return;\n }\n switch (this._listeners.length) {\n case 0: return;\n case 1: {\n const { fn, thisArgs } = this._listeners[0];\n fn.call(thisArgs, event);\n return;\n }\n default: {\n // Snapshot listeners to allow modifications during iteration (2+ listeners)\n const listeners = this._listeners.slice();\n for (const { fn, thisArgs } of listeners) {\n fn.call(thisArgs, event);\n }\n }\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward(from: IEvent, to: Emitter): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map(event: IEvent, map: (i: I) => O): IEvent {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent;\n export function any(...events: IEvent[]): IEvent {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe(event: IEvent, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe(event: IEvent, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Emitter, IEvent } from '../../common/Event';\nimport { Disposable, IDisposable } from '../../common/Lifecycle';\n\nexport const enum ScrollbarVisibility {\n AUTO = 1,\n HIDDEN = 2,\n VISIBLE = 3\n}\n\nexport interface IScrollEvent {\n inSmoothScrolling: boolean;\n\n oldWidth: number;\n oldScrollWidth: number;\n oldScrollLeft: number;\n\n width: number;\n scrollWidth: number;\n scrollLeft: number;\n\n oldHeight: number;\n oldScrollHeight: number;\n oldScrollTop: number;\n\n height: number;\n scrollHeight: number;\n scrollTop: number;\n\n widthChanged: boolean;\n scrollWidthChanged: boolean;\n scrollLeftChanged: boolean;\n\n heightChanged: boolean;\n scrollHeightChanged: boolean;\n scrollTopChanged: boolean;\n}\n\nexport class ScrollState implements IScrollDimensions, IScrollPosition {\n private _scrollStateBrand: void = undefined;\n\n public readonly rawScrollLeft: number;\n public readonly rawScrollTop: number;\n\n public readonly width: number;\n public readonly scrollWidth: number;\n public readonly scrollLeft: number;\n public readonly height: number;\n public readonly scrollHeight: number;\n public readonly scrollTop: number;\n\n constructor(\n private readonly _forceIntegerValues: boolean,\n width: number,\n scrollWidth: number,\n scrollLeft: number,\n height: number,\n scrollHeight: number,\n scrollTop: number\n ) {\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n\n this.rawScrollLeft = scrollLeft;\n this.rawScrollTop = scrollTop;\n\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n\n public equals(other: ScrollState): boolean {\n return (\n this.rawScrollLeft === other.rawScrollLeft\n\t\t\t&& this.rawScrollTop === other.rawScrollTop\n\t\t\t&& this.width === other.width\n\t\t\t&& this.scrollWidth === other.scrollWidth\n\t\t\t&& this.scrollLeft === other.scrollLeft\n\t\t\t&& this.height === other.height\n\t\t\t&& this.scrollHeight === other.scrollHeight\n\t\t\t&& this.scrollTop === other.scrollTop\n );\n }\n\n public withScrollDimensions(update: INewScrollDimensions, useRawScrollPositions: boolean): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n (typeof update.width !== 'undefined' ? update.width : this.width),\n (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth),\n useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft,\n (typeof update.height !== 'undefined' ? update.height : this.height),\n (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight),\n useRawScrollPositions ? this.rawScrollTop : this.scrollTop\n );\n }\n\n public withScrollPosition(update: INewScrollPosition): ScrollState {\n return new ScrollState(\n this._forceIntegerValues,\n this.width,\n this.scrollWidth,\n (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft),\n this.height,\n this.scrollHeight,\n (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop)\n );\n }\n\n public createScrollEvent(previous: ScrollState, inSmoothScrolling: boolean): IScrollEvent {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n\n}\n\nexport interface IScrollDimensions {\n readonly width: number;\n readonly scrollWidth: number;\n readonly height: number;\n readonly scrollHeight: number;\n}\nexport interface INewScrollDimensions {\n width?: number;\n scrollWidth?: number;\n height?: number;\n scrollHeight?: number;\n}\n\nexport interface IScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n}\nexport interface ISmoothScrollPosition {\n readonly scrollLeft: number;\n readonly scrollTop: number;\n\n readonly width: number;\n readonly height: number;\n}\nexport interface INewScrollPosition {\n scrollLeft?: number;\n scrollTop?: number;\n}\n\nexport interface IScrollableOptions {\n forceIntegerValues: boolean;\n smoothScrollDuration: number;\n scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n}\n\nexport class Scrollable extends Disposable {\n\n private _scrollableBrand: void = undefined;\n\n private _smoothScrollDuration: number;\n private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable;\n private _state: ScrollState;\n private _smoothScrolling: SmoothScrollingOperation | null;\n\n private _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n constructor(options: IScrollableOptions) {\n super();\n\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n\n public override dispose(): void {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n\n public setSmoothScrollDuration(smoothScrollDuration: number): void {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n\n public validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition {\n return this._state.withScrollPosition(scrollPosition);\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._state;\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void {\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n\n this._smoothScrolling?.acceptScrollDimensions(this._state);\n }\n\n public getFutureScrollPosition(): IScrollPosition {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n\n public getCurrentScrollPosition(): IScrollPosition {\n return this._state;\n }\n\n public setScrollPositionNow(update: INewScrollPosition): void {\n const newState = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n\n this._setState(newState, false);\n }\n\n public setScrollPositionSmooth(update: INewScrollPosition, reuseAnimation?: boolean): void {\n if (this._smoothScrollDuration === 0) {\n this.setScrollPositionNow(update); return;\n }\n\n if (this._smoothScrolling) {\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n\n const validTarget = this._state.withScrollPosition(update);\n\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n return;\n }\n let newSmoothScrolling: SmoothScrollingOperation;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n } else {\n newSmoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n } else {\n const validTarget = this._state.withScrollPosition(update);\n\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n public hasPendingScrollAnimation(): boolean {\n return Boolean(this._smoothScrolling);\n }\n\n private _performSmoothScrolling(): void {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n\n this._setState(newState, true);\n\n if (!this._smoothScrolling) {\n return;\n }\n\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n\n private _setState(newState: ScrollState, inSmoothScrolling: boolean): void {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\n\nclass SmoothScrollingUpdate {\n\n public readonly scrollLeft: number;\n public readonly scrollTop: number;\n public readonly isDone: boolean;\n\n constructor(scrollLeft: number, scrollTop: number, isDone: boolean) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n\n}\n\ninterface IAnimation {\n (completion: number): number;\n}\n\nfunction createEaseOutCubic(from: number, to: number): IAnimation {\n const delta = to - from;\n return function (completion: number): number {\n return from + delta * easeOutCubic(completion);\n };\n}\n\nfunction createComposed(a: IAnimation, b: IAnimation, cut: number): IAnimation {\n return function (completion: number): number {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\n\nclass SmoothScrollingOperation {\n\n public readonly from: ISmoothScrollPosition;\n public to: ISmoothScrollPosition;\n public readonly duration: number;\n public readonly startTime: number;\n public animationFrameDisposable: IDisposable | null;\n\n private _scrollLeft!: IAnimation;\n private _scrollTop!: IAnimation;\n\n constructor(from: ISmoothScrollPosition, to: ISmoothScrollPosition, startTime: number, duration: number) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n\n this.animationFrameDisposable = null;\n\n this._initAnimations();\n }\n\n private _initAnimations(): void {\n this._scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this._scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n\n private _initAnimation(from: number, to: number, viewportSize: number): IAnimation {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1: number; let stop2: number;\n if (from < to) {\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n } else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n\n public dispose(): void {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n\n public acceptScrollDimensions(state: ScrollState): void {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n\n public tick(): SmoothScrollingUpdate {\n return this._tick(Date.now());\n }\n\n protected _tick(now: number): SmoothScrollingUpdate {\n const completion = (now - this.startTime) / this.duration;\n\n if (completion < 1) {\n const newScrollLeft = this._scrollLeft(completion);\n const newScrollTop = this._scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n\n public static start(from: ISmoothScrollPosition, to: ISmoothScrollPosition, duration: number): SmoothScrollingOperation {\n duration = duration + 10;\n const startTime = Date.now() - 10;\n\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\n\nfunction easeInCubic(t: number): number {\n return Math.pow(t, 3);\n}\n\nfunction easeOutCubic(t: number): number {\n return 1 - easeInCubic(1 - t);\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { FastDomNode } from './fastDomNode';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ScrollbarVisibility } from './scrollable';\n\nexport class ScrollbarVisibilityController extends Disposable {\n private _visibility: ScrollbarVisibility;\n private _visibleClassName: string;\n private _invisibleClassName: string;\n private _domNode: FastDomNode | null;\n private _rawShouldBeVisible: boolean;\n private _shouldBeVisible: boolean;\n private _isNeeded: boolean;\n private _isVisible: boolean;\n private _revealTimer: TimeoutTimer;\n\n constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n\n public setVisibility(visibility: ScrollbarVisibility): void {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n\n public setShouldBeVisible(rawShouldBeVisible: boolean): void {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n\n private _applyVisibilitySetting(): boolean {\n if (this._visibility === ScrollbarVisibility.HIDDEN) {\n return false;\n }\n if (this._visibility === ScrollbarVisibility.VISIBLE) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n\n private _updateShouldBeVisible(): void {\n const shouldBeVisible = this._applyVisibilitySetting();\n\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n\n public setIsNeeded(isNeeded: boolean): void {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n\n public setDomNode(domNode: FastDomNode): void {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n\n this.setShouldBeVisible(false);\n }\n\n public ensureVisibility(): void {\n\n if (!this._isNeeded) {\n this._hide(false);\n return;\n }\n\n if (this._shouldBeVisible) {\n this._reveal();\n } else {\n this._hide(true);\n }\n }\n\n private _reveal(): void {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n\n this._revealTimer.setIfNotSet(() => {\n this._domNode?.setClassName(this._visibleClassName);\n }, 0);\n }\n\n private _hide(withFadeAway: boolean): void {\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' xterm-fade' : ''));\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';\nimport { StandardWheelEvent } from './mouseEvent';\nimport { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';\nimport { ScrollbarState } from './scrollbarState';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController';\nimport { Widget } from './widget';\nimport * as platform from '../../common/Platform';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';\n\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\n\nexport interface ISimplifiedPointerEvent {\n buttons: number;\n pageX: number;\n pageY: number;\n}\n\nexport interface IScrollbarHost {\n handleMouseWheel(mouseWheelEvent: StandardWheelEvent): void;\n handleDragStart(): void;\n handleDragEnd(): void;\n}\n\ninterface IAbstractScrollbarOptions {\n lazyRender: boolean;\n host: IScrollbarHost;\n scrollbarState: ScrollbarState;\n visibility: ScrollbarVisibility;\n extraScrollbarClassName: string;\n scrollable: Scrollable;\n scrollByPage: boolean;\n}\n\nexport abstract class AbstractScrollbar extends Widget {\n\n protected _host: IScrollbarHost;\n protected _scrollable: Scrollable;\n protected _scrollByPage: boolean;\n private _lazyRender: boolean;\n protected _scrollbarState: ScrollbarState;\n protected _visibilityController: ScrollbarVisibilityController;\n private _pointerMoveMonitor: GlobalPointerMoveMonitor;\n\n public domNode: FastDomNode;\n public slider!: FastDomNode;\n\n protected _shouldRender: boolean;\n\n constructor(opts: IAbstractScrollbarOptions) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'xterm-visible xterm-scrollbar ' + opts.extraScrollbarClassName, 'xterm-invisible xterm-scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = new FastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.eventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));\n }\n\n // ----------------- creation\n\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n return arrow;\n }\n\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {\n this.slider = new FastDomNode(document.createElement('div'));\n this.slider.setClassName('xterm-slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n\n this.domNode.domNode.appendChild(this.slider.domNode);\n\n this._register(dom.addDisposableListener(\n this.slider.domNode,\n dom.eventType.POINTER_DOWN,\n (e: PointerEvent) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n ));\n\n this._onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n\n // ----------------- Update state\n\n protected _handleElementSize(visibleSize: number): boolean {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollSize(elementScrollSize: number): boolean {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n protected _handleElementScrollPosition(elementScrollPosition: number): boolean {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n\n // ----------------- rendering\n\n public beginReveal(): void {\n this._visibilityController.setShouldBeVisible(true);\n }\n\n public beginHide(): void {\n this._visibilityController.setShouldBeVisible(false);\n }\n\n public render(): void {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n\n private _domNodePointerDown(e: PointerEvent): void {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._handlePointerDown(e);\n }\n\n public delegatePointerDown(e: PointerEvent): void {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n } else {\n this._handlePointerDown(e);\n }\n }\n\n private _handlePointerDown(e: PointerEvent): void {\n let offsetX: number;\n let offsetY: number;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n } else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(\n this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)\n );\n\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n\n private _sliderPointerDown(e: PointerEvent): void {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('xterm-active', true);\n\n this._pointerMoveMonitor.startMonitoring(\n e.target,\n e.pointerId,\n e.buttons,\n (pointerMoveData: PointerEvent) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n },\n () => {\n this.slider.toggleClassName('xterm-active', false);\n this._host.handleDragEnd();\n }\n );\n\n this._host.handleDragStart();\n }\n\n private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {\n\n const desiredScrollPosition: INewScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n public updateScrollbarSize(scrollbarSize: number): void {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n\n public isNeeded(): boolean {\n return this._scrollbarState.isNeeded();\n }\n\n // ----------------- Overwrite these\n\n protected abstract _renderDomNode(largeSize: number, smallSize: number): void;\n protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;\n\n protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;\n protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;\n protected abstract _updateScrollbarSize(size: number): void;\n\n public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n/**\n * The minimal size of the slider (such that it can still be clickable).\n * The slider is artificially enlarged to keep it usable.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\n\ninterface IScrollbarStateComputedValues {\n computedAvailableSize: number;\n computedIsNeeded: boolean;\n computedSliderSize: number;\n computedSliderRatio: number;\n computedSliderPosition: number;\n}\n\nexport class ScrollbarState {\n\n /**\n * For the vertical scrollbar: the width.\n * For the horizontal scrollbar: the height.\n */\n private _scrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the pair horizontal scrollbar.\n * For the horizontal scrollbar: the width of the pair vertical scrollbar.\n */\n private _oppositeScrollbarSize: number;\n\n /**\n * For the vertical scrollbar: the height of the scrollbar's arrows.\n * For the horizontal scrollbar: the width of the scrollbar's arrows.\n */\n private _arrowSize: number;\n\n // --- variables\n /**\n * For the vertical scrollbar: the viewport height.\n * For the horizontal scrollbar: the viewport width.\n */\n private _visibleSize: number;\n\n /**\n * For the vertical scrollbar: the scroll height.\n * For the horizontal scrollbar: the scroll width.\n */\n private _scrollSize: number;\n\n /**\n * For the vertical scrollbar: the scroll top.\n * For the horizontal scrollbar: the scroll left.\n */\n private _scrollPosition: number;\n\n // --- computed variables\n\n /**\n * `visibleSize` - `oppositeScrollbarSize`\n */\n private _computedAvailableSize: number;\n /**\n * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)\n */\n private _computedIsNeeded: boolean;\n\n private _computedSliderSize: number;\n private _computedSliderRatio: number;\n private _computedSliderPosition: number;\n\n constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n\n this._refreshComputedValues();\n }\n\n public clone(): ScrollbarState {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n\n public setVisibleSize(visibleSize: number): boolean {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollSize(scrollSize: number): boolean {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollPosition(scrollPosition: number): boolean {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n\n public setScrollbarSize(scrollbarSize: number): void {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n\n public setArrowSize(arrowSize: number): void {\n const iArrowSize = Math.round(arrowSize);\n if (this._arrowSize !== iArrowSize) {\n this._arrowSize = iArrowSize;\n this._refreshComputedValues();\n }\n }\n\n public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n\n private static _computeValues(\n oppositeScrollbarSize: number,\n arrowSize: number,\n visibleSize: number,\n scrollSize: number,\n scrollPosition: number\n ): IScrollbarStateComputedValues {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n\n if (!computedIsNeeded) {\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n\n private _refreshComputedValues(): void {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n\n public getArrowSize(): number {\n return this._arrowSize;\n }\n\n public getScrollPosition(): number {\n return this._scrollPosition;\n }\n\n public getRectangleLargeSize(): number {\n return this._computedAvailableSize;\n }\n\n public getRectangleSmallSize(): number {\n return this._scrollbarSize;\n }\n\n public isNeeded(): boolean {\n return this._computedIsNeeded;\n }\n\n public getSliderSize(): number {\n return this._computedSliderSize;\n }\n\n public getSliderPosition(): number {\n return this._computedSliderPosition;\n }\n\n public getDesiredScrollPositionFromOffset(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n\n public getDesiredScrollPositionFromOffsetPaged(offset: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const correctedOffset = offset - this._arrowSize;\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize;\n } else {\n desiredScrollPosition += this._visibleSize;\n }\n return desiredScrollPosition;\n }\n\n public getDesiredScrollPositionFromDelta(delta: number): number {\n if (!this._computedIsNeeded) {\n return 0;\n }\n\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\n\nexport class HorizontalScrollbar extends AbstractScrollbar {\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (options.horizontalHasArrows ? options.horizontalScrollbarSize : 0),\n (options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n scrollDimensions.width,\n scrollDimensions.scrollWidth,\n scrollPosition.scrollLeft\n ),\n visibility: options.horizontal,\n extraScrollbarClassName: 'xterm-horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n if (options.horizontalHasArrows) {\n throw new Error('horizontalHasArrows is not supported in xterm.js');\n }\n\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetX;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setHeight(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollLeft = scrollPosition;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.HIDDEN ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './abstractScrollbar';\nimport { IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { ScrollbarState } from './scrollbarState';\nimport { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';\nimport type { ScrollbarArrow } from './scrollbarArrow';\n\nexport class VerticalScrollbar extends AbstractScrollbar {\n private _arrowUp: ScrollbarArrow | undefined;\n private _arrowDown: ScrollbarArrow | undefined;\n private _arrowScrollDelta: number = 0;\n\n constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n const hasArrows = options.verticalHasArrows;\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState(\n (hasArrows ? options.verticalScrollbarSize : 0),\n (options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),\n 0,\n scrollDimensions.height,\n scrollDimensions.scrollHeight,\n scrollPosition.scrollTop\n ),\n visibility: options.vertical,\n extraScrollbarClassName: 'xterm-vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n\n this._setArrows(hasArrows, options.verticalScrollbarSize);\n\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n\n protected _updateSlider(sliderSize: number, sliderPosition: number): void {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n\n protected _renderDomNode(largeSize: number, smallSize: number): void {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n\n public handleScroll(e: IScrollEvent): boolean {\n this._shouldRender = this._handleElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._handleElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._handleElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n\n protected _pointerDownRelativePosition(offsetX: number, offsetY: number): number {\n return offsetY;\n }\n\n protected _sliderPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageY;\n }\n\n protected _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number {\n return e.pageX;\n }\n\n protected _updateScrollbarSize(size: number): void {\n this.slider.setWidth(size);\n }\n\n public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {\n target.scrollTop = scrollPosition;\n }\n\n private _arrowScroll(delta: number): void {\n const currentPosition = this._scrollable.getCurrentScrollPosition();\n this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });\n }\n\n private _setArrows(showArrows: boolean, size: number): void {\n this._arrowScrollDelta = size;\n if (!this._arrowUp || !this._arrowDown) {\n const arrowDelta = 0;\n this._arrowUp = this._createArrow({\n className: 'xterm-scra xterm-arrow-up',\n top: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)\n });\n this._arrowDown = this._createArrow({\n className: 'xterm-scra xterm-arrow-down',\n bottom: arrowDelta,\n left: arrowDelta,\n bgWidth: size,\n bgHeight: size,\n handleActivate: () => this._arrowScroll(this._arrowScrollDelta)\n });\n }\n\n this._updateArrowSize(this._arrowUp, size);\n this._updateArrowSize(this._arrowDown, size);\n\n if (!this._arrowUp || !this._arrowDown) {\n return;\n }\n\n const display = showArrows ? '' : 'none';\n this._arrowUp.bgDomNode.style.display = display;\n this._arrowUp.domNode.style.display = display;\n this._arrowDown.bgDomNode.style.display = display;\n this._arrowDown.domNode.style.display = display;\n }\n\n private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {\n if (!arrow) {\n return;\n }\n arrow.bgDomNode.style.width = `${size}px`;\n arrow.bgDomNode.style.height = `${size}px`;\n arrow.domNode.style.width = `${size}px`;\n arrow.domNode.style.height = `${size}px`;\n }\n\n public updateOptions(options: IScrollableElementResolvedOptions): void {\n const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;\n this._scrollbarState.setArrowSize(arrowSize);\n this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);\n this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as dom from '../Dom';\nimport { FastDomNode } from './fastDomNode';\nimport { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';\nimport { IScrollbarHost } from './abstractScrollbar';\nimport { HorizontalScrollbar } from './horizontalScrollbar';\nimport { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';\nimport { VerticalScrollbar } from './verticalScrollbar';\nimport { Widget } from './widget';\nimport { TimeoutTimer } from '../../common/Async';\nimport { Emitter, IEvent } from '../../common/Event';\nimport { IDisposable, dispose } from '../../common/Lifecycle';\nimport * as platform from '../../common/Platform';\nimport { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';\n// import 'vs/css!./media/scrollbars';\n\nconst enum Constants {\n HIDE_TIMEOUT = 500,\n SCROLL_WHEEL_SENSITIVITY = 50\n}\n\nclass MouseWheelClassifierItem {\n public timestamp: number;\n public deltaX: number;\n public deltaY: number;\n public score: number;\n\n constructor(timestamp: number, deltaX: number, deltaY: number) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\n\nclass MouseWheelClassifier {\n\n public static readonly INSTANCE = new MouseWheelClassifier();\n\n private readonly _capacity: number;\n private _memory: MouseWheelClassifierItem[];\n private _front: number;\n private _rear: number;\n\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n\n public isPhysicalMouseWheel(): boolean {\n if (this._front === -1 && this._rear === -1) {\n return false;\n }\n\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n\n let index = this._rear;\n while (index !== -1) {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n\n if (index === this._front) {\n break;\n }\n\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n }\n\n return (score <= 0.5);\n }\n\n public acceptStandardWheelEvent(e: StandardWheelEvent): void {\n if (platform.isChrome) {\n const targetWindow = dom.getWindow(e.browserEvent);\n const pageZoomFactor = platform.getZoomFactor(targetWindow);\n this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);\n } else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n\n public accept(timestamp: number, deltaX: number, deltaY: number): void {\n let previousItem = null;\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n } else {\n previousItem = this._memory[this._rear];\n\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n\n item.score = this._computeScore(item, previousItem);\n }\n\n private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {\n\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n return 1;\n }\n\n let score: number = 0.5;\n\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n score += 0.25;\n }\n\n if (previousItem) {\n const absDeltaX = Math.abs(item.deltaX);\n const absDeltaY = Math.abs(item.deltaY);\n\n const absPreviousDeltaX = Math.abs(previousItem.deltaX);\n const absPreviousDeltaY = Math.abs(previousItem.deltaY);\n\n const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);\n const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);\n\n const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);\n const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);\n\n const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);\n if (isSameModulo) {\n score -= 0.5;\n }\n }\n\n return Math.min(Math.max(score, 0), 1);\n }\n\n private _isAlmostInt(value: number): boolean {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\n\nexport class SmoothScrollableElement extends Widget {\n\n private readonly _options: IScrollableElementResolvedOptions;\n protected readonly _scrollable: Scrollable;\n private readonly _verticalScrollbar: VerticalScrollbar;\n private readonly _horizontalScrollbar: HorizontalScrollbar;\n private readonly _domNode: HTMLElement;\n\n private readonly _leftShadowDomNode: FastDomNode | null;\n private readonly _topShadowDomNode: FastDomNode | null;\n private readonly _topLeftShadowDomNode: FastDomNode | null;\n\n private readonly _listenOnDomNode: HTMLElement;\n\n private _mouseWheelToDispose: IDisposable[];\n\n private _isDragging: boolean;\n private _mouseIsOver: boolean;\n\n private readonly _hideTimeout: TimeoutTimer;\n private _shouldRender: boolean;\n\n private _revealOnScroll: boolean;\n\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll: IEvent = this._onScroll.event;\n\n public get options(): Readonly {\n return this._options;\n }\n\n public constructor(element: HTMLElement, options: IScrollableElementCreationOptions, scrollable?: Scrollable) {\n super();\n options = options ?? {};\n let resolvedScrollable: Scrollable;\n const ownsScrollable = !scrollable;\n if (scrollable) {\n resolvedScrollable = scrollable;\n } else {\n options.mouseWheelSmoothScroll = false;\n resolvedScrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)\n });\n }\n\n this._options = resolveOptions(options);\n this._scrollable = resolvedScrollable;\n\n this._register(this._scrollable.onScroll((e) => {\n this._handleScroll(e);\n this._onScroll.fire(e);\n }));\n if (ownsScrollable) {\n this._register(this._scrollable);\n }\n\n const scrollbarHost: IScrollbarHost = {\n handleMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._handleMouseWheel(mouseWheelEvent),\n handleDragStart: () => this._handleDragStart(),\n handleDragEnd: () => this._handleDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n\n this._domNode = document.createElement('div');\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n\n if (this._options.useShadows) {\n this._leftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n\n this._topShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n\n this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('xterm-shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n } else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n\n this._listenOnDomNode = this._options.listenOnDomNode ?? this._domNode;\n\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n\n this._onmouseover(this._listenOnDomNode, (e) => this._handleMouseOver(e));\n this._onmouseleave(this._listenOnDomNode, (e) => this._handleMouseLeave(e));\n\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n\n this._shouldRender = true;\n\n this._revealOnScroll = true;\n }\n\n public override dispose(): void {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n\n public getDomNode(): HTMLElement {\n return this._domNode;\n }\n\n public getScrollDimensions(): IScrollDimensions {\n return this._scrollable.getScrollDimensions();\n }\n\n public setScrollDimensions(dimensions: INewScrollDimensions): void {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n\n public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n } else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n\n public getScrollPosition(): IScrollPosition {\n return this._scrollable.getCurrentScrollPosition();\n }\n\n public updateClassName(newClassName: string): void {\n this._options.className = newClassName;\n if (platform.isMac) {\n this._options.className += ' xterm-mac';\n }\n this._domNode.className = 'xterm-scrollable-element ' + this._options.className;\n }\n\n public updateOptions(newOptions: IScrollableElementChangeOptions): void {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalHasArrows !== 'undefined') {\n this._options.horizontalHasArrows = newOptions.horizontalHasArrows;\n }\n if (typeof newOptions.verticalHasArrows !== 'undefined') {\n this._options.verticalHasArrows = newOptions.verticalHasArrows;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n }\n\n // -------------------- mouse wheel scrolling --------------------\n\n private _setListeningToMouseWheel(shouldListen: boolean): void {\n const isListening = (this._mouseWheelToDispose.length > 0);\n\n if (isListening === shouldListen) {\n return;\n }\n\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n\n if (shouldListen) {\n const onMouseWheel = (browserEvent: IMouseWheelEvent): void => {\n this._handleMouseWheel(new StandardWheelEvent(browserEvent));\n };\n\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.eventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n\n private _handleMouseWheel(e: StandardWheelEvent): void {\n if (e.browserEvent?.defaultPrevented) {\n return;\n }\n\n const classifier = MouseWheelClassifier.INSTANCE;\n classifier.acceptStandardWheelEvent(e);\n\n let didScroll = false;\n\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n\n if (this._options.scrollPredominantAxis) {\n if (this._options.scrollYToX && deltaX + deltaY === 0) {\n deltaX = deltaY = 0;\n } else if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n } else {\n deltaY = 0;\n }\n }\n\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n\n const shiftConvert = !platform.isMac && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n\n if (e.browserEvent && e.browserEvent.altKey) {\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n\n let desiredScrollPosition: INewScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = Constants.SCROLL_WHEEL_SENSITIVITY * deltaY;\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = Constants.SCROLL_WHEEL_SENSITIVITY * deltaX;\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n\n const canPerformSmoothScroll = (\n this._options.mouseWheelSmoothScroll\n\t\t\t\t\t&& classifier.isPhysicalMouseWheel()\n );\n\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n } else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n\n didScroll = true;\n }\n }\n\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleScroll(e: IScrollEvent): void {\n this._shouldRender = this._horizontalScrollbar.handleScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.handleScroll(e) || this._shouldRender;\n\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n\n if (this._revealOnScroll) {\n this._reveal();\n }\n\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n\n public renderNow(): void {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n\n this._render();\n }\n\n private _render(): void {\n if (!this._shouldRender) {\n return;\n }\n\n this._shouldRender = false;\n\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n\n const leftClassName = (enableLeft ? ' xterm-shadow-left' : '');\n const topClassName = (enableTop ? ' xterm-shadow-top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' xterm-shadow-top-left-corner' : '');\n this._leftShadowDomNode!.setClassName(`xterm-shadow${leftClassName}`);\n this._topShadowDomNode!.setClassName(`xterm-shadow${topClassName}`);\n this._topLeftShadowDomNode!.setClassName(`xterm-shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n\n // -------------------- fade in / fade out --------------------\n\n private _handleDragStart(): void {\n this._isDragging = true;\n this._reveal();\n }\n\n private _handleDragEnd(): void {\n this._isDragging = false;\n this._hide();\n }\n\n private _handleMouseLeave(e: IMouseEvent): void {\n this._mouseIsOver = false;\n this._hide();\n }\n\n private _handleMouseOver(e: IMouseEvent): void {\n this._mouseIsOver = true;\n this._reveal();\n }\n\n private _reveal(): void {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n\n private _hide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n\n private _scheduleHide(): void {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), Constants.HIDE_TIMEOUT);\n }\n }\n}\n\nfunction resolveOptions(opts: IScrollableElementCreationOptions): IScrollableElementResolvedOptions {\n const result: IScrollableElementResolvedOptions = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.AUTO),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.AUTO),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n\n if (platform.isMac) {\n result.className += ' xterm-mac';\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2024 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';\nimport { ViewportConstants } from './shared/Constants';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';\nimport { CoreMouseEventType } from '../common/Types';\nimport { scheduleAtNextAnimationFrame } from './Dom';\nimport { SmoothScrollableElement } from './scrollable/scrollableElement';\nimport type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';\nimport { Emitter, EventUtils } from '../common/Event';\nimport { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';\n\nexport class Viewport extends Disposable {\n\n protected _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n private _scrollableElement: SmoothScrollableElement;\n private _styleElement: HTMLStyleElement;\n\n private _queuedAnimationFrame?: number;\n private _latestYDisp?: number;\n private _isSyncing: boolean = false;\n private _isHandlingScroll: boolean = false;\n private _suppressOnScrollHandler: boolean = false;\n private _needsSyncOnRender: boolean = false;\n\n constructor(\n element: HTMLElement,\n screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseStateService mouseStateService: IMouseStateService,\n @IThemeService themeService: IThemeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n const scrollable = this._register(new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,\n // This is used over `IRenderService.addRefreshCallback` since it can be canceled\n scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)\n }));\n this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {\n scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);\n }));\n\n this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {\n vertical: ScrollbarVisibility.AUTO,\n horizontal: ScrollbarVisibility.HIDDEN,\n useShadows: false,\n mouseWheelSmoothScroll: true,\n verticalHasArrows: this._optionsService.rawOptions.scrollbar?.showArrows ?? false,\n ...this._getChangeOptions()\n }, scrollable));\n this._register(this._optionsService.onMultipleOptionChange([\n 'scrollSensitivity',\n 'fastScrollSensitivity',\n 'scrollbar'\n ], () => this._scrollableElement.updateOptions(this._getChangeOptions())));\n // Don't handle mouse wheel if wheel events are supported by the current mouse prototcol\n this._register(mouseStateService.onProtocolChange(type => {\n this._scrollableElement.updateOptions({\n handleMouseWheel: !(type & CoreMouseEventType.WHEEL)\n });\n }));\n\n this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n element.style.backgroundColor = themeService.colors.background.css;\n this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;\n }));\n element.appendChild(this._scrollableElement.getDomNode());\n this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));\n\n this._styleElement = coreBrowserService.mainDocument.createElement('style');\n screenElement.appendChild(this._styleElement);\n this._register(toDisposable(() => this._styleElement.remove()));\n this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {\n this._styleElement.textContent = [\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider {`,\n ` background: ${themeService.colors.scrollbarSliderBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider:hover {`,\n ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,\n `}`,\n `.xterm .xterm-scrollable-element > .xterm-scrollbar > .xterm-slider.xterm-active {`,\n ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,\n `}`\n ].join('\\n');\n }));\n\n this._register(this._bufferService.onResize(() => this.queueSync()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n // Reset _latestYDisp when switching buffers to prevent stale scroll position\n // from alt buffer contaminating normal buffer scroll position\n this._latestYDisp = undefined;\n this.queueSync();\n }));\n this._register(this._bufferService.onScroll(() => this._sync()));\n\n // Flush deferred viewport sync after a render completes (e.g. after ESU ends\n // synchronized output mode). This ensures DOM scroll position updates atomically\n // with the canvas render.\n this._register(this._renderService.onRender(() => {\n if (this._needsSyncOnRender) {\n this._needsSyncOnRender = false;\n this._sync();\n }\n }));\n\n this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));\n\n }\n\n public scrollLines(disp: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n reuseAnimation: true,\n scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height\n });\n }\n\n public scrollToLine(line: number, disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll) {\n this._latestYDisp = line;\n }\n this._scrollableElement.setScrollPosition({\n reuseAnimation: !disableSmoothScroll,\n scrollTop: line * this._renderService.dimensions.css.cell.height\n });\n }\n\n private _getChangeOptions(): IScrollableElementChangeOptions {\n const showScrollbar = this._optionsService.rawOptions.scrollbar?.showScrollbar ?? true;\n const showArrows = this._optionsService.rawOptions.scrollbar?.showArrows ?? false;\n const verticalScrollbarSize = showScrollbar\n ? (this._optionsService.rawOptions.scrollbar?.width ?? ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH)\n : 0;\n return {\n mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,\n fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,\n vertical: showScrollbar ? ScrollbarVisibility.AUTO : ScrollbarVisibility.HIDDEN,\n verticalScrollbarSize,\n verticalHasArrows: showArrows\n };\n }\n\n public queueSync(ydisp?: number): void {\n // Update state\n if (ydisp !== undefined) {\n this._latestYDisp = ydisp;\n }\n\n // Don't queue more than one callback\n if (this._queuedAnimationFrame !== undefined) {\n return;\n }\n this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {\n this._queuedAnimationFrame = undefined;\n this._sync(this._latestYDisp);\n });\n }\n\n private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {\n if (!this._renderService || this._isSyncing) {\n return;\n }\n // Defer DOM scroll updates during synchronized output to prevent visible\n // scroll position flickering while the canvas content is frozen.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._needsSyncOnRender = true;\n return;\n }\n this._isSyncing = true;\n\n // Ignore any onScroll event that happens as a result of dimensions changing as this should\n // never cause a scrollLines call, only setScrollPosition can do that.\n this._suppressOnScrollHandler = true;\n this._scrollableElement.setScrollDimensions({\n height: this._renderService.dimensions.css.canvas.height,\n scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length\n });\n this._suppressOnScrollHandler = false;\n\n // If ydisp has been changed by some other component (input/buffer), then stop animating smooth\n // scroll and scroll there immediately.\n if (ydisp !== this._latestYDisp) {\n this._scrollableElement.setScrollPosition({\n scrollTop: ydisp * this._renderService.dimensions.css.cell.height\n });\n }\n\n this._isSyncing = false;\n }\n\n private _handleScroll(e: IScrollEvent): void {\n if (!this._renderService) {\n return;\n }\n if (this._isHandlingScroll || this._suppressOnScrollHandler) {\n return;\n }\n this._isHandlingScroll = true;\n const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);\n const diff = newRow - this._bufferService.buffer.ydisp;\n if (diff !== 0) {\n this._latestYDisp = newRow;\n this._onRequestScrollLines.fire(diff);\n }\n this._isHandlingScroll = false;\n }\n\n public handleTouchScroll(translationY: number): void {\n const pos = this._scrollableElement.getScrollPosition();\n this._scrollableElement.setScrollPosition({\n scrollTop: pos.scrollTop - translationY\n });\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ICoreBrowserService, IRenderService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';\n\nexport class BufferDecorationRenderer extends Disposable {\n private readonly _container: HTMLElement;\n private readonly _decorationElements: Map = new Map();\n\n private _animationFrame: number | undefined;\n private _altBufferIsActive: boolean = false;\n private _dimensionsChanged: boolean = false;\n\n constructor(\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n\n this._container = document.createElement('div');\n this._container.classList.add('xterm-decoration-container');\n this._screenElement.appendChild(this._container);\n\n this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));\n this._register(this._renderService.onDimensionsChange(() => {\n this._dimensionsChanged = true;\n this._queueRefresh();\n }));\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;\n }));\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));\n this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));\n this._register(toDisposable(() => {\n this._container.remove();\n this._decorationElements.clear();\n }));\n }\n\n private _queueRefresh(): void {\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._renderService.addRefreshCallback(() => {\n this._doRefreshDecorations();\n this._animationFrame = undefined;\n });\n }\n\n private _doRefreshDecorations(): void {\n for (const decoration of this._decorationService.decorations) {\n this._renderDecoration(decoration);\n }\n this._dimensionsChanged = false;\n }\n\n private _renderDecoration(decoration: IInternalDecoration): void {\n this._refreshStyle(decoration);\n if (this._dimensionsChanged) {\n this._refreshXPosition(decoration);\n }\n }\n\n private _createElement(decoration: IInternalDecoration): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.classList.add('xterm-decoration');\n element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n\n const x = decoration.options.x ?? 0;\n if (x && x > this._bufferService.cols) {\n // exceeded the container width, so hide\n element.style.display = 'none';\n }\n this._refreshXPosition(decoration, element);\n\n return element;\n }\n\n private _refreshStyle(decoration: IInternalDecoration): void {\n const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;\n if (line < 0 || line >= this._bufferService.rows) {\n // outside of viewport\n if (decoration.element) {\n decoration.element.style.display = 'none';\n decoration.onRenderEmitter.fire(decoration.element);\n }\n } else {\n let element = this._decorationElements.get(decoration);\n if (!element) {\n element = this._createElement(decoration);\n decoration.element = element;\n this._decorationElements.set(decoration, element);\n this._container.appendChild(element);\n decoration.onDispose(() => {\n this._decorationElements.delete(decoration);\n element!.remove();\n });\n }\n element.style.display = this._altBufferIsActive ? 'none' : 'block';\n if (!this._altBufferIsActive) {\n element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;\n element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;\n element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;\n }\n decoration.onRenderEmitter.fire(element);\n }\n }\n\n private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {\n if (!element) {\n return;\n }\n const x = decoration.options.x ?? 0;\n if ((decoration.options.anchor || 'left') === 'right') {\n element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n } else {\n element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';\n }\n }\n\n private _removeDecoration(decoration: IInternalDecoration): void {\n this._decorationElements.get(decoration)?.remove();\n this._decorationElements.delete(decoration);\n decoration.dispose();\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInternalDecoration } from '../../common/services/Services';\n\nexport interface IColorZoneStore {\n readonly zones: IColorZone[];\n clear(): void;\n addDecoration(decoration: IInternalDecoration): void;\n /**\n * Sets the amount of padding in lines that will be added between zones, if new lines intersect\n * the padding they will be merged into the same zone.\n */\n setPadding(padding: { [position: string]: number }): void;\n}\n\nexport interface IColorZone {\n /** Color in a format supported by canvas' fillStyle. */\n color: string;\n position: 'full' | 'left' | 'center' | 'right' | undefined;\n startBufferLine: number;\n endBufferLine: number;\n}\n\ninterface IMinimalDecorationForColorZone {\n marker: Pick;\n options: Pick;\n}\n\nexport class ColorZoneStore implements IColorZoneStore {\n private _zones: IColorZone[] = [];\n\n // The zone pool is used to keep zone objects from being freed between clearing the color zone\n // store and fetching the zones. This helps reduce GC pressure since the color zones are\n // accumulated on potentially every scroll event.\n private _zonePool: IColorZone[] = [];\n private _zonePoolIndex = 0;\n\n private _linePadding: { [position: string]: number } = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n };\n\n public get zones(): IColorZone[] {\n // Trim the zone pool to free unused memory\n this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);\n return this._zones;\n }\n\n public clear(): void {\n this._zones.length = 0;\n this._zonePoolIndex = 0;\n }\n\n public addDecoration(decoration: IMinimalDecorationForColorZone): void {\n if (!decoration.options.overviewRulerOptions) {\n return;\n }\n for (const z of this._zones) {\n if (z.color === decoration.options.overviewRulerOptions.color &&\n z.position === decoration.options.overviewRulerOptions.position) {\n if (this._lineIntersectsZone(z, decoration.marker.line)) {\n return;\n }\n if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {\n this._addLineToZone(z, decoration.marker.line);\n return;\n }\n }\n }\n // Create using zone pool if possible\n if (this._zonePoolIndex < this._zonePool.length) {\n this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;\n this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;\n this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;\n this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;\n this._zones.push(this._zonePool[this._zonePoolIndex++]);\n return;\n }\n // Create\n this._zones.push({\n color: decoration.options.overviewRulerOptions.color,\n position: decoration.options.overviewRulerOptions.position,\n startBufferLine: decoration.marker.line,\n endBufferLine: decoration.marker.line\n });\n this._zonePool.push(this._zones[this._zones.length - 1]);\n this._zonePoolIndex++;\n }\n\n public setPadding(padding: { [position: string]: number }): void {\n this._linePadding = padding;\n }\n\n private _lineIntersectsZone(zone: IColorZone, line: number): boolean {\n return (\n line >= zone.startBufferLine &&\n line <= zone.endBufferLine\n );\n }\n\n private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {\n return (\n (line >= zone.startBufferLine - this._linePadding[position || 'full']) &&\n (line <= zone.endBufferLine + this._linePadding[position || 'full'])\n );\n }\n\n private _addLineToZone(zone: IColorZone, line: number): void {\n zone.startBufferLine = Math.min(zone.startBufferLine, line);\n zone.endBufferLine = Math.max(zone.endBufferLine, line);\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';\nimport { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';\n\nconst enum Constants {\n OVERVIEW_RULER_BORDER_WIDTH = 1\n}\n\n// Helper objects to avoid excessive calculation and garbage collection during rendering. These are\n// static values for each render and can be accessed using the decoration position as the key.\nconst drawHeight = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawWidth = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\nconst drawX = {\n full: 0,\n left: 0,\n center: 0,\n right: 0\n};\n\nexport class OverviewRulerRenderer extends Disposable {\n private readonly _canvas: HTMLCanvasElement;\n private readonly _ctx: CanvasRenderingContext2D;\n private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();\n private get _width(): number {\n const scrollbar = this._optionsService.rawOptions.scrollbar;\n const showScrollbar = scrollbar?.showScrollbar ?? true;\n if (!showScrollbar) {\n return 0;\n }\n return scrollbar?.width ?? 0;\n }\n private _animationFrame: number | undefined;\n\n private _shouldUpdateDimensions: boolean | undefined = true;\n private _shouldUpdateAnchor: boolean | undefined = true;\n private _lastKnownBufferLength: number = 0;\n\n constructor(\n private readonly _viewportElement: HTMLElement,\n private readonly _screenElement: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IRenderService private readonly _renderService: IRenderService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IThemeService private readonly _themeService: IThemeService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');\n this._canvas.classList.add('xterm-decoration-overview-ruler');\n this._refreshCanvasDimensions();\n this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);\n this._register(toDisposable(() => this._canvas?.remove()));\n\n const ctx = this._canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Ctx cannot be null');\n } else {\n this._ctx = ctx;\n }\n\n this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));\n this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));\n\n this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';\n }));\n this._register(this._bufferService.onScroll(() => {\n if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {\n this._refreshDrawHeightConstants();\n this._refreshColorZonePadding();\n }\n }));\n\n this._register(this._renderService.onDimensionsChange(() => this._queueRefresh(true)));\n\n this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));\n this._register(this._optionsService.onSpecificOptionChange('scrollbar', () => this._queueRefresh(true)));\n this._register(this._themeService.onChangeColors(() => this._queueRefresh()));\n this._register(toDisposable(() => {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }));\n this._queueRefresh(true);\n }\n\n private _refreshDrawConstants(): void {\n // width\n const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);\n drawWidth.full = this._canvas.width;\n drawWidth.left = outerWidth;\n drawWidth.center = innerWidth;\n drawWidth.right = outerWidth;\n // height\n this._refreshDrawHeightConstants();\n // x\n drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;\n drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;\n drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;\n }\n\n private _refreshDrawHeightConstants(): void {\n drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);\n // Calculate actual pixels per line\n const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;\n // Clamp actual pixels within a range\n const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);\n drawHeight.left = nonFullHeight;\n drawHeight.center = nonFullHeight;\n drawHeight.right = nonFullHeight;\n }\n\n private _refreshColorZonePadding(): void {\n this._colorZoneStore.setPadding({\n full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),\n left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),\n center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),\n right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)\n });\n this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;\n }\n\n private _refreshCanvasDimensions(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n const cssCanvasHeight = this._renderService.dimensions.css.canvas.height;\n const deviceCanvasHeight = this._renderService.dimensions.device.canvas.height;\n this._canvas.style.width = `${this._width}px`;\n this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);\n this._canvas.style.height = `${cssCanvasHeight}px`;\n this._canvas.height = deviceCanvasHeight;\n this._refreshDrawConstants();\n this._refreshColorZonePadding();\n }\n\n private _refreshDecorations(): void {\n if (this._store.isDisposed || !this._renderService.hasRenderer()) {\n return;\n }\n if (this._shouldUpdateDimensions) {\n this._refreshCanvasDimensions();\n }\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._colorZoneStore.clear();\n for (const decoration of this._decorationService.decorations) {\n this._colorZoneStore.addDecoration(decoration);\n }\n this._ctx.lineWidth = 1;\n this._renderRulerOutline();\n const zones = this._colorZoneStore.zones;\n for (const zone of zones) {\n if (zone.position !== 'full') {\n this._renderColorZone(zone);\n }\n }\n for (const zone of zones) {\n if (zone.position === 'full') {\n this._renderColorZone(zone);\n }\n }\n this._shouldUpdateDimensions = false;\n this._shouldUpdateAnchor = false;\n }\n\n private _renderRulerOutline(): void {\n this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;\n this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showTopBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);\n }\n if (this._optionsService.rawOptions.scrollbar?.overviewRuler?.showBottomBorder) {\n this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);\n }\n }\n\n private _renderColorZone(zone: IColorZone): void {\n this._ctx.fillStyle = zone.color;\n this._ctx.fillRect(\n /* x */ drawX[zone.position || 'full'],\n /* y */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n (zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2\n ),\n /* w */ drawWidth[zone.position || 'full'],\n /* h */ Math.round(\n (this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line\n ((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']\n )\n );\n }\n\n private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {\n if (this._store.isDisposed) {\n return;\n }\n this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;\n this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;\n if (this._animationFrame !== undefined) {\n return;\n }\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {\n if (!this._store.isDisposed) {\n this._refreshDecorations();\n }\n this._animationFrame = undefined;\n });\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderService } from '../services/Services';\nimport { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';\nimport { C0 } from '../../common/data/EscapeSequences';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\ninterface IPendingComposition {\n transactionId: number;\n finalizerTimer?: ReturnType;\n lifecycleSettled: boolean;\n sessionEnded: boolean;\n position: IPosition;\n suffix: string;\n dataAlreadySent: string;\n compositionData: string;\n endData: string;\n inputData: string;\n keypressData: string;\n keypressMayOverlapComposition: boolean;\n expectsPostCompositionInput: boolean;\n nextCompositionStart?: number;\n}\n\nconst XTERM_COMPOSITION_SESSION_START_EVENT = 'xterm-composition-session-start';\nconst XTERM_COMPOSITION_SESSION_END_EVENT = 'xterm-composition-session-end';\nconst XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT =\n 'xterm-composition-transaction-accepted';\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private _isComposing: boolean;\n public get isComposing(): boolean { return this._isComposing; }\n public get hasPendingCompositionFinalization(): boolean {\n return this._pendingComposition !== undefined;\n }\n public get _isSendingComposition(): boolean {\n return this.hasPendingCompositionFinalization;\n }\n public get _pendingKeypressData(): string {\n return this._pendingComposition?.keypressData ?? '';\n }\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private _compositionPosition: IPosition;\n\n /**\n * Text that existed after the composing range when composition started.\n * This is used to avoid treating existing trailing text as new input.\n */\n private _compositionSuffix: string;\n\n /**\n * Data already sent due to keydown event.\n */\n private _dataAlreadySent: string;\n\n private _pendingComposition?: IPendingComposition;\n\n private _isAwaitingCompositionEnd: boolean;\n\n private _compositionInputData: string;\n\n private _lastCompositionData: string;\n\n private _compositionStartValue: string;\n\n private _compositionStartSelection: IPosition;\n\n private _compositionHasObservedProgress: boolean;\n\n private _canceledKey?: Pick;\n\n /**\n * The pending textarea change timer, if any.\n */\n private _textareaChangeTimer?: number;\n\n /**\n * Identifies the composition transaction that owns deferred work.\n */\n private _compositionTransactionId: number;\n\n /**\n * Timers that still own deferred composition state.\n */\n private _compositionTimers: Set>;\n\n private _compositionPositionTimer?: ReturnType;\n\n private _compositionViewTimer?: ReturnType;\n\n private _compositionEndTimer?: ReturnType;\n\n constructor(\n private readonly _textarea: HTMLTextAreaElement,\n private readonly _compositionView: HTMLElement,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreService private readonly _coreService: ICoreService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n this._isComposing = false;\n this._isAwaitingCompositionEnd = false;\n this._compositionPosition = { start: 0, end: 0 };\n this._compositionSuffix = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionStartValue = '';\n this._compositionStartSelection = { start: 0, end: 0 };\n this._compositionHasObservedProgress = false;\n this._compositionTransactionId = 0;\n this._compositionTimers = new Set();\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = undefined;\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = undefined;\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n // It's important to use the selection here instead of textarea length to avoid conflicts with\n // screen reader mode\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n this._compositionPosition.start = Math.min(start, end);\n this._compositionPosition.end = Math.max(start, end);\n this._compositionStartValue = this._textarea.value;\n this._compositionStartSelection = { start, end };\n this._compositionHasObservedProgress = false;\n if (this._pendingComposition) {\n this._pendingComposition.nextCompositionStart = this._compositionPosition.start;\n }\n this._compositionTransactionId++;\n this._isComposing = true;\n this._isAwaitingCompositionEnd = true;\n this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);\n this._compositionView.textContent = '';\n this._dataAlreadySent = '';\n this._compositionInputData = '';\n this._lastCompositionData = '';\n this._compositionView.classList.add('active');\n this._dispatchCompositionSessionEvent(new CustomEvent(XTERM_COMPOSITION_SESSION_START_EVENT, {\n bubbles: true,\n detail: { id: this._compositionTransactionId }\n }));\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param ev The event.\n */\n public compositionupdate(ev: Pick): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (ev.data?.length > 0) {\n this._lastCompositionData = ev.data;\n }\n // Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long\n // compositions\n this._compositionView.textContent = `\\u200E${ev.data ?? ''}\\u200E`;\n this.updateCompositionElements();\n const transactionId = this._compositionTransactionId;\n this._cancelDeferredTimer(this._compositionPositionTimer);\n this._compositionPositionTimer = this._defer(() => {\n if (this._isComposing && this._compositionTransactionId === transactionId) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n });\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(ev?: Pick): boolean {\n if (!this._isAwaitingCompositionEnd) {\n return false;\n }\n if (!this._isComposing) {\n const pending = this._pendingComposition;\n if (pending?.transactionId === this._compositionTransactionId) {\n pending.endData = ev?.data ?? '';\n this._updatePostCompositionInputExpectation(pending);\n }\n return false;\n }\n const endData = ev?.data ?? '';\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n if (!this._compositionEndBelongsToCurrentTransaction(endData)) {\n const pending = this._pendingComposition;\n if (pending && pending.transactionId !== this._compositionTransactionId) {\n this._sendPendingComposition(pending);\n }\n this._deferCompositionEnd(endData);\n return false;\n }\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n return true;\n }\n\n public blur(): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n this._compositionEndTimer = undefined;\n if (this._isComposing) {\n const end = this._textarea.selectionEnd ?? this._textarea.value.length;\n this._compositionPosition.end = Math.max(this._compositionPosition.start, end);\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n this._finalizeComposition(false);\n }\n }\n\n public dispose(): void {\n if (this._textareaChangeTimer !== undefined) {\n clearTimeout(this._textareaChangeTimer);\n this._textareaChangeTimer = undefined;\n }\n for (const timer of this._compositionTimers) {\n clearTimeout(timer);\n }\n this._compositionTimers.clear();\n this._compositionPositionTimer = undefined;\n this._compositionViewTimer = undefined;\n this._compositionEndTimer = undefined;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionTransactionId++;\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @returns Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this._canceledKey?.code === ev.code && this._canceledKey.timeStamp === ev.timeStamp) {\n this._canceledKey = undefined;\n return false;\n }\n if (ev.key === 'Escape' && (this._isComposing || this.hasPendingCompositionFinalization)) {\n this._canceledKey = { code: ev.code, timeStamp: ev.timeStamp };\n this._cancelComposition();\n return false;\n }\n if (this._isComposing || this.hasPendingCompositionFinalization) {\n if (ev.keyCode === 20 || ev.keyCode === 229) {\n // 20 is CapsLock, 229 is Enter\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n }\n if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n }\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this._finalizeComposition(false);\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this._handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Defers keypress text while a composition finalizer is pending so all input is emitted once\n * after reconciliation with the final textarea candidate.\n */\n public keypress(text: string): boolean {\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.keypressMayOverlapComposition) {\n pending.keypressData += text;\n return true;\n }\n if (pending.expectsPostCompositionInput && pending.keypressData.length === 0) {\n pending.keypressData = text;\n return true;\n }\n this._sendPendingComposition(pending);\n return false;\n }\n\n public input(text: string): boolean {\n if (this._isComposing) {\n this._compositionHasObservedProgress ||= this._hasCompositionProgress();\n this._compositionInputData += text;\n return true;\n }\n const pending = this._pendingComposition;\n if (!pending) {\n return false;\n }\n if (pending.expectsPostCompositionInput) {\n pending.inputData += text;\n pending.expectsPostCompositionInput = false;\n this._sendPendingComposition(pending);\n return true;\n }\n const repeatsPendingTextareaInput =\n text.length > 0 &&\n this._getPendingTextareaInput(pending) === text &&\n this._getPendingTextareaInput(pending, true) === text;\n this._sendPendingComposition(pending);\n if (!repeatsPendingTextareaInput) {\n this._coreService.triggerDataEvent(text, true);\n }\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropagation Whether to wait for events to propagate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is sent before\n * the command is executed.\n */\n private _finalizeComposition(waitForPropagation: boolean, endData: string = ''): void {\n const wasComposing = this._isComposing;\n this._compositionView.classList.remove('active');\n this._isComposing = false;\n if (waitForPropagation && !wasComposing) {\n return;\n }\n\n if (!waitForPropagation) {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition, true);\n }\n if (wasComposing) {\n const input = this._getCompositionInput(\n this._compositionPosition.start + this._dataAlreadySent.length,\n this._compositionSuffix\n );\n this._sendCompositionInput(this._compositionTransactionId, input);\n }\n } else {\n if (this._pendingComposition) {\n this._sendPendingComposition(this._pendingComposition);\n }\n const pending: IPendingComposition = {\n transactionId: this._compositionTransactionId,\n lifecycleSettled: false,\n sessionEnded: false,\n position: {\n start: this._compositionPosition.start,\n end: this._compositionPosition.end\n },\n suffix: this._compositionSuffix,\n dataAlreadySent: this._dataAlreadySent,\n compositionData: this._lastCompositionData,\n endData,\n inputData: this._compositionInputData,\n keypressData: '',\n keypressMayOverlapComposition:\n this._lastCompositionData.length === 0 && endData.length === 0,\n expectsPostCompositionInput: false\n };\n this._updatePostCompositionInputExpectation(pending);\n this._pendingComposition = pending;\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved.\n // This solution was used because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n pending.finalizerTimer = this._defer(() => {\n pending.finalizerTimer = undefined;\n if (this._compositionTransactionId === pending.transactionId) {\n this._isAwaitingCompositionEnd = false;\n }\n if (this._pendingComposition === pending) {\n this._sendPendingComposition(pending, true);\n }\n });\n }\n }\n\n private _sendPendingComposition(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): void {\n this._cancelPendingFinalizer(pending);\n if (this._pendingComposition === pending) {\n this._pendingComposition = undefined;\n }\n const textareaInput = this._getPendingTextareaInput(pending, includeFollowingInput);\n const observedInput = this._removeAlreadySentData(\n pending.inputData || pending.keypressData,\n pending.dataAlreadySent\n );\n // Why: with no textarea, end, input, or keypress evidence the composition\n // was cancelled (e.g. Backspace over the whole preedit); stale\n // compositionupdate data must not be replayed as committed text.\n const input = this._mergeTextObservations(\n textareaInput || pending.endData || (observedInput ? pending.compositionData : ''),\n observedInput,\n pending.keypressMayOverlapComposition\n );\n this._sendCompositionInput(pending.transactionId, input, !pending.sessionEnded);\n this._settlePendingComposition(pending);\n }\n\n private _cancelPendingFinalizer(pending: IPendingComposition): void {\n if (pending.finalizerTimer === undefined) {\n return;\n }\n clearTimeout(pending.finalizerTimer);\n this._compositionTimers.delete(pending.finalizerTimer);\n pending.finalizerTimer = undefined;\n }\n\n private _settlePendingComposition(pending: IPendingComposition): void {\n if (pending.lifecycleSettled) {\n return;\n }\n pending.lifecycleSettled = true;\n this._dispatchCompositionTransactionSettled();\n }\n\n private _mergeTextObservations(\n candidate: string,\n observed: string,\n findShortestOrder: boolean\n ): string {\n if (!observed || candidate.includes(observed)) {\n return candidate;\n }\n if (!candidate || observed.includes(candidate)) {\n return observed;\n }\n if (findShortestOrder) {\n let candidateFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n candidateFirstOverlap > 0 &&\n !candidate.endsWith(observed.substring(0, candidateFirstOverlap))\n ) {\n candidateFirstOverlap--;\n }\n let observedFirstOverlap = Math.min(candidate.length, observed.length);\n while (\n observedFirstOverlap > 0 &&\n !observed.endsWith(candidate.substring(0, observedFirstOverlap))\n ) {\n observedFirstOverlap--;\n }\n return candidateFirstOverlap > observedFirstOverlap\n ? candidate + observed.substring(candidateFirstOverlap)\n : observed + candidate.substring(observedFirstOverlap);\n }\n let overlap = Math.min(candidate.length, observed.length);\n while (overlap > 0 && !candidate.endsWith(observed.substring(0, overlap))) {\n overlap--;\n }\n return candidate + observed.substring(overlap);\n }\n\n private _updatePostCompositionInputExpectation(pending: IPendingComposition): void {\n pending.expectsPostCompositionInput =\n (pending.endData.length > 0 || pending.compositionData.length > 0) &&\n pending.inputData.length === 0 &&\n this._getPendingTextareaInput(pending).length === 0;\n }\n\n private _getPendingTextareaInput(\n pending: IPendingComposition,\n includeFollowingInput: boolean = false\n ): string {\n const value = this._textarea.value;\n const start = pending.position.start + pending.dataAlreadySent.length;\n if (pending.nextCompositionStart !== undefined) {\n return value.substring(start, Math.max(start, pending.nextCompositionStart));\n }\n const suffixEnd =\n pending.suffix.length > 0 && value.endsWith(pending.suffix)\n ? value.length - pending.suffix.length\n : value.length;\n const compositionLength = (pending.endData || pending.compositionData).length;\n const observedEnd = includeFollowingInput\n ? suffixEnd\n : Math.max(pending.position.end, start + compositionLength);\n return value.substring(start, Math.max(start, Math.min(suffixEnd, observedEnd)));\n }\n\n private _getCompositionInput(start: number, suffix: string): string {\n const value = this._textarea.value;\n const valueEnd =\n suffix.length > 0 && value.endsWith(suffix) ? value.length - suffix.length : value.length;\n return value.substring(start, Math.max(start, valueEnd));\n }\n\n private _removeAlreadySentData(input: string, dataAlreadySent: string): string {\n if (dataAlreadySent.length === 0) {\n return input;\n }\n if (input.startsWith(dataAlreadySent)) {\n return input.substring(dataAlreadySent.length);\n }\n return dataAlreadySent.includes(input) ? '' : input;\n }\n\n private _cancelComposition(): void {\n const pending = this._pendingComposition;\n if (\n pending &&\n this._isComposing &&\n pending.transactionId !== this._compositionTransactionId\n ) {\n this._sendPendingComposition(pending);\n }\n const transactionId = this._isComposing\n ? this._compositionTransactionId\n : this._pendingComposition?.transactionId ?? 0;\n const settlesPending = pending !== undefined && this._pendingComposition === pending;\n this._pendingComposition = undefined;\n this._isAwaitingCompositionEnd = false;\n this._isComposing = false;\n this._compositionView.classList.remove('active');\n this._textarea.value =\n this._textarea.value.substring(0, this._compositionPosition.start) + this._compositionSuffix;\n this._sendCompositionInput(transactionId, '');\n if (settlesPending && pending) {\n this._settlePendingComposition(pending);\n }\n }\n\n private _sendCompositionInput(\n transactionId: number,\n input: string,\n dispatchSessionEnd: boolean = true\n ): void {\n let prevented = false;\n if (dispatchSessionEnd) {\n const event = new CustomEvent(XTERM_COMPOSITION_SESSION_END_EVENT, {\n bubbles: true,\n cancelable: true,\n detail: { id: transactionId, data: input }\n });\n this._dispatchCompositionSessionEvent(event);\n prevented = event.defaultPrevented;\n }\n if (input.length > 0 && !prevented) {\n this._coreService.triggerDataEvent(input, true);\n }\n }\n\n private _endPendingCompositionSession(pending: IPendingComposition): void {\n if (pending.sessionEnded) {\n return;\n }\n pending.sessionEnded = true;\n const input =\n this._getPendingTextareaInput(pending) ||\n pending.endData ||\n pending.compositionData;\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_SESSION_END_EVENT,\n {\n bubbles: true,\n cancelable: true,\n detail: {\n id: pending.transactionId,\n data: input,\n dataPendingReconciliation: true\n }\n }\n ));\n }\n\n private _dispatchCompositionSessionEvent(event: CustomEvent): void {\n if (typeof this._textarea.dispatchEvent === 'function') {\n this._textarea.dispatchEvent(event);\n }\n }\n\n private _dispatchCompositionTransactionSettled(): void {\n this._dispatchCompositionSessionEvent(new CustomEvent(\n 'xterm-composition-transaction-settled',\n { bubbles: true }\n ));\n }\n\n private _deferCompositionEnd(endData: string): void {\n this._cancelDeferredTimer(this._compositionEndTimer);\n const transactionId = this._compositionTransactionId;\n const timer = this._defer(() => {\n if (\n this._compositionEndTimer !== timer ||\n !this._isComposing ||\n this._compositionTransactionId !== transactionId ||\n !this._compositionEndBelongsToCurrentTransaction(endData)\n ) {\n return;\n }\n this._compositionEndTimer = undefined;\n this._finalizeComposition(true, endData);\n this._dispatchCompositionSessionEvent(new CustomEvent(\n XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT,\n { bubbles: true }\n ));\n const pending = this._pendingComposition;\n if (pending?.transactionId === transactionId) {\n this._sendPendingComposition(pending, true);\n }\n });\n this._compositionEndTimer = timer;\n }\n\n private _hasCompositionProgress(): boolean {\n const start = this._textarea.selectionStart ?? this._textarea.value.length;\n const end = this._textarea.selectionEnd ?? start;\n return this._compositionHasObservedProgress || (\n this._textarea.value !== this._compositionStartValue ||\n start !== this._compositionStartSelection.start ||\n end !== this._compositionStartSelection.end\n );\n }\n\n private _compositionEndBelongsToCurrentTransaction(endData: string): boolean {\n return (\n this._hasCompositionProgress() ||\n (endData.length > 0 && endData === this._lastCompositionData)\n );\n }\n\n private _defer(callback: () => void): ReturnType {\n const timer = setTimeout(() => {\n this._compositionTimers.delete(timer);\n callback();\n }, 0);\n this._compositionTimers.add(timer);\n return timer;\n }\n\n private _cancelDeferredTimer(timer?: ReturnType): void {\n if (timer === undefined) {\n return;\n }\n clearTimeout(timer);\n this._compositionTimers.delete(timer);\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private _handleAnyTextareaChanges(): void {\n if (this._textareaChangeTimer) {\n return;\n }\n const oldValue = this._textarea.value;\n this._textareaChangeTimer = window.setTimeout(() => {\n this._textareaChangeTimer = undefined;\n // Ignore if a composition has started since the timeout\n if (!this._isComposing) {\n const newValue = this._textarea.value;\n\n const diff = newValue.replace(oldValue, '');\n\n this._dataAlreadySent = diff;\n\n if (newValue.length > oldValue.length) {\n this._coreService.triggerDataEvent(diff, true);\n } else if (newValue.length < oldValue.length) {\n this._coreService.triggerDataEvent(`${C0.DEL}`, true);\n } else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {\n this._coreService.triggerDataEvent(newValue, true);\n }\n\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this._isComposing) {\n return;\n }\n\n if (this._bufferService.buffer.isCursorInViewport) {\n const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);\n\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n this._compositionView.style.left = cursorLeft + 'px';\n this._compositionView.style.top = cursorTop + 'px';\n this._compositionView.style.height = cellHeight + 'px';\n this._compositionView.style.lineHeight = cellHeight + 'px';\n this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';\n // Limit the composition view width to the space between the cursor and\n // the terminal's right edge, preventing it from overflowing the terminal.\n const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;\n this._compositionView.style.maxWidth = maxWidth + 'px';\n this._compositionView.style.overflow = 'hidden';\n this._compositionView.style.direction = 'rtl';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this._compositionView.getBoundingClientRect();\n this._textarea.style.left = cursorLeft + 'px';\n this._textarea.style.top = cursorTop + 'px';\n // Ensure the text area is at least 1x1, otherwise certain IMEs may break\n this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';\n this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';\n this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n this._cancelDeferredTimer(this._compositionViewTimer);\n this._compositionViewTimer = this._defer(() => this.updateCompositionElements(true));\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { ICharacterJoiner } from '../Types';\nimport { AttributeData } from '../../common/buffer/AttributeData';\nimport { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService } from '../../common/services/Services';\nimport { ICharacterJoinerService } from './Services';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n private _width: number;\n // .content carries no meaning for joined CellData, simply nullify it\n // thus we have to overload all other .content accessors\n public content: number = 0;\n public fg: number;\n public bg: number;\n public combinedData: string = '';\n\n constructor(firstCell: ICellData, chars: string, width: number) {\n super();\n this.fg = firstCell.fg;\n this.bg = firstCell.bg;\n this.combinedData = chars;\n this._width = width;\n }\n\n public isCombined(): number {\n // always mark joined cell data as combined\n return Content.IS_COMBINED_MASK;\n }\n\n public getWidth(): number {\n return this._width;\n }\n\n public getChars(): string {\n return this.combinedData;\n }\n\n public getCode(): number {\n // code always gets the highest possible fake codepoint (read as -1)\n // this is needed as code is used by caches as identifier\n return 0x1FFFFF;\n }\n\n public setFromCharData(value: CharData): void {\n throw new Error('not implemented');\n }\n\n public getAsCharData(): CharData {\n return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n }\n}\n\nexport class CharacterJoinerService implements ICharacterJoinerService {\n public serviceBrand: undefined;\n\n private _characterJoiners: ICharacterJoiner[] = [];\n private _nextCharacterJoinerId: number = 0;\n private _workCell: CellData = new CellData();\n\n constructor(\n @IBufferService private _bufferService: IBufferService\n ) { }\n\n public register(handler: (text: string) => [number, number][]): number {\n const joiner: ICharacterJoiner = {\n id: this._nextCharacterJoinerId++,\n handler\n };\n\n this._characterJoiners.push(joiner);\n return joiner.id;\n }\n\n public deregister(joinerId: number): boolean {\n for (let i = 0; i < this._characterJoiners.length; i++) {\n if (this._characterJoiners[i].id === joinerId) {\n this._characterJoiners.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n public getJoinedCharacters(row: number): [number, number][] {\n if (this._characterJoiners.length === 0) {\n return [];\n }\n\n const line = this._bufferService.buffer.lines.get(row);\n if (!line || line.length === 0) {\n return [];\n }\n\n const ranges: [number, number][] = [];\n const lineStr = line.translateToString(true);\n const trimmedLength = line.getTrimmedLength();\n\n // Because some cells can be represented by multiple javascript characters,\n // we track the cell and the string indexes separately. This allows us to\n // translate the string ranges we get from the joiners back into cell ranges\n // for use when rendering\n let rangeStartColumn = 0;\n let currentStringIndex = 0;\n let rangeStartStringIndex = 0;\n let rangeAttrFG = line.getFg(0);\n let rangeAttrBG = line.getBg(0);\n\n for (let x = 0; x < trimmedLength; x++) {\n line.loadCell(x, this._workCell);\n\n if (this._workCell.getWidth() === 0) {\n // If this character is of width 0, skip it.\n continue;\n }\n\n // End of range\n if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n // If we ended up with a sequence of more than one character,\n // look for ranges to join.\n if (x - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n // Reset our markers for a new range.\n rangeStartColumn = x;\n rangeStartStringIndex = currentStringIndex;\n rangeAttrFG = this._workCell.fg;\n rangeAttrBG = this._workCell.bg;\n }\n\n currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n }\n\n // Process any trailing ranges.\n if (trimmedLength - rangeStartColumn > 1) {\n const joinedRanges = this._getJoinedRanges(\n lineStr,\n rangeStartStringIndex,\n currentStringIndex,\n line,\n rangeStartColumn\n );\n for (let i = 0; i < joinedRanges.length; i++) {\n ranges.push(joinedRanges[i]);\n }\n }\n\n return ranges;\n }\n\n /**\n * Given a segment of a line of text, find all ranges of text that should be\n * joined in a single rendering unit. Ranges are internally converted to\n * column ranges, rather than string ranges.\n * @param line String representation of the full line of text\n * @param startIndex Start position of the range to search in the string (inclusive)\n * @param endIndex End position of the range to search in the string (exclusive)\n */\n private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n const text = line.substring(startIndex, endIndex);\n // At this point we already know that there is at least one joiner so\n // we can just pull its value and assign it directly rather than\n // merging it into an empty array, which incurs unnecessary writes.\n let allJoinedRanges: [number, number][] = [];\n try {\n allJoinedRanges = this._characterJoiners[0].handler(text);\n } catch (error) {\n console.error(error);\n }\n for (let i = 1; i < this._characterJoiners.length; i++) {\n // We merge any overlapping ranges across the different joiners\n try {\n const joinerRanges = this._characterJoiners[i].handler(text);\n for (let j = 0; j < joinerRanges.length; j++) {\n CharacterJoinerService._mergeRanges(allJoinedRanges, joinerRanges[j]);\n }\n } catch (error) {\n console.error(error);\n }\n }\n this._stringRangesToCellRanges(allJoinedRanges, lineData, startCol);\n return allJoinedRanges;\n }\n\n /**\n * Modifies the provided ranges in-place to adjust for variations between\n * string length and cell width so that the range represents a cell range,\n * rather than the string range the joiner provides.\n * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n * @param line Cell data for the relevant line in the terminal\n * @param startCol Offset within the line to start from\n */\n private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n let currentRangeIndex = 0;\n let currentRangeStarted = false;\n let currentStringIndex = 0;\n let currentRange = ranges[currentRangeIndex];\n\n // If we got through all of the ranges, stop searching\n if (!currentRange) {\n return;\n }\n\n const trimmedLength = line.getTrimmedLength();\n for (let x = startCol; x < trimmedLength; x++) {\n const width = line.getWidth(x);\n const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n // We skip zero-width characters when creating the string to join the text\n // so we do the same here\n if (width === 0) {\n continue;\n }\n\n // Adjust the start of the range\n if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n }\n\n // Adjust the end of the range\n if (currentRange[1] <= currentStringIndex) {\n currentRange[1] = x;\n\n // We're finished with this range, so we move to the next one\n currentRange = ranges[++currentRangeIndex];\n\n // If there are no more ranges left, stop searching\n if (!currentRange) {\n break;\n }\n\n // Ranges can be on adjacent characters. Because the end index of the\n // ranges are exclusive, this means that the index for the start of a\n // range can be the same as the end index of the previous range. To\n // account for the start of the next range, we check here just in case.\n if (currentRange[0] <= currentStringIndex) {\n currentRange[0] = x;\n currentRangeStarted = true;\n } else {\n currentRangeStarted = false;\n }\n }\n\n // Adjust the string index based on the character length to line up with\n // the column adjustment\n currentStringIndex += length;\n }\n\n // If there is still a range left at the end, it must extend all the way to\n // the end of the line.\n if (currentRange) {\n currentRange[1] = trimmedLength;\n }\n }\n\n /**\n * Merges the range defined by the provided start and end into the list of\n * existing ranges. The merge is done in place on the existing range for\n * performance and is also returned.\n * @param ranges Existing range list\n * @param newRange Tuple of two numbers representing the new range to merge in.\n * @returns The ranges input with the new range merged in place\n */\n private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n let inRange = false;\n for (let i = 0; i < ranges.length; i++) {\n const range = ranges[i];\n if (!inRange) {\n if (newRange[1] <= range[0]) {\n // Case 1: New range is before the search range\n ranges.splice(i, 0, newRange);\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 2: New range is either wholly contained within the\n // search range or overlaps with the front of it\n range[0] = Math.min(newRange[0], range[0]);\n return ranges;\n }\n\n if (newRange[0] < range[1]) {\n // Case 3: New range either wholly contains the search range\n // or overlaps with the end of it\n range[0] = Math.min(newRange[0], range[0]);\n inRange = true;\n }\n\n // Case 4: New range starts after the search range\n continue;\n } else {\n if (newRange[1] <= range[0]) {\n // Case 5: New range extends from previous range but doesn't\n // reach the current one\n ranges[i - 1][1] = newRange[1];\n return ranges;\n }\n\n if (newRange[1] <= range[1]) {\n // Case 6: New range extends from prvious range into the\n // current range\n ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n ranges.splice(i, 1);\n return ranges;\n }\n\n // Case 7: New range extends from previous range past the\n // end of the current range\n ranges.splice(i, 1);\n i--;\n }\n }\n\n if (inRange) {\n // Case 8: New range extends past the last existing range\n ranges[ranges.length - 1][1] = newRange[1];\n } else {\n // Case 9: New range starts after the last existing range\n ranges.push(newRange);\n }\n\n return ranges;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDimensions, IRenderDimensions } from './Types';\n\nexport function throwIfFalsy(value: T | undefined | null): T {\n if (!value) {\n throw new Error('value must not be falsy');\n }\n return value;\n}\n\nexport function isPowerlineGlyph(codepoint: number): boolean {\n // Only return true for Powerline symbols which require\n // different padding and should be excluded from minimum contrast\n // ratio standards\n return 0xE0A4 <= codepoint && codepoint <= 0xE0D6;\n}\n\nexport function isRestrictedPowerlineGlyph(codepoint: number): boolean {\n return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;\n}\n\nfunction isNerdFontGlyph(codepoint: number): boolean {\n return 0xE000 <= codepoint && codepoint <= 0xF8FF;\n}\n\nfunction isBoxOrBlockGlyph(codepoint: number): boolean {\n return 0x2500 <= codepoint && codepoint <= 0x259F;\n}\n\nexport function isEmoji(codepoint: number): boolean {\n return (\n codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons\n codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs\n codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map\n codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols\n codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats\n codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors\n codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs\n codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF\n );\n}\n\nexport function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {\n return (\n // Is single cell width\n width === 1 &&\n // Glyph exceeds cell bounds, add 50% to avoid hurting readability by rescaling glyphs that\n // barely overlap\n glyphSizeX > Math.ceil(deviceCellWidth * 1.5) &&\n // Never rescale ascii\n codepoint !== undefined && codepoint > 0xFF &&\n // Never rescale emoji\n !isEmoji(codepoint) &&\n // Never rescale powerline or nerd fonts\n !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)\n );\n}\n\nexport function treatGlyphAsBackgroundColor(codepoint: number): boolean {\n return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);\n}\n\nexport function createRenderDimensions(): IRenderDimensions {\n return {\n css: {\n canvas: createDimension(),\n cell: createDimension()\n },\n device: {\n canvas: createDimension(),\n cell: createDimension(),\n char: {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }\n }\n };\n}\n\nfunction createDimension(): IDimensions {\n return {\n width: 0,\n height: 0\n };\n}\n\nexport function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {\n return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);\n}\n", "/**\n * Copyright (c) 2018, 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor } from '../../../common/Types';\nimport { IBufferLine, ICellData } from '../../../common/buffer/Types';\nimport { INVERTED_DEFAULT_COLOR } from '../shared/Constants';\nimport { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';\nimport { CellData } from '../../../common/buffer/CellData';\nimport { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';\nimport { channels, color } from '../../../common/Color';\nimport { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { JoinedCellData } from '../../services/CharacterJoinerService';\nimport { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';\nimport { AttributeData } from '../../../common/buffer/AttributeData';\nimport { WidthCache } from './WidthCache';\nimport { IColorContrastCache } from '../../Types';\n\n\nexport const enum RowCss {\n BOLD_CLASS = 'xterm-bold',\n DIM_CLASS = 'xterm-dim',\n ITALIC_CLASS = 'xterm-italic',\n UNDERLINE_CLASS = 'xterm-underline',\n OVERLINE_CLASS = 'xterm-overline',\n STRIKETHROUGH_CLASS = 'xterm-strikethrough',\n BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',\n CURSOR_CLASS = 'xterm-cursor',\n CURSOR_BLINK_CLASS = 'xterm-cursor-blink',\n CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',\n CURSOR_STYLE_OUTLINE_CLASS = 'xterm-cursor-outline',\n CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar',\n CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline'\n}\n\n\nexport class DomRendererRowFactory {\n private _workCell: CellData = new CellData();\n\n private _selectionStart: [number, number] | undefined;\n private _selectionEnd: [number, number] | undefined;\n private _columnSelectMode: boolean = false;\n\n public defaultSpacing = 0;\n\n constructor(\n private readonly _document: Document,\n @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService private readonly _decorationService: IDecorationService,\n @IThemeService private readonly _themeService: IThemeService\n ) {}\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionStart = start;\n this._selectionEnd = end;\n this._columnSelectMode = columnSelectMode;\n }\n\n public createRow(\n lineData: IBufferLine,\n row: number,\n isCursorRow: boolean,\n cursorStyle: string | undefined,\n cursorInactiveStyle: string | undefined,\n cursorX: number,\n cursorBlink: boolean,\n blinkOn: boolean,\n cellWidth: number,\n widthCache: WidthCache,\n linkStart: number,\n linkEnd: number,\n rowInfo?: { hasBlinkingCells: boolean }\n ): HTMLSpanElement[] {\n\n const elements: HTMLSpanElement[] = [];\n if (rowInfo) {\n rowInfo.hasBlinkingCells = false;\n }\n const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);\n const colors = this._themeService.colors;\n\n let lineLength = lineData.getNoBgTrimmedLength();\n if (isCursorRow && lineLength < cursorX + 1) {\n lineLength = cursorX + 1;\n }\n\n let charElement: HTMLSpanElement | undefined;\n let cellAmount = 0;\n let text = '';\n let i;\n let oldBg = 0;\n let oldFg = 0;\n let oldExt = 0;\n let oldLinkHover: number | boolean = false;\n let oldSpacing = 0;\n let oldIsInSelection: boolean = false;\n let spacing;\n let skipJoinedCheckUntilX = 0;\n const classes: string[] = [];\n\n const hasHover = linkStart !== -1 && linkEnd !== -1;\n\n for (let x = 0; x < lineLength; x++) {\n lineData.loadCell(x, this._workCell);\n let width = this._workCell.getWidth();\n\n // The character to the left is a wide character, drawing is owned by the char at x-1\n if (width === 0) {\n continue;\n }\n\n // If true, indicates that the current character(s) to draw were joined.\n let isJoined = false;\n\n // Indicates whether this cell is part of a joined range that should be ignored as it cannot\n // be rendered entirely, like the selection state differs across the range.\n let isValidJoinRange = (x >= skipJoinedCheckUntilX);\n\n let lastCharX = x;\n\n // Process any joined character ranges as needed. Because of how the\n // ranges are produced, we know that they are valid for the characters\n // and attributes of our input.\n let cell: ICellData = this._workCell;\n if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {\n const range = joinedRanges.shift()!;\n // If the ligature's selection state is not consistent, don't join it. This helps the\n // selection render correctly regardless whether they should be joined.\n const firstSelectionState = this._isCellInSelection(range[0], row);\n for (i = range[0] + 1; i < range[1]; i++) {\n isValidJoinRange &&= (firstSelectionState === this._isCellInSelection(i, row));\n }\n // Similarly, if the cursor is in the ligature, don't join it.\n isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];\n if (!isValidJoinRange) {\n skipJoinedCheckUntilX = range[1];\n } else {\n isJoined = true;\n\n // We already know the exact start and end column of the joined range,\n // so we get the string and width representing it directly\n cell = new JoinedCellData(\n this._workCell,\n lineData.translateToString(true, range[0], range[1]),\n range[1] - range[0]\n );\n\n // Skip over the cells occupied by this range in the loop\n lastCharX = range[1] - 1;\n\n // Recalculate width\n width = cell.getWidth();\n }\n }\n\n const isInSelection = this._isCellInSelection(x, row);\n const isCursorCell = isCursorRow && x === cursorX;\n const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;\n if (rowInfo && cell.isBlink()) {\n rowInfo.hasBlinkingCells = true;\n }\n const isBlinkHidden = !blinkOn && cell.isBlink();\n if (isBlinkHidden) {\n classes.push(RowCss.BLINK_HIDDEN_CLASS);\n }\n\n let isDecorated = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n isDecorated = true;\n });\n\n // get chars to render for this cell\n let chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n if (chars === ' ' && (cell.isUnderline() || cell.isOverline())) {\n chars = '\\xa0';\n }\n\n // lookup char render width and calc spacing\n spacing = width * cellWidth - widthCache.get(chars, cell.isBold(), cell.isItalic());\n\n if (!charElement) {\n charElement = this._document.createElement('span');\n } else {\n /**\n * chars can only be merged on existing span if:\n * - existing span only contains mergeable chars (cellAmount != 0)\n * - bg did not change (or both are in selection)\n * - fg did not change (or both are in selection and selection fg is set)\n * - ext did not change\n * - underline from hover state did not change\n * - cell content renders to same letter-spacing\n * - cell is not cursor\n */\n if (\n cellAmount\n && (\n (isInSelection && oldIsInSelection)\n || (!isInSelection && !oldIsInSelection && cell.bg === oldBg)\n )\n && (\n (isInSelection && oldIsInSelection && colors.selectionForeground)\n || cell.fg === oldFg\n )\n && cell.extended.ext === oldExt\n && isLinkHover === oldLinkHover\n && spacing === oldSpacing\n && !isCursorCell\n && !isJoined\n && !isDecorated\n && isValidJoinRange\n ) {\n // no span alterations, thus only account chars skipping all code below\n if (cell.isInvisible()) {\n text += WHITESPACE_CELL_CHAR;\n } else {\n text += chars;\n }\n cellAmount++;\n continue;\n } else {\n /**\n * cannot merge:\n * - apply left-over text to old span\n * - create new span, reset state holders cellAmount & text\n */\n if (cellAmount) {\n charElement.textContent = text;\n }\n charElement = this._document.createElement('span');\n cellAmount = 0;\n text = '';\n }\n }\n // preserve conditions for next merger eval round\n oldBg = cell.bg;\n oldFg = cell.fg;\n oldExt = cell.extended.ext;\n oldLinkHover = isLinkHover;\n oldSpacing = spacing;\n oldIsInSelection = isInSelection;\n\n if (isJoined) {\n // The DOM renderer colors the background of the cursor but for ligatures all cells are\n // joined. The workaround here is to show a cursor around the whole ligature so it shows up,\n // the cursor looks the same when on any character of the ligature though\n if (cursorX >= x && cursorX <= lastCharX) {\n cursorX = x;\n }\n }\n\n if (!this._coreService.isCursorHidden && isCursorCell && this._coreService.isCursorInitialized) {\n classes.push(RowCss.CURSOR_CLASS);\n if (this._coreBrowserService.isFocused) {\n if (cursorBlink) {\n classes.push(RowCss.CURSOR_BLINK_CLASS);\n }\n classes.push(\n cursorStyle === 'bar'\n ? RowCss.CURSOR_STYLE_BAR_CLASS\n : cursorStyle === 'underline'\n ? RowCss.CURSOR_STYLE_UNDERLINE_CLASS\n : RowCss.CURSOR_STYLE_BLOCK_CLASS\n );\n } else {\n if (cursorInactiveStyle) {\n switch (cursorInactiveStyle) {\n case 'outline':\n classes.push(RowCss.CURSOR_STYLE_OUTLINE_CLASS);\n break;\n case 'block':\n classes.push(RowCss.CURSOR_STYLE_BLOCK_CLASS);\n break;\n case 'bar':\n classes.push(RowCss.CURSOR_STYLE_BAR_CLASS);\n break;\n case 'underline':\n classes.push(RowCss.CURSOR_STYLE_UNDERLINE_CLASS);\n break;\n default:\n break;\n }\n }\n }\n }\n\n if (cell.isBold()) {\n classes.push(RowCss.BOLD_CLASS);\n }\n\n if (cell.isItalic()) {\n classes.push(RowCss.ITALIC_CLASS);\n }\n\n if (cell.isDim()) {\n classes.push(RowCss.DIM_CLASS);\n }\n\n if (cell.isInvisible()) {\n text = WHITESPACE_CELL_CHAR;\n } else {\n text = cell.getChars() || WHITESPACE_CELL_CHAR;\n }\n\n if (cell.isUnderline()) {\n classes.push(`${RowCss.UNDERLINE_CLASS}-${cell.extended.underlineStyle}`);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n if (!cell.isUnderlineColorDefault()) {\n if (cell.isUnderlineColorRGB()) {\n charElement.style.textDecorationColor = `rgb(${AttributeData.toColorRGB(cell.getUnderlineColor()).join(',')})`;\n } else {\n let fg = cell.getUnderlineColor();\n if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n fg += 8;\n }\n charElement.style.textDecorationColor = colors.ansi[fg].css;\n }\n }\n }\n\n if (cell.isOverline()) {\n classes.push(RowCss.OVERLINE_CLASS);\n if (text === ' ') {\n text = '\\xa0'; // =  \n }\n }\n\n if (cell.isStrikethrough()) {\n classes.push(RowCss.STRIKETHROUGH_CLASS);\n }\n\n // apply link hover underline late, effectively overrides any previous text-decoration\n // settings\n if (isLinkHover) {\n charElement.style.textDecoration = 'underline';\n }\n\n let fg = cell.getFgColor();\n let fgColorMode = cell.getFgColorMode();\n let bg = cell.getBgColor();\n let bgColorMode = cell.getBgColorMode();\n const isInverse = !!cell.isInverse();\n if (isInverse) {\n const temp = fg;\n fg = bg;\n bg = temp;\n const temp2 = fgColorMode;\n fgColorMode = bgColorMode;\n bgColorMode = temp2;\n }\n\n // Apply any decoration foreground/background overrides, this must happen after inverse has\n // been applied\n let bgOverride: IColor | undefined;\n let fgOverride: IColor | undefined;\n let isTop = false;\n this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {\n if (d.options.layer !== 'top' && isTop) {\n return;\n }\n if (d.backgroundColorRGB) {\n bgColorMode = Attributes.CM_RGB;\n bg = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF;\n bgOverride = d.backgroundColorRGB;\n }\n if (d.foregroundColorRGB) {\n fgColorMode = Attributes.CM_RGB;\n fg = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF;\n fgOverride = d.foregroundColorRGB;\n }\n isTop = d.options.layer === 'top';\n });\n\n // Apply selection\n if (!isTop && isInSelection) {\n // If in the selection, force the element to be above the selection to improve contrast and\n // support opaque selections. The applies background is not actually needed here as\n // selection is drawn in a seperate container, the main purpose of this to ensuring minimum\n // contrast ratio\n bgOverride = this._coreBrowserService.isFocused ? colors.selectionBackgroundOpaque : colors.selectionInactiveBackgroundOpaque;\n bg = bgOverride.rgba >> 8 & 0xFFFFFF;\n bgColorMode = Attributes.CM_RGB;\n // Since an opaque selection is being rendered, the selection pretends to be a decoration to\n // ensure text is drawn above the selection.\n isTop = true;\n // Apply selection foreground if applicable\n if (colors.selectionForeground) {\n fgColorMode = Attributes.CM_RGB;\n fg = colors.selectionForeground.rgba >> 8 & 0xFFFFFF;\n fgOverride = colors.selectionForeground;\n }\n }\n\n // If it's a top decoration, render above the selection\n if (isTop) {\n classes.push('xterm-decoration-top');\n }\n\n // Background\n let resolvedBg: IColor;\n switch (bgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n resolvedBg = colors.ansi[bg];\n classes.push(`xterm-bg-${bg}`);\n break;\n case Attributes.CM_RGB:\n resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);\n this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (isInverse) {\n resolvedBg = colors.foreground;\n classes.push(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n } else {\n resolvedBg = colors.background;\n }\n }\n\n // If there is no background override by now it's the original color, so apply dim if needed\n if (!bgOverride) {\n if (cell.isDim()) {\n bgOverride = color.multiplyOpacity(resolvedBg, 0.5);\n }\n }\n\n // Foreground\n switch (fgColorMode) {\n case Attributes.CM_P16:\n case Attributes.CM_P256:\n if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {\n fg += 8;\n }\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.ansi[fg], cell, bgOverride, undefined)) {\n classes.push(`xterm-fg-${fg}`);\n }\n break;\n case Attributes.CM_RGB:\n const color = channels.toColor(\n (fg >> 16) & 0xFF,\n (fg >> 8) & 0xFF,\n (fg ) & 0xFF\n );\n if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {\n this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);\n }\n break;\n case Attributes.CM_DEFAULT:\n default:\n if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {\n if (isInverse) {\n classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n }\n }\n }\n\n // apply CSS classes\n // slightly faster than using classList by omitting\n // checks for doubled entries (code above should not have doublets)\n if (classes.length) {\n charElement.className = classes.join(' ');\n classes.length = 0;\n }\n\n // exclude conditions for cell merging - never merge these\n if (!isCursorCell && !isJoined && !isDecorated && isValidJoinRange) {\n cellAmount++;\n } else {\n charElement.textContent = text;\n }\n // apply letter-spacing rule\n if (spacing !== this.defaultSpacing) {\n charElement.style.letterSpacing = `${spacing}px`;\n }\n\n elements.push(charElement);\n x = lastCharX;\n }\n\n // postfix text of last merged span\n if (charElement && cellAmount) {\n charElement.textContent = text;\n }\n\n return elements;\n }\n\n private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {\n if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {\n return false;\n }\n\n // Try get from cache first, only use the cache when there are no decoration overrides\n const cache = this._getContrastCache(cell);\n let adjustedColor: IColor | undefined | null = undefined;\n if (!bgOverride && !fgOverride) {\n adjustedColor = cache.getColor(bg.rgba, fg.rgba);\n }\n\n // Calculate and store in cache\n if (adjustedColor === undefined) {\n // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from\n // non-dim cells\n const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);\n adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);\n cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);\n }\n\n if (adjustedColor) {\n this._addStyle(element, `color:${adjustedColor.css}`);\n return true;\n }\n\n return false;\n }\n\n private _getContrastCache(cell: ICellData): IColorContrastCache {\n if (cell.isDim()) {\n return this._themeService.colors.halfContrastCache;\n }\n return this._themeService.colors.contrastCache;\n }\n\n private _addStyle(element: HTMLElement, style: string): void {\n element.setAttribute('style', `${element.getAttribute('style') || ''}${style};`);\n }\n\n private _isCellInSelection(x: number, y: number): boolean {\n const start = this._selectionStart;\n const end = this._selectionEnd;\n if (!start || !end) {\n return false;\n }\n if (this._columnSelectMode) {\n if (start[0] <= end[0]) {\n return x >= start[0] && y >= start[1] &&\n x < end[0] && y <= end[1];\n }\n return x < start[0] && y >= start[1] &&\n x >= end[0] && y <= end[1];\n }\n return (y > start[1] && y < end[1]) ||\n (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||\n (start[1] < end[1] && y === end[1] && x < end[0]) ||\n (start[1] < end[1] && y === start[1] && x >= start[0]);\n }\n}\n", "/**\n * Copyright (c) 2023 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { throwIfFalsy } from '../shared/RendererUtils';\nimport { IDisposable } from '../../../common/Types';\nimport { FontWeight } from '../../../common/services/Services';\n\n\nexport const enum WidthCacheSettings {\n /** sentinel for unset values in flat cache */\n FLAT_UNSET = -9999,\n /** size of flat cache, size-1 equals highest codepoint handled by flat */\n FLAT_SIZE = 256,\n /** char repeat for measuring */\n REPEAT = 32\n}\n\n\nconst enum FontVariant {\n REGULAR = 0,\n BOLD = 1,\n ITALIC = 2,\n BOLD_ITALIC = 3\n}\n\nexport interface IWidthCacheFontVariantCanvas {\n setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;\n measure(c: string): number;\n}\n\nexport class WidthCache implements IDisposable {\n // flat cache for regular variant up to CacheSettings.FLAT_SIZE\n // NOTE: ~4x faster access than holey (serving >>80% of terminal content)\n // It has a small memory footprint (only 1MB for full BMP caching),\n // still the sweet spot is not reached before touching 32k different codepoints,\n // thus we store the remaining <<20% of terminal data in a holey structure.\n protected _flat = new Float32Array(WidthCacheSettings.FLAT_SIZE);\n\n // holey cache for bold, italic and bold&italic for any string\n // FIXME: can grow really big over time (~8.5 MB for full BMP caching),\n // so a shared API across terminals is needed\n protected _holey: Map | undefined;\n\n private _font = '';\n private _fontSize = 0;\n private _weight: FontWeight = 'normal';\n private _weightBold: FontWeight = 'bold';\n private _canvasElements: IWidthCacheFontVariantCanvas[] = [];\n\n constructor(\n canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()\n ) {\n this._canvasElements = [\n canvasFactory(),\n canvasFactory(),\n canvasFactory(),\n canvasFactory()\n ];\n\n this.clear();\n }\n\n public dispose(): void {\n this._canvasElements.length = 0;\n this._holey = undefined; // free cache memory via GC\n }\n\n /**\n * Clear the width cache.\n */\n public clear(): void {\n this._flat.fill(WidthCacheSettings.FLAT_UNSET);\n // .clear() has some overhead, re-assign instead (>3 times faster)\n this._holey = new Map();\n }\n\n /**\n * Set the font for measuring.\n * Must be called for any changes on font settings.\n * Also clears the cache.\n */\n public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {\n // skip if nothing changed\n if (\n font === this._font &&\n fontSize === this._fontSize &&\n weight === this._weight &&\n weightBold === this._weightBold\n ) {\n return;\n }\n\n this._font = font;\n this._fontSize = fontSize;\n this._weight = weight;\n this._weightBold = weightBold;\n\n this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);\n this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);\n this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);\n this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);\n\n this.clear();\n }\n\n /**\n * Get the render width for cell content `c` with current font settings.\n * `variant` denotes the font variant to be used.\n */\n public get(c: string, bold: boolean | number, italic: boolean | number): number {\n let cp: number;\n if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {\n if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {\n return this._flat[cp];\n }\n const width = this._measure(c, 0);\n if (width > 0) {\n this._flat[cp] = width;\n }\n return width;\n }\n let key = c;\n if (bold) key += 'B';\n if (italic) key += 'I';\n let width = this._holey!.get(key);\n if (width === undefined) {\n let variant = 0;\n if (bold) variant |= FontVariant.BOLD;\n if (italic) variant |= FontVariant.ITALIC;\n width = this._measure(c, variant);\n if (width > 0) {\n this._holey!.set(key, width);\n }\n }\n return width;\n }\n\n protected _measure(c: string, variant: FontVariant): number {\n return this._canvasElements[variant].measure(c);\n }\n}\n\nclass WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {\n private _canvas: OffscreenCanvas | HTMLCanvasElement;\n private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\n constructor() {\n if (typeof OffscreenCanvas !== 'undefined') {\n this._canvas = new OffscreenCanvas(1, 1);\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n } else {\n this._canvas = document.createElement('canvas');\n this._canvas.width = 1;\n this._canvas.height = 1;\n this._ctx = throwIfFalsy(this._canvas.getContext('2d'));\n }\n }\n\n public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {\n const fontStyle = italic ? 'italic' : '';\n this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();\n }\n\n public measure(c: string): number {\n return this._ctx.measureText(c).width;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { ISelectionRenderModel } from './Types';\nimport { Terminal } from '@xterm/xterm';\n\nclass SelectionRenderModel implements ISelectionRenderModel {\n public hasSelection!: boolean;\n public columnSelectMode!: boolean;\n public viewportStartRow!: number;\n public viewportEndRow!: number;\n public viewportCappedStartRow!: number;\n public viewportCappedEndRow!: number;\n public startCol!: number;\n public endCol!: number;\n public selectionStart: [number, number] | undefined;\n public selectionEnd: [number, number] | undefined;\n\n constructor() {\n this.clear();\n }\n\n public clear(): void {\n this.hasSelection = false;\n this.columnSelectMode = false;\n this.viewportStartRow = 0;\n this.viewportEndRow = 0;\n this.viewportCappedStartRow = 0;\n this.viewportCappedEndRow = 0;\n this.startCol = 0;\n this.endCol = 0;\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n }\n\n public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {\n this.selectionStart = start;\n this.selectionEnd = end;\n // Selection does not exist\n if (!start || !end || (start[0] === end[0] && start[1] === end[1])) {\n this.clear();\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportY = terminal.buffers.active.ydisp;\n const viewportStartRow = start[1] - viewportY;\n const viewportEndRow = end[1] - viewportY;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n this.clear();\n return;\n }\n\n this.hasSelection = true;\n this.columnSelectMode = columnSelectMode;\n this.viewportStartRow = viewportStartRow;\n this.viewportEndRow = viewportEndRow;\n this.viewportCappedStartRow = viewportCappedStartRow;\n this.viewportCappedEndRow = viewportCappedEndRow;\n this.startCol = start[0];\n this.endCol = end[0];\n }\n\n public isCellSelected(terminal: Terminal, x: number, y: number): boolean {\n if (!this.hasSelection) {\n return false;\n }\n y -= terminal.buffer.active.viewportY;\n if (this.columnSelectMode) {\n if (this.startCol <= this.endCol) {\n return x >= this.startCol && y >= this.viewportCappedStartRow &&\n x < this.endCol && y <= this.viewportCappedEndRow;\n }\n return x < this.startCol && y >= this.viewportCappedStartRow &&\n x >= this.endCol && y <= this.viewportCappedEndRow;\n }\n return (y > this.viewportStartRow && y < this.viewportEndRow) ||\n (this.viewportStartRow === this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportEndRow && x < this.endCol) ||\n (this.viewportStartRow < this.viewportEndRow && y === this.viewportStartRow && x >= this.startCol);\n }\n}\n\nexport function createSelectionRenderModel(): ISelectionRenderModel {\n return new SelectionRenderModel();\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from '../../services/Services';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IOptionsService } from '../../../common/services/Services';\n\nexport class TextBlinkStateManager extends Disposable {\n private _intervalDuration: number = 0;\n private _interval: number | undefined;\n private _blinkOn: boolean = true;\n private _needsBlinkInViewport: boolean = false;\n private _isViewportVisible: boolean = true;\n\n constructor(\n private readonly _renderCallback: () => void,\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _optionsService: IOptionsService\n ) {\n super();\n this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {\n this.setIntervalDuration(duration);\n }));\n this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);\n this._register(toDisposable(() => this._clearInterval()));\n }\n\n public get isBlinkOn(): boolean {\n return this._blinkOn;\n }\n\n public get isEnabled(): boolean {\n return this._intervalDuration > 0;\n }\n\n public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {\n if (this._needsBlinkInViewport === needsBlinkInViewport) {\n return;\n }\n\n this._needsBlinkInViewport = needsBlinkInViewport;\n this._updateIntervalState();\n }\n\n public setViewportVisible(isVisible: boolean): void {\n if (this._isViewportVisible === isVisible) {\n return;\n }\n\n this._isViewportVisible = isVisible;\n this._updateIntervalState();\n }\n\n public setIntervalDuration(duration: number): void {\n if (duration === this._intervalDuration) {\n return;\n }\n\n this._intervalDuration = duration;\n this._clearInterval();\n this._updateIntervalState();\n }\n\n private _updateIntervalState(): void {\n const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;\n if (shouldBlink) {\n if (this._interval !== undefined) {\n return;\n }\n const wasBlinkOn = this._blinkOn;\n this._blinkOn = true;\n this._interval = this._coreBrowserService.window.setInterval(() => {\n this._blinkOn = !this._blinkOn;\n this._renderCallback();\n }, this._intervalDuration);\n if (!wasBlinkOn) {\n this._renderCallback();\n }\n return;\n }\n\n this._clearInterval();\n if (!this._blinkOn) {\n this._blinkOn = true;\n this._renderCallback();\n }\n }\n\n private _clearInterval(): void {\n if (this._interval !== undefined) {\n this._coreBrowserService.window.clearInterval(this._interval);\n this._interval = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';\nimport { WidthCache } from './WidthCache';\nimport { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';\nimport { createRenderDimensions } from '../shared/RendererUtils';\nimport { createSelectionRenderModel } from '../shared/SelectionRenderModel';\nimport { TextBlinkStateManager } from '../shared/TextBlinkStateManager';\nimport { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';\nimport { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';\nimport { color } from '../../../common/Color';\nimport { Disposable, toDisposable } from '../../../common/Lifecycle';\nimport { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';\nimport { Emitter } from '../../../common/Event';\nimport { addDisposableListener } from '../../Dom';\n\n\nconst enum Constants {\n TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',\n ROW_CONTAINER_CLASS = 'xterm-rows',\n FG_CLASS_PREFIX = 'xterm-fg-',\n BG_CLASS_PREFIX = 'xterm-bg-',\n FOCUS_CLASS = 'xterm-focus',\n SELECTION_CLASS = 'xterm-selection',\n CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'\n}\n\nlet nextTerminalId = 1;\n\n/**\n * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be\n * particularly fast and will even lack some features such as custom glyphs, hoever this is more\n * reliable as webgl may not work on some machines.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n private _rowFactory: DomRendererRowFactory;\n private _terminalClass: number = nextTerminalId++;\n\n private _themeStyleElement!: HTMLStyleElement;\n private _dimensionsStyleElement!: HTMLStyleElement;\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[] = [];\n private _selectionContainer: HTMLElement;\n private _widthCache: WidthCache;\n private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();\n private _lastSelectionStart: [number, number] | undefined;\n private _lastSelectionEnd: [number, number] | undefined;\n private _lastSelectionColumnMode: boolean = false;\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _textBlinkStateManager: TextBlinkStateManager;\n private _rowHasBlinkingCells: boolean[] = [];\n private _rowHasBlinkingCellsCount: number = 0;\n\n public dimensions: IRenderDimensions;\n\n private readonly _onRequestRedraw = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRequestRedraw.event;\n\n constructor(\n private readonly _terminal: ITerminal,\n private readonly _document: Document,\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _viewportElement: HTMLElement,\n private readonly _helperContainer: HTMLElement,\n private readonly _linkifier2: ILinkifier2,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService private readonly _themeService: IThemeService\n ) {\n super();\n this._rowContainer = this._document.createElement('div');\n this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);\n this._rowContainer.style.lineHeight = 'normal';\n this._rowContainer.setAttribute('aria-hidden', 'true');\n this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);\n this._selectionContainer = this._document.createElement('div');\n this._selectionContainer.classList.add(Constants.SELECTION_CLASS);\n this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n this.dimensions = createRenderDimensions();\n this._updateDimensions();\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n\n this._register(this._themeService.onChangeColors(e => this._injectCss(e)));\n this._injectCss(this._themeService.colors);\n\n this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);\n\n this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n this._screenElement.appendChild(this._rowContainer);\n this._screenElement.appendChild(this._selectionContainer);\n\n this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));\n this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));\n\n this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);\n this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));\n this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));\n this._textBlinkStateManager = this._register(new TextBlinkStateManager(\n () => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),\n this._coreBrowserService,\n this._optionsService\n ));\n\n this._register(toDisposable(() => {\n this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);\n\n // Outside influences such as React unmounts may manipulate the DOM before our disposal.\n // https://github.com/xtermjs/xterm.js/issues/2960\n this._rowContainer.remove();\n this._selectionContainer.remove();\n this._widthCache.dispose();\n this._themeStyleElement.remove();\n this._dimensionsStyleElement.remove();\n }));\n\n this._widthCache = new WidthCache();\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n private _updateDimensions(): void {\n const dpr = this._coreBrowserService.dpr;\n this.dimensions.device.char.width = this._charSizeService.width * dpr;\n this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);\n this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);\n this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);\n this.dimensions.device.char.left = 0;\n this.dimensions.device.char.top = 0;\n this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;\n this.dimensions.device.canvas.height = this.dimensions.device.cell.height * this._bufferService.rows;\n this.dimensions.css.canvas.width = Math.round(this.dimensions.device.canvas.width / dpr);\n this.dimensions.css.canvas.height = Math.round(this.dimensions.device.canvas.height / dpr);\n this.dimensions.css.cell.width = this.dimensions.css.canvas.width / this._bufferService.cols;\n this.dimensions.css.cell.height = this.dimensions.css.canvas.height / this._bufferService.rows;\n\n for (const element of this._rowElements) {\n element.style.width = `${this.dimensions.css.canvas.width}px`;\n element.style.height = `${this.dimensions.css.cell.height}px`;\n element.style.lineHeight = `${this.dimensions.css.cell.height}px`;\n // Make sure rows don't overflow onto following row\n element.style.overflow = 'hidden';\n }\n\n if (!this._dimensionsStyleElement) {\n this._dimensionsStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._dimensionsStyleElement);\n }\n\n const styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)\n ` height: 100%;` +\n ` vertical-align: top;` +\n `}`;\n\n this._dimensionsStyleElement.textContent = styles;\n\n this._selectionContainer.style.height = this._viewportElement.style.height;\n this._screenElement.style.width = `${this.dimensions.css.canvas.width}px`;\n this._screenElement.style.height = `${this.dimensions.css.canvas.height}px`;\n }\n\n private _injectCss(colors: ReadonlyColorSet): void {\n if (!this._themeStyleElement) {\n this._themeStyleElement = this._document.createElement('style');\n this._screenElement.appendChild(this._themeStyleElement);\n }\n\n // Base CSS\n let styles =\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +\n // Disabling pointer events circumvents a browser behavior that prevents `click` events from\n // being delivered if the target element is replaced during the click. This happened due to\n // refresh() being called during the mousedown handler to start a selection.\n ` pointer-events: none;` +\n ` color: ${colors.foreground.css};` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +\n ` font-family: ${this._optionsService.rawOptions.fontFamily};` +\n ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +\n ` font-kerning: none;` +\n ` white-space: pre` +\n `}`;\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +\n ` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +\n `}`;\n // Text styles\n styles +=\n `${this._terminalSelector} span:not(.${RowCss.BOLD_CLASS}) {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeight};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BOLD_CLASS} {` +\n ` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +\n `}` +\n `${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +\n ` font-style: italic;` +\n `}` +\n `${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +\n ` visibility: hidden;` +\n `}`;\n // Blink animation\n const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;\n const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;\n const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;\n styles +=\n `@keyframes ${blinkAnimationUnderlineId} {` +\n ` 50% {` +\n ` border-bottom-style: hidden;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBarId} {` +\n ` 50% {` +\n ` box-shadow: none;` +\n ` }` +\n `}`;\n styles +=\n `@keyframes ${blinkAnimationBlockId} {` +\n ` 0% {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n ` }` +\n ` 50% {` +\n ` background-color: inherit;` +\n ` color: ${colors.cursor.css};` +\n ` }` +\n `}`;\n // Cursor\n styles +=\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +\n `}` +\n // Disable cursor blinking when idle\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +\n ` animation: none !important;` +\n `}` +\n // !important helps fix an issue where the cursor will not render on top of the selection,\n // however it's very hard to fix this issue and retain the blink animation without the use of\n // !important. So this edge case fails when cursor blink is on.\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +\n ` background-color: ${colors.cursor.css};` +\n ` color: ${colors.cursorAccent.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +\n ` background-color: ${colors.cursor.css} !important;` +\n ` color: ${colors.cursorAccent.css} !important;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +\n ` outline: 1px solid ${colors.cursor.css};` +\n ` outline-offset: -1px;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +\n ` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +\n `}` +\n `${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +\n ` border-bottom: 1px ${colors.cursor.css};` +\n ` border-bottom-style: solid;` +\n ` height: calc(100% - 1px);` +\n `}`;\n // Selection\n styles +=\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +\n ` position: absolute;` +\n ` top: 0;` +\n ` left: 0;` +\n ` z-index: 1;` +\n ` pointer-events: none;` +\n `}` +\n `${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionBackgroundOpaque.css};` +\n `}` +\n `${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +\n ` position: absolute;` +\n ` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +\n `}`;\n // Colors\n for (const [i, c] of colors.ansi.entries()) {\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n }\n styles +=\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +\n `${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +\n `${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;\n\n this._themeStyleElement.textContent = styles;\n }\n\n /**\n * default letter spacing\n * Due to rounding issues in dimensions dpr calc glyph might render\n * slightly too wide or too narrow. The method corrects the stacking offsets\n * by applying a default letter-spacing for all chars.\n * The value gets passed to the row factory to avoid setting this value again\n * (render speedup is roughly 10%).\n */\n private _setDefaultSpacing(): void {\n // measure same char as in CharSizeService to get the base deviation\n const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false);\n this._rowContainer.style.letterSpacing = `${spacing}px`;\n this._rowFactory.defaultSpacing = spacing;\n }\n\n public handleDevicePixelRatioChange(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n private _refreshRowElements(cols: number, rows: number): void {\n // Add missing elements\n for (let i = this._rowElements.length; i <= rows; i++) {\n const row = this._document.createElement('div');\n this._rowContainer.appendChild(row);\n this._rowElements.push(row);\n this._rowHasBlinkingCells.push(false);\n }\n // Remove excess elements\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n if (this._rowHasBlinkingCells.pop()) {\n this._rowHasBlinkingCellsCount--;\n }\n }\n }\n\n public handleResize(cols: number, rows: number): void {\n this._refreshRowElements(cols, rows);\n this._updateDimensions();\n this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);\n }\n\n public handleCharSizeChanged(): void {\n this._updateDimensions();\n this._widthCache.clear();\n this._setDefaultSpacing();\n }\n\n public handleBlur(): void {\n this._rowContainer.classList.remove(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.pause();\n this.renderRows(0, this._bufferService.rows - 1);\n }\n\n public handleFocus(): void {\n this._rowContainer.classList.add(Constants.FOCUS_CLASS);\n this._cursorBlinkStateManager.resume();\n this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);\n }\n\n public handleViewportVisibilityChange(isVisible: boolean): void {\n this._textBlinkStateManager.setViewportVisible(isVisible);\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n const rows = this._bufferService.rows;\n\n // Remove all selections\n this._selectionContainer.replaceChildren();\n this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);\n\n // Determine old selection viewport band\n let oldViewportStart = 0;\n let oldViewportEnd = -1;\n if (this._lastSelectionStart && this._lastSelectionEnd) {\n this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);\n if (this._selectionRenderModel.hasSelection) {\n oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;\n oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;\n }\n }\n\n // Determine new selection viewport band and create overlays\n let newViewportStart = 0;\n let newViewportEnd = -1;\n if (!start || !end) {\n return;\n }\n this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);\n if (this._selectionRenderModel.hasSelection) {\n const viewportStartRow = this._selectionRenderModel.viewportStartRow;\n const viewportEndRow = this._selectionRenderModel.viewportEndRow;\n const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;\n const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;\n\n newViewportStart = viewportCappedStartRow;\n newViewportEnd = viewportCappedEndRow;\n\n // Create the selections\n const documentFragment = this._document.createDocumentFragment();\n\n if (columnSelectMode) {\n const isXFlipped = start[0] > end[0];\n documentFragment.appendChild(\n this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n );\n } else {\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n // Draw middle rows\n const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewporttartRow\n const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;\n documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));\n }\n }\n this._selectionContainer.appendChild(documentFragment);\n }\n\n // Compute minimal row range to redraw\n let renderStartRow = Math.min(oldViewportStart, newViewportStart);\n let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);\n\n if (renderEndRow >= 0) {\n // Clamp to viewport\n renderStartRow = Math.max(renderStartRow, 0);\n renderEndRow = Math.min(renderEndRow, rows - 1);\n\n // Ensure cursor row is included when a selection is present\n const buffer = this._bufferService.buffer;\n const cursorViewportRow = buffer.y;\n if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {\n renderStartRow = Math.min(renderStartRow, cursorViewportRow);\n renderEndRow = Math.max(renderEndRow, cursorViewportRow);\n }\n\n this.renderRows(renderStartRow, renderEndRow);\n }\n\n // Update last selection state\n this._lastSelectionStart = start;\n this._lastSelectionEnd = end;\n this._lastSelectionColumnMode = columnSelectMode;\n }\n\n /**\n * Creates a selection element at the specified position.\n * @param row The row of the selection.\n * @param colStart The start column.\n * @param colEnd The end columns.\n */\n private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n const element = this._document.createElement('div');\n const left = colStart * this.dimensions.css.cell.width;\n let width = this.dimensions.css.cell.width * (colEnd - colStart);\n if (left + width > this.dimensions.css.canvas.width) {\n width = this.dimensions.css.canvas.width - left;\n }\n\n element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;\n element.style.top = `${row * this.dimensions.css.cell.height}px`;\n element.style.left = `${left}px`;\n element.style.width = `${width}px`;\n return element;\n }\n\n public handleCursorMove(): void {\n // Reset idle timer on cursor movement (which happens on input)\n this._cursorBlinkStateManager.restartBlinkAnimation();\n }\n\n private _handleOptionsChanged(): void {\n // Force a refresh\n this._updateDimensions();\n // Refresh CSS\n this._injectCss(this._themeService.colors);\n // update spacing cache\n this._widthCache.setFont(\n this._optionsService.rawOptions.fontFamily,\n this._optionsService.rawOptions.fontSize,\n this._optionsService.rawOptions.fontWeight,\n this._optionsService.rawOptions.fontWeightBold\n );\n this._setDefaultSpacing();\n }\n\n public clear(): void {\n for (const e of this._rowElements) {\n /**\n * NOTE: This used to be `e.innerText = '';` but that doesn't work when using `jsdom` and\n * `@testing-library/react`\n *\n * references:\n * - https://github.com/testing-library/react-testing-library/issues/1146\n * - https://github.com/jsdom/jsdom/issues/1245\n */\n e.replaceChildren();\n }\n if (this._rowHasBlinkingCellsCount > 0) {\n this._rowHasBlinkingCells.fill(false);\n this._rowHasBlinkingCellsCount = 0;\n this._textBlinkStateManager.setNeedsBlinkInViewport(false);\n }\n }\n\n public renderRows(start: number, end: number): void {\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);\n const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n for (let y = start; y <= end; y++) {\n const row = y + buffer.ydisp;\n const rowElement = this._rowElements[y];\n if (!rowElement) {\n continue;\n }\n const lineData = buffer.lines.get(row);\n if (!lineData) {\n rowElement.replaceChildren();\n this._setRowBlinkState(y, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n lineData,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n -1,\n -1,\n rowInfo\n )\n );\n this._setRowBlinkState(y, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private get _terminalSelector(): string {\n return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n }\n\n private _handleLinkHover(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n }\n\n private _handleLinkLeave(e: ILinkifierEvent): void {\n this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n }\n\n private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n /**\n * NOTE: The linkifier may send out of viewport y-values if:\n * - negative y-value: the link started at a higher line\n * - y-value >= maxY: the link ends at a line below viewport\n *\n * For negative y-values we can simply adjust x = 0,\n * as higher up link start means, that everything from\n * (0,0) is a link under top-down-left-right char progression\n *\n * Additionally there might be a small chance of out-of-sync x|y-values\n * from a race condition of render updates vs. link event handler execution:\n * - (sync) resize: chances terminal buffer in sync, schedules render update async\n * - (async) link handler race condition: new buffer metrics, but still on old render state\n * - (async) render update: brings term metrics and render state back in sync\n */\n // clip coords into viewport\n if (y < 0) x = 0;\n if (y2 < 0) x2 = 0;\n const maxY = this._bufferService.rows - 1;\n y = Math.max(Math.min(y, maxY), 0);\n y2 = Math.max(Math.min(y2, maxY), 0);\n\n cols = Math.min(cols, this._bufferService.cols);\n const buffer = this._bufferService.buffer;\n const cursorAbsoluteY = buffer.ybase + buffer.y;\n const cursorX = Math.min(buffer.x, cols - 1);\n const cursorBlink = this._optionsService.rawOptions.cursorBlink;\n const cursorStyle = this._optionsService.rawOptions.cursorStyle;\n const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;\n const rowInfo = { hasBlinkingCells: false };\n\n // refresh rows within link range\n for (let i = y; i <= y2; ++i) {\n const row = i + buffer.ydisp;\n const rowElement = this._rowElements[i];\n if (!rowElement) {\n continue;\n }\n const bufferline = buffer.lines.get(row);\n if (!bufferline) {\n rowElement.replaceChildren();\n this._setRowBlinkState(i, false);\n continue;\n }\n rowElement.replaceChildren(\n ...this._rowFactory.createRow(\n bufferline,\n row,\n row === cursorAbsoluteY,\n cursorStyle,\n cursorInactiveStyle,\n cursorX,\n cursorBlink,\n this._textBlinkStateManager.isBlinkOn,\n this.dimensions.css.cell.width,\n this._widthCache,\n enabled ? (i === y ? x : 0) : -1,\n enabled ? ((i === y2 ? x2 : cols) - 1) : -1,\n rowInfo\n )\n );\n this._setRowBlinkState(i, rowInfo.hasBlinkingCells);\n }\n this._updateTextBlinkState();\n }\n\n private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {\n const previous = this._rowHasBlinkingCells[row];\n if (previous === hasBlinkingCells) {\n return;\n }\n this._rowHasBlinkingCells[row] = hasBlinkingCells;\n this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;\n }\n\n private _updateTextBlinkState(): void {\n this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);\n }\n}\n\nclass CursorBlinkStateManager {\n private _idleTimeout: number | undefined;\n private _isIdlePaused: boolean = false;\n\n constructor(\n private readonly _rowContainer: HTMLElement,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n if (this._coreBrowserService.isFocused) {\n this._resetIdleTimer();\n }\n }\n\n public dispose(): void {\n this._clearIdleTimer();\n }\n\n public restartBlinkAnimation(): void {\n if (this._isIdlePaused) {\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n }\n this._resetIdleTimer();\n }\n\n public pause(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n }\n\n public resume(): void {\n this._isIdlePaused = false;\n this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._resetIdleTimer();\n }\n\n private _resetIdleTimer(): void {\n this._isIdlePaused = false;\n this._clearIdleTimer();\n this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {\n this._stopBlinkingDueToIdle();\n }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);\n }\n\n private _clearIdleTimer(): void {\n if (this._idleTimeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._idleTimeout);\n this._idleTimeout = undefined;\n }\n }\n\n private _stopBlinkingDueToIdle(): void {\n this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);\n this._isIdlePaused = true;\n this._idleTimeout = undefined;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOptionsService } from '../../common/services/Services';\nimport { ICharSizeService } from './Services';\nimport { Disposable } from '../../common/Lifecycle';\nimport { Emitter } from '../../common/Event';\n\nexport class CharSizeService extends Disposable implements ICharSizeService {\n public serviceBrand: undefined;\n\n public width: number = 0;\n public height: number = 0;\n private _measureStrategy: IMeasureStrategy;\n\n public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }\n\n private readonly _onCharSizeChange = this._register(new Emitter());\n public readonly onCharSizeChange = this._onCharSizeChange.event;\n\n constructor(\n document: Document,\n parentElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n try {\n this._measureStrategy = this._register(new TextMetricsMeasureStrategy(this._optionsService));\n } catch {\n this._measureStrategy = this._register(new DomMeasureStrategy(document, parentElement, this._optionsService));\n }\n this._register(this._optionsService.onMultipleOptionChange(['fontFamily', 'fontSize'], () => this.measure()));\n }\n\n public measure(): void {\n const result = this._measureStrategy.measure();\n if (result.width !== this.width || result.height !== this.height) {\n this.width = result.width;\n this.height = result.height;\n this._onCharSizeChange.fire();\n }\n }\n}\n\ninterface IMeasureStrategy {\n measure(): Readonly;\n}\n\ninterface IMeasureResult {\n width: number;\n height: number;\n}\n\nconst enum DomMeasureStrategyConstants {\n REPEAT = 32\n}\n\nabstract class BaseMeasureStategy extends Disposable implements IMeasureStrategy {\n protected _result: IMeasureResult = { width: 0, height: 0 };\n\n protected _validateAndSet(width: number | undefined, height: number | undefined): void {\n // If values are 0 then the element is likely currently display:none, in which case we should\n // retain the previous value.\n if (width !== undefined && width > 0 && height !== undefined && height > 0) {\n this._result.width = width;\n this._result.height = height;\n }\n }\n\n public abstract measure(): Readonly;\n}\n\nclass DomMeasureStrategy extends BaseMeasureStategy {\n private _measureElement: HTMLElement;\n\n constructor(\n private _document: Document,\n private _parentElement: HTMLElement,\n private _optionsService: IOptionsService\n ) {\n super();\n this._measureElement = this._document.createElement('span');\n this._measureElement.classList.add('xterm-char-measure-element');\n this._measureElement.textContent = 'W'.repeat(DomMeasureStrategyConstants.REPEAT);\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._measureElement.style.whiteSpace = 'pre';\n this._measureElement.style.fontKerning = 'none';\n this._parentElement.appendChild(this._measureElement);\n }\n\n public measure(): Readonly {\n this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;\n this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;\n\n // Note that this triggers a synchronous layout\n this._validateAndSet(Number(this._measureElement.offsetWidth) / DomMeasureStrategyConstants.REPEAT, Number(this._measureElement.offsetHeight));\n\n return this._result;\n }\n}\n\nclass TextMetricsMeasureStrategy extends BaseMeasureStategy {\n private _canvas: OffscreenCanvas;\n private _ctx: OffscreenCanvasRenderingContext2D;\n\n constructor(\n private _optionsService: IOptionsService\n ) {\n super();\n // This will throw if any required API is not supported\n this._canvas = new OffscreenCanvas(100, 100);\n this._ctx = this._canvas.getContext('2d')!;\n const a = this._ctx.measureText('W');\n if (!('width' in a && 'fontBoundingBoxAscent' in a && 'fontBoundingBoxDescent' in a)) {\n throw new Error('Required font metrics not supported');\n }\n }\n\n public measure(): Readonly {\n this._ctx.font = `${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;\n const metrics = this._ctx.measureText('W');\n this._validateAndSet(metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent);\n return this._result;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreBrowserService } from './Services';\nimport { Emitter, EventUtils } from '../../common/Event';\nimport { addDisposableListener } from '../Dom';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\n\nexport class CoreBrowserService extends Disposable implements ICoreBrowserService {\n public serviceBrand: undefined;\n\n private _isFocused = false;\n private _cachedIsFocused: boolean | undefined = undefined;\n private _screenDprMonitor: ScreenDprMonitor;\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n private readonly _onWindowChange = this._register(new Emitter());\n public readonly onWindowChange = this._onWindowChange.event;\n\n constructor(\n private _textarea: HTMLTextAreaElement,\n private _window: Window & typeof globalThis,\n public readonly mainDocument: Document\n ) {\n super();\n\n this._screenDprMonitor = this._register(new ScreenDprMonitor(this._window));\n\n // Monitor device pixel ratio\n this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));\n this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));\n\n this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));\n this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));\n }\n\n public get window(): Window & typeof globalThis {\n return this._window;\n }\n\n public set window(value: Window & typeof globalThis) {\n if (this._window !== value) {\n this._window = value;\n this._onWindowChange.fire(this._window);\n }\n }\n\n public get dpr(): number {\n return this.window.devicePixelRatio;\n }\n\n public get isFocused(): boolean {\n if (this._cachedIsFocused === undefined) {\n this._cachedIsFocused = this._isFocused && this._textarea.ownerDocument.hasFocus();\n queueMicrotask(() => this._cachedIsFocused = undefined);\n }\n return this._cachedIsFocused;\n }\n}\n\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will _register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nclass ScreenDprMonitor extends Disposable {\n private _currentDevicePixelRatio: number;\n private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n private _resolutionMediaMatchList: MediaQueryList | undefined;\n private _windowResizeListener = this._register(new MutableDisposable());\n\n private readonly _onDprChange = this._register(new Emitter());\n public readonly onDprChange = this._onDprChange.event;\n\n constructor(private _parentWindow: Window) {\n super();\n\n // Initialize listener and dpr value\n this._outerListener = () => this._setDprAndFireIfDiffers();\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._updateDpr();\n\n // Monitor active window resize\n this._setWindowResizeListener();\n\n // Setup additional disposables\n this._register(toDisposable(() => this.clearListener()));\n }\n\n\n public setWindow(parentWindow: Window): void {\n this._parentWindow = parentWindow;\n this._setWindowResizeListener();\n this._setDprAndFireIfDiffers();\n }\n\n private _setWindowResizeListener(): void {\n this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());\n }\n\n private _setDprAndFireIfDiffers(): void {\n if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {\n this._onDprChange.fire(this._parentWindow.devicePixelRatio);\n }\n this._updateDpr();\n }\n\n private _updateDpr(): void {\n if (!this._outerListener) {\n return;\n }\n\n // Clear listeners for old DPR\n this._resolutionMediaMatchList?.removeListener(this._outerListener);\n\n // Add listeners for new DPR\n this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;\n this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);\n this._resolutionMediaMatchList.addListener(this._outerListener);\n }\n\n public clearListener(): void {\n if (!this._resolutionMediaMatchList || !this._outerListener) {\n return;\n }\n this._resolutionMediaMatchList.removeListener(this._outerListener);\n this._resolutionMediaMatchList = undefined;\n this._outerListener = undefined;\n }\n}\n", "import { ILinkProvider, ILinkProviderService } from './Services';\nimport { Disposable, toDisposable } from '../../common/Lifecycle';\nimport { IDisposable } from '../../common/Types';\n\nexport class LinkProviderService extends Disposable implements ILinkProviderService {\n declare public serviceBrand: undefined;\n\n public readonly linkProviders: ILinkProvider[] = [];\n\n constructor() {\n super();\n this._register(toDisposable(() => this.linkProviders.length = 0));\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n this.linkProviders.push(linkProvider);\n return {\n dispose: () => {\n // Remove the link provider from the list\n const providerIndex = this.linkProviders.indexOf(linkProvider);\n\n if (providerIndex !== -1) {\n this.linkProviders.splice(providerIndex, 1);\n }\n }\n };\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport function getCoordsRelativeToElement(window: Pick, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n const rect = element.getBoundingClientRect();\n const elementStyle = window.getComputedStyle(element);\n const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'), 10);\n const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'), 10);\n return [\n event.clientX - rect.left - leftPadding,\n event.clientY - rect.top - topPadding\n ];\n}\n\n/**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param window The window object the element belongs to.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n * @param hasValidCharSize Whether there is a valid character size available.\n * @param cssCellWidth The cell width device pixel render dimensions.\n * @param cssCellHeight The cell height device pixel render dimensions.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\nexport function getCoords(window: Pick, event: Pick, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {\n // Coordinates cannot be measured if there is no valid character size.\n if (!hasValidCharSize) {\n return undefined;\n }\n\n const coords = getCoordsRelativeToElement(window, event, element);\n coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);\n coords[1] = Math.ceil(coords[1] / cssCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an additional point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { getWindow } from '../Dom';\nimport { getCoords, getCoordsRelativeToElement } from '../input/Mouse';\nimport { ICharSizeService, IMouseCoordsService, IRenderService } from './Services';\n\nexport class MouseCoordsService implements IMouseCoordsService {\n public serviceBrand: undefined;\n\n constructor(\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n }\n\n public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {\n return getCoords(\n getWindow(element),\n event,\n element,\n colCount,\n rowCount,\n this._charSizeService.hasValidSize,\n this._renderService.dimensions.css.cell.width,\n this._renderService.dimensions.css.cell.height,\n isSelection\n );\n }\n\n public getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined {\n const coords = getCoordsRelativeToElement(getWindow(element), event, element);\n if (!this._charSizeService.hasValidSize) {\n return undefined;\n }\n coords[0] = Math.min(Math.max(coords[0], 0), this._renderService.dimensions.css.canvas.width - 1);\n coords[1] = Math.min(Math.max(coords[1], 0), this._renderService.dimensions.css.canvas.height - 1);\n return {\n col: Math.floor(coords[0] / this._renderService.dimensions.css.cell.width),\n row: Math.floor(coords[1] / this._renderService.dimensions.css.cell.height),\n x: Math.floor(coords[0]),\n y: Math.floor(coords[1])\n };\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as DomUtils from '../Dom';\nimport { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';\n\nconst mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;\n\nfunction tail(array: ArrayLike, n: number = 0): T | undefined {\n return array[array.length - (1 + n)];\n}\n\nfunction memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {\n let fnKey: string | null = null;\n let fn: Function | null = null;\n\n if (typeof descriptor.value === 'function') {\n fnKey = 'value';\n fn = descriptor.value;\n\n if (fn!.length !== 0) {\n console.warn('Memoize should only be used in functions with zero parameters');\n }\n } else if (typeof descriptor.get === 'function') {\n fnKey = 'get';\n fn = descriptor.get;\n }\n\n if (!fn || !fnKey) {\n throw new Error('not supported');\n }\n\n const memoizeKey = `$memoize$${key}`;\n const descriptorAny = descriptor as { [key: string]: any };\n descriptorAny[fnKey] = function (...args: any[]) {\n if (!this.hasOwnProperty(memoizeKey)) {\n Object.defineProperty(this, memoizeKey, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: fn.apply(this, args)\n });\n }\n\n return (this as { [key: string]: any })[memoizeKey];\n };\n}\n\nclass LinkedListNode {\n\n public static readonly Undefined = new LinkedListNode(undefined);\n\n public element: E;\n public next: LinkedListNode;\n public prev: LinkedListNode;\n\n public constructor(element: E) {\n this.element = element;\n this.next = LinkedListNode.Undefined;\n this.prev = LinkedListNode.Undefined;\n }\n}\n\nclass LinkedList {\n\n private _first: LinkedListNode = LinkedListNode.Undefined;\n private _last: LinkedListNode = LinkedListNode.Undefined;\n\n public push(element: E): () => void {\n return this._insert(element, true);\n }\n\n private _insert(element: E, atTheEnd: boolean): () => void {\n const newNode = new LinkedListNode(element);\n if (this._first === LinkedListNode.Undefined) {\n this._first = newNode;\n this._last = newNode;\n\n } else if (atTheEnd) {\n const oldLast = this._last;\n this._last = newNode;\n newNode.prev = oldLast;\n oldLast.next = newNode;\n\n } else {\n const oldFirst = this._first;\n this._first = newNode;\n newNode.next = oldFirst;\n oldFirst.prev = newNode;\n }\n let didRemove = false;\n return () => {\n if (!didRemove) {\n didRemove = true;\n this._remove(newNode);\n }\n };\n }\n\n private _remove(node: LinkedListNode): void {\n if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {\n const anchor = node.prev;\n anchor.next = node.next;\n node.next.prev = anchor;\n\n } else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {\n this._first = LinkedListNode.Undefined;\n this._last = LinkedListNode.Undefined;\n\n } else if (node.next === LinkedListNode.Undefined) {\n this._last = this._last.prev!;\n this._last.next = LinkedListNode.Undefined;\n\n } else if (node.prev === LinkedListNode.Undefined) {\n this._first = this._first.next!;\n this._first.prev = LinkedListNode.Undefined;\n }\n }\n\n public *[Symbol.iterator](): Iterator {\n let node = this._first;\n while (node !== LinkedListNode.Undefined) {\n yield node.element;\n node = node.next;\n }\n }\n}\n\nexport namespace EventType {\n export const TAP = '-xterm-gesturetap';\n export const CHANGE = '-xterm-gesturechange';\n export const START = '-xterm-gesturestart';\n export const END = '-xterm-gesturesend';\n export const CONTEXT_MENU = '-xterm-gesturecontextmenu';\n}\n\ninterface ITouchData {\n id: number;\n initialTarget: EventTarget;\n initialTimeStamp: number;\n initialPageX: number;\n initialPageY: number;\n rollingTimestamps: number[];\n rollingPageX: number[];\n rollingPageY: number[];\n}\n\nexport interface IGestureEvent extends MouseEvent {\n initialTarget: EventTarget | undefined;\n translationX: number;\n translationY: number;\n pageX: number;\n pageY: number;\n clientX: number;\n clientY: number;\n tapCount: number;\n}\n\ninterface ITouch {\n identifier: number;\n screenX: number;\n screenY: number;\n clientX: number;\n clientY: number;\n pageX: number;\n pageY: number;\n radiusX: number;\n radiusY: number;\n rotationAngle: number;\n force: number;\n target: Element;\n}\n\ninterface ITouchList {\n [i: number]: ITouch;\n length: number;\n item(index: number): ITouch;\n identifiedTouch(id: number): ITouch;\n}\n\ninterface ITouchEvent extends Event {\n touches: ITouchList;\n targetTouches: ITouchList;\n changedTouches: ITouchList;\n}\n\nexport class Gesture extends Disposable {\n\n private static readonly _scrollFriction = -0.005;\n private static _instance: Gesture;\n private static readonly _holdDelay = 700;\n\n private _dispatched = false;\n private readonly _targets = new LinkedList();\n private readonly _ignoreTargets = new LinkedList();\n private _handle: IDisposable | null;\n\n private readonly _activeTouches: { [id: number]: ITouchData };\n\n private _lastSetTapCountTime: number;\n\n private static readonly _clearTapCountTime = 400; // ms\n\n\n private constructor() {\n super();\n\n this._activeTouches = {};\n this._handle = null;\n this._lastSetTapCountTime = 0;\n\n const targetWindow = mainWindow;\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchstart', (e: ITouchEvent) => this._handleTouchStart(e), { passive: false }));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchend', (e: ITouchEvent) => this._handleTouchEnd(targetWindow, e)));\n this._register(DomUtils.addDisposableListener(targetWindow.document, 'touchmove', (e: ITouchEvent) => this._handleTouchMove(e), { passive: false }));\n }\n\n public static addTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._targets.push(element);\n return toDisposable(remove);\n }\n\n public static ignoreTarget(element: HTMLElement): IDisposable {\n if (!Gesture.isTouchDevice()) {\n return Disposable.None;\n }\n if (!Gesture._instance) {\n Gesture._instance = new Gesture();\n }\n\n const remove = Gesture._instance._ignoreTargets.push(element);\n return toDisposable(remove);\n }\n\n @memoize\n public static isTouchDevice(): boolean {\n return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;\n }\n\n public override dispose(): void {\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n super.dispose();\n }\n\n private _handleTouchStart(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n if (this._handle) {\n this._handle.dispose();\n this._handle = null;\n }\n\n for (let i = 0, len = e.targetTouches.length; i < len; i++) {\n const touch = e.targetTouches.item(i);\n\n this._activeTouches[touch.identifier] = {\n id: touch.identifier,\n initialTarget: touch.target,\n initialTimeStamp: timestamp,\n initialPageX: touch.pageX,\n initialPageY: touch.pageY,\n rollingTimestamps: [timestamp],\n rollingPageX: [touch.pageX],\n rollingPageY: [touch.pageY]\n };\n\n const evt = this._newGestureEvent(EventType.START, touch.target);\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n this._dispatchEvent(evt);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _handleTouchEnd(targetWindow: Window, e: ITouchEvent): void {\n const timestamp = Date.now();\n\n const activeTouchCount = Object.keys(this._activeTouches).length;\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('move of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n const holdTime = Date.now() - data.initialTimeStamp;\n\n if (holdTime < Gesture._holdDelay\n && Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n && Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (holdTime >= Gesture._holdDelay\n\t\t\t\t&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30\n\t\t\t\t&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {\n\n const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);\n evt.pageX = tail(data.rollingPageX)!;\n evt.pageY = tail(data.rollingPageY)!;\n this._dispatchEvent(evt);\n\n } else if (activeTouchCount === 1) {\n const finalX = tail(data.rollingPageX)!;\n const finalY = tail(data.rollingPageY)!;\n\n const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];\n const deltaX = finalX - data.rollingPageX[0];\n const deltaY = finalY - data.rollingPageY[0];\n\n const dispatchTo = [...this._targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));\n this._inertia(targetWindow, dispatchTo, timestamp,\n Math.abs(deltaX) / deltaT,\n deltaX > 0 ? 1 : -1,\n finalX,\n Math.abs(deltaY) / deltaT,\n deltaY > 0 ? 1 : -1,\n finalY\n );\n }\n\n\n this._dispatchEvent(this._newGestureEvent(EventType.END, data.initialTarget));\n delete this._activeTouches[touch.identifier];\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n\n private _newGestureEvent(type: string, initialTarget?: EventTarget): IGestureEvent {\n const event = document.createEvent('CustomEvent') as unknown as IGestureEvent;\n event.initEvent(type, false, true);\n event.initialTarget = initialTarget;\n event.tapCount = 0;\n return event;\n }\n\n private _dispatchEvent(event: IGestureEvent): void {\n if (event.type === EventType.TAP) {\n const currentTime = (new Date()).getTime();\n let setTapCount;\n if (currentTime - this._lastSetTapCountTime > Gesture._clearTapCountTime) {\n setTapCount = 1;\n } else {\n setTapCount = 2;\n }\n\n this._lastSetTapCountTime = currentTime;\n event.tapCount = setTapCount;\n } else if (event.type === EventType.CHANGE || event.type === EventType.CONTEXT_MENU) {\n this._lastSetTapCountTime = 0;\n }\n\n if (event.initialTarget instanceof Node) {\n for (const ignoreTarget of this._ignoreTargets) {\n if (ignoreTarget.contains(event.initialTarget)) {\n return;\n }\n }\n\n const targets: [number, HTMLElement][] = [];\n for (const target of this._targets) {\n if (target.contains(event.initialTarget)) {\n let depth = 0;\n let now: Node | null = event.initialTarget;\n while (now && now !== target) {\n depth++;\n now = now.parentElement;\n }\n targets.push([depth, target]);\n }\n }\n\n targets.sort((a, b) => a[0] - b[0]);\n\n for (const [, target] of targets) {\n target.dispatchEvent(event);\n this._dispatched = true;\n }\n }\n }\n\n private _inertia(targetWindow: Window, dispatchTo: ReadonlyArray, t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {\n this._handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {\n const now = Date.now();\n\n const deltaT = now - t1;\n let deltaPosX = 0;\n let deltaPosY = 0;\n let stopped = true;\n\n vX += Gesture._scrollFriction * deltaT;\n vY += Gesture._scrollFriction * deltaT;\n\n if (vX > 0) {\n stopped = false;\n deltaPosX = dirX * vX * deltaT;\n }\n\n if (vY > 0) {\n stopped = false;\n deltaPosY = dirY * vY * deltaT;\n }\n\n const evt = this._newGestureEvent(EventType.CHANGE);\n evt.translationX = deltaPosX;\n evt.translationY = deltaPosY;\n dispatchTo.forEach(d => d.dispatchEvent(evt));\n\n if (!stopped) {\n this._inertia(targetWindow, dispatchTo, now, vX, dirX, x + deltaPosX, vY, dirY, y + deltaPosY);\n }\n });\n }\n\n private _handleTouchMove(e: ITouchEvent): void {\n const timestamp = Date.now();\n\n for (let i = 0, len = e.changedTouches.length; i < len; i++) {\n\n const touch = e.changedTouches.item(i);\n\n if (!this._activeTouches.hasOwnProperty(String(touch.identifier))) {\n console.warn('end of an UNKNOWN touch', touch);\n continue;\n }\n\n const data = this._activeTouches[touch.identifier];\n\n const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);\n evt.translationX = touch.pageX - tail(data.rollingPageX)!;\n evt.translationY = touch.pageY - tail(data.rollingPageY)!;\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n evt.clientX = touch.clientX;\n evt.clientY = touch.clientY;\n this._dispatchEvent(evt);\n\n if (data.rollingPageX.length > 3) {\n data.rollingPageX.shift();\n data.rollingPageY.shift();\n data.rollingTimestamps.shift();\n }\n\n data.rollingPageX.push(touch.pageX);\n data.rollingPageY.push(touch.pageY);\n data.rollingTimestamps.push(timestamp);\n }\n\n if (this._dispatched) {\n e.preventDefault();\n e.stopPropagation();\n this._dispatched = false;\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { addDisposableListener } from '../Dom';\nimport { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';\nimport { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';\n\ntype RequestedMouseEvents = Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener | null>;\n\nexport const enum MouseEventCssClasses {\n ENABLE_MOUSE_EVENTS = 'enable-mouse-events'\n}\n\ninterface IMouseBindContext {\n readonly target: IMouseServiceTarget;\n readonly focus: () => void;\n readonly requestedEvents: RequestedMouseEvents;\n}\n\nexport class MouseService implements IMouseService {\n public serviceBrand: undefined;\n\n private _lastEvent: ICoreMouseEvent | null = null;\n private _wheelPartialScroll: number = 0;\n private _touchScrollAccumulator: number = 0;\n private _altMouseCursor: AltMouseCursorController | undefined;\n\n constructor(\n @IRenderService private readonly _renderService: IRenderService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @ICoreService private readonly _coreService: ICoreService,\n @IBufferService private readonly _bufferService: IBufferService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ISelectionService private readonly _selectionService: ISelectionService,\n @ILogService private readonly _logService: ILogService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void {\n const { element, document } = target;\n\n /**\n * Event listener state handling.\n * We listen to the onProtocolChange event of MouseStateService and put\n * requested listeners in `requestedEvents`. With this the listeners\n * have all bits to do the event listener juggling.\n * Note: 'mousedown' currently is \"always on\" and not managed\n * by onProtocolChange.\n */\n const requestedEvents: RequestedMouseEvents = {\n mouseup: null,\n wheel: null,\n mousedrag: null,\n mousemove: null\n };\n const ctx: IMouseBindContext = { target, focus, requestedEvents };\n const eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener> = {\n mouseup: (ev: Event) => this._handleMouseUp(ctx, ev as MouseEvent),\n wheel: (ev: Event) => this._handleWheel(ctx, ev as WheelEvent),\n mousedrag: (ev: Event) => this._handleMouseDrag(ctx, ev as MouseEvent),\n mousemove: (ev: Event) => this._handleMouseMove(ctx, ev as MouseEvent)\n };\n this._altMouseCursor = new AltMouseCursorController(\n element,\n document,\n () => this._mouseStateService.areMouseEventsActive\n && !!this._optionsService.rawOptions.mouseEventsRequireAlt\n );\n register(this._altMouseCursor);\n register(this._mouseStateService.onProtocolChange(events => {\n this._handleProtocolChange(ctx, eventListeners, events);\n }));\n register(this._optionsService.onSpecificOptionChange('mouseEventsRequireAlt', () => {\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n }));\n // force initial onProtocolChange so we dont miss early mouse requests\n this._mouseStateService.activeProtocol = this._mouseStateService.activeProtocol;\n\n // Ensure document-level listeners are removed on dispose\n register(toDisposable(() => {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n }));\n\n /**\n * \"Always on\" event listeners.\n */\n register(addDisposableListener(element, 'mousedown', (ev: MouseEvent) => this._handleMouseDown(ctx, ev)));\n register(addDisposableListener(element, 'wheel', (ev: WheelEvent) => this._handlePassiveWheel(ctx, ev), { passive: false }));\n register(Gesture.addTarget(target.screenElement));\n register(addDisposableListener(target.screenElement, GestureEventType.START, () => this._handleTouchStart()));\n register(addDisposableListener(target.screenElement, GestureEventType.CHANGE, (e: IGestureEvent) => this._handleTouchChange(ctx, e)));\n }\n\n private _sendEvent(ctx: IMouseBindContext, ev: MouseEvent | WheelEvent): boolean {\n // Get mouse coordinates\n const pos = this._mouseCoordsService.getMouseReportCoords(ev as MouseEvent, ctx.target.screenElement);\n if (!pos) {\n return false;\n }\n\n let but: CoreMouseButton;\n let action: CoreMouseAction | undefined;\n switch ((ev as MouseEvent & { overrideType?: string }).overrideType || ev.type) {\n case 'mousemove':\n action = CoreMouseAction.MOVE;\n if (ev.buttons === undefined) {\n // buttons is not supported on macOS, try to get a value from button instead\n but = CoreMouseButton.NONE;\n if (ev.button !== undefined) {\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n }\n } else {\n // according to MDN buttons only reports up to button 5 (AUX2)\n but = ev.buttons & 1 ? CoreMouseButton.LEFT :\n ev.buttons & 4 ? CoreMouseButton.MIDDLE :\n ev.buttons & 2 ? CoreMouseButton.RIGHT :\n CoreMouseButton.NONE; // fallback to NONE\n }\n break;\n case 'mouseup':\n action = CoreMouseAction.UP;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'mousedown':\n action = CoreMouseAction.DOWN;\n but = ev.button < 3 ? ev.button : CoreMouseButton.NONE;\n break;\n case 'wheel':\n if (!this._mouseStateService.allowCustomWheelEvent(ev as WheelEvent)) {\n return false;\n }\n const deltaY = (ev as WheelEvent).deltaY;\n if (deltaY === 0) {\n return false;\n }\n const lines = this._consumeWheelEvent(\n ev as WheelEvent,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n return false;\n }\n action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;\n but = CoreMouseButton.WHEEL;\n break;\n default:\n // dont handle other event types by accident\n return false;\n }\n\n // exit if we cannot determine valid button/action values\n // do nothing for higher buttons than wheel\n if (action === undefined || but === undefined || but > CoreMouseButton.WHEEL) {\n return false;\n }\n\n if (but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive\n && !ev.altKey) {\n return false;\n }\n\n // Alt is only used locally to gate mouse passthrough; do not forward it to the\n // application (e.g. tmux ignores alt-modified mouse reports).\n const stripAltFromReport = but !== CoreMouseButton.WHEEL\n && this._optionsService.rawOptions.mouseEventsRequireAlt\n && this._mouseStateService.areMouseEventsActive;\n\n return this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: but,\n action,\n ctrl: ev.ctrlKey,\n alt: stripAltFromReport ? false : ev.altKey,\n shift: ev.shiftKey\n });\n }\n\n private _handleMouseUp(ctx: IMouseBindContext, ev: MouseEvent): void {\n this._sendEvent(ctx, ev);\n if (!ev.buttons) {\n // if no other button is held remove global handlers\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.removeEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.removeEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n }\n\n private _handleWheel(ctx: IMouseBindContext, ev: WheelEvent): false {\n this._sendEvent(ctx, ev);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n private _handleMouseDrag(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move while a button is held\n if (ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseMove(ctx: IMouseBindContext, ev: MouseEvent): void {\n // deal only with move without any button\n if (!ev.buttons) {\n this._sendEvent(ctx, ev);\n }\n }\n\n private _handleMouseDown(ctx: IMouseBindContext, ev: MouseEvent): void {\n ev.preventDefault();\n ctx.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this._mouseStateService.areMouseEventsActive || this._selectionService.shouldForceSelection(ev)) {\n return;\n }\n\n this._sendEvent(ctx, ev);\n\n // Register additional global handlers which should keep reporting outside\n // of the terminal element.\n // Note: Other emulators also do this for 'mousedown' while a button\n // is held, we currently limit 'mousedown' to the terminal only.\n if (ctx.requestedEvents.mouseup) {\n ctx.target.document.addEventListener('mouseup', ctx.requestedEvents.mouseup);\n }\n if (ctx.requestedEvents.mousedrag) {\n ctx.target.document.addEventListener('mousemove', ctx.requestedEvents.mousedrag);\n }\n }\n\n private _handlePassiveWheel(ctx: IMouseBindContext, ev: WheelEvent): false | void {\n // do nothing, if app side handles wheel itself\n if (ctx.requestedEvents.wheel) {\n return;\n }\n\n if (!this._mouseStateService.allowCustomWheelEvent(ev)) {\n return false;\n }\n\n if (!this._bufferService.buffer.hasScrollback) {\n // Convert wheel events into up/down events when the buffer does not have scrollback, this\n // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse\n // events are not enabled.\n // This used implementation used get the actual lines/partial lines scrolled from the\n // viewport but since moving to the new viewport implementation has been simplified to\n // simply send a single up or down sequence.\n\n // Do nothing if there's no vertical scroll\n const deltaY = ev.deltaY;\n if (deltaY === 0) {\n return false;\n }\n\n const lines = this._consumeWheelEvent(\n ev,\n this._renderService?.dimensions?.device?.cell?.height,\n this._coreBrowserService?.dpr\n );\n if (lines === 0) {\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // Construct and send sequences\n const sequence = C0.ESC + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');\n this._coreService.triggerDataEvent(sequence, true);\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n }\n\n private _handleTouchStart(): void {\n this._touchScrollAccumulator = 0;\n }\n\n private _handleTouchChange(ctx: IMouseBindContext, e: IGestureEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // When mouse protocol has wheel events active, send as mouse wheel events.\n if (ctx.requestedEvents.wheel) {\n this._handleTouchScrollAsWheel(ctx, e);\n return;\n }\n\n // When in alt buffer (no scrollback), send up/down key sequences.\n if (!this._bufferService.buffer.hasScrollback) {\n this._handleTouchScrollAsKeys(e);\n return;\n }\n\n // Normal scrollback: delegate to viewport scrolling when available.\n ctx.target.handleTouchScroll?.(e.translationY);\n }\n\n private _handleTouchScrollAsKeys(e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const sequence = C0.ESC\n + (this._coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[')\n + (lines < 0 ? 'A' : 'B');\n for (let i = 0; i < Math.abs(lines); i++) {\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n\n private _handleTouchScrollAsWheel(ctx: IMouseBindContext, e: IGestureEvent): void {\n const cellHeight = this._renderService?.dimensions.css.cell.height;\n if (!cellHeight) {\n return;\n }\n\n this._touchScrollAccumulator -= e.translationY;\n const lines = Math.trunc(this._touchScrollAccumulator / cellHeight);\n if (lines === 0) {\n return;\n }\n\n this._touchScrollAccumulator -= lines * cellHeight;\n const pos = this._mouseCoordsService.getMouseReportCoords(e, ctx.target.screenElement);\n if (!pos) {\n return;\n }\n\n for (let i = 0; i < Math.abs(lines); i++) {\n this._triggerMouseEvent({\n col: pos.col,\n row: pos.row,\n x: pos.x,\n y: pos.y,\n button: CoreMouseButton.WHEEL,\n action: lines < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN,\n ctrl: false,\n alt: false,\n shift: false\n });\n }\n }\n\n public reset(): void {\n this._lastEvent = null;\n this._wheelPartialScroll = 0;\n this._touchScrollAccumulator = 0;\n }\n\n private _syncMouseModeState(element: HTMLElement): void {\n if (this._mouseStateService.areMouseEventsActive) {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt) {\n this._altMouseCursor?.resetClass();\n this._selectionService.enable();\n } else {\n element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.disable();\n }\n } else {\n element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n this._selectionService.enable();\n }\n }\n\n private _handleProtocolChange(ctx: IMouseBindContext, eventListeners: Record<'mouseup' | 'wheel' | 'mousedrag' | 'mousemove', EventListener>, events: CoreMouseEventType): void {\n const { element, document } = ctx.target;\n const { requestedEvents } = ctx;\n // apply global changes on events\n if (events) {\n if (this._optionsService.rawOptions.logLevel === 'debug') {\n this._logService.debug('Binding to mouse events:', this._explainEvents(events));\n }\n } else {\n this._logService.debug('Unbinding from mouse events.');\n }\n this._syncMouseModeState(element);\n this._altMouseCursor?.sync();\n\n // add/remove handlers from requestedEvents\n if (!(events & CoreMouseEventType.MOVE)) {\n if (requestedEvents.mousemove) {\n element.removeEventListener('mousemove', requestedEvents.mousemove);\n }\n requestedEvents.mousemove = null;\n } else if (!requestedEvents.mousemove) {\n element.addEventListener('mousemove', eventListeners.mousemove);\n requestedEvents.mousemove = eventListeners.mousemove;\n }\n\n if (!(events & CoreMouseEventType.WHEEL)) {\n if (requestedEvents.wheel) {\n element.removeEventListener('wheel', requestedEvents.wheel);\n }\n requestedEvents.wheel = null;\n } else if (!requestedEvents.wheel) {\n element.addEventListener('wheel', eventListeners.wheel, { passive: false });\n requestedEvents.wheel = eventListeners.wheel;\n }\n\n if (!(events & CoreMouseEventType.UP)) {\n if (requestedEvents.mouseup) {\n document.removeEventListener('mouseup', requestedEvents.mouseup);\n }\n requestedEvents.mouseup = null;\n } else {\n requestedEvents.mouseup ??= eventListeners.mouseup;\n }\n\n if (!(events & CoreMouseEventType.DRAG)) {\n if (requestedEvents.mousedrag) {\n document.removeEventListener('mousemove', requestedEvents.mousedrag);\n }\n requestedEvents.mousedrag = null;\n } else {\n requestedEvents.mousedrag ??= eventListeners.mousedrag;\n }\n }\n\n private _applyScrollModifier(amount: number, ev: WheelEvent): number {\n // Multiply the scroll speed when the modifier key is pressed\n if (ev.altKey || ev.ctrlKey || ev.shiftKey) {\n return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;\n }\n return amount * this._optionsService.rawOptions.scrollSensitivity;\n }\n\n /**\n * Processes a wheel event, accounting for partial scrolls for trackpad, mouse scrolls.\n * This prevents hyper-sensitive scrolling in alt buffer.\n */\n private _consumeWheelEvent(ev: WheelEvent, cellHeight?: number, dpr?: number): number {\n // Do nothing if it's not a vertical scroll event\n if (ev.deltaY === 0 || ev.shiftKey) {\n return 0;\n }\n\n if (cellHeight === undefined || dpr === undefined) {\n return 0;\n }\n\n const targetWheelEventPixels = cellHeight / dpr;\n let amount = this._applyScrollModifier(ev.deltaY, ev);\n\n if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n amount /= (targetWheelEventPixels + 0.0); // Prevent integer division\n\n const isLikelyTrackpad = Math.abs(ev.deltaY) < 50;\n if (isLikelyTrackpad) {\n amount *= 0.3;\n }\n\n this._wheelPartialScroll += amount;\n amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n this._wheelPartialScroll %= 1;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n amount *= this._bufferService.rows;\n }\n return amount;\n }\n\n /**\n * Triggers a mouse event to be sent.\n *\n * Returns true if the event passed all protocol restrictions and a report\n * was sent, otherwise false. The return value may be used to decide whether\n * the default event action in the browser component should be omitted.\n *\n * Note: The method will change values of the given event object\n * to fulfill protocol and encoding restrictions.\n */\n private _triggerMouseEvent(e: ICoreMouseEvent): boolean {\n // range check for col/row\n if (e.col < 0 || e.col >= this._bufferService.cols\n || e.row < 0 || e.row >= this._bufferService.rows) {\n return false;\n }\n\n // filter nonsense combinations of button + action\n if (e.button === CoreMouseButton.WHEEL && e.action === CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button === CoreMouseButton.NONE && e.action !== CoreMouseAction.MOVE) {\n return false;\n }\n if (e.button !== CoreMouseButton.WHEEL && (e.action === CoreMouseAction.LEFT || e.action === CoreMouseAction.RIGHT)) {\n return false;\n }\n\n // report 1-based coords\n e.col++;\n e.row++;\n\n // debounce move events at grid or pixel level\n if (e.action === CoreMouseAction.MOVE\n && this._lastEvent\n && this._equalEvents(this._lastEvent, e, this._mouseStateService.isPixelEncoding)\n ) {\n return false;\n }\n\n // apply protocol restrictions\n if (!this._mouseStateService.restrictMouseEvent(e)) {\n return false;\n }\n\n // encode report and send\n const report = this._mouseStateService.encodeMouseEvent(e);\n if (report) {\n if (this._mouseStateService.isDefaultEncoding) {\n this._coreService.triggerBinaryEvent(report);\n } else {\n this._coreService.triggerDataEvent(report, true);\n }\n }\n\n this._lastEvent = e;\n return true;\n }\n\n private _explainEvents(events: CoreMouseEventType): { [event: string]: boolean } {\n return {\n down: !!(events & CoreMouseEventType.DOWN),\n up: !!(events & CoreMouseEventType.UP),\n drag: !!(events & CoreMouseEventType.DRAG),\n move: !!(events & CoreMouseEventType.MOVE),\n wheel: !!(events & CoreMouseEventType.WHEEL)\n };\n }\n\n private _equalEvents(e1: ICoreMouseEvent, e2: ICoreMouseEvent, pixels: boolean): boolean {\n if (pixels) {\n if (e1.x !== e2.x) return false;\n if (e1.y !== e2.y) return false;\n } else {\n if (e1.col !== e2.col) return false;\n if (e1.row !== e2.row) return false;\n }\n if (e1.button !== e2.button) return false;\n if (e1.action !== e2.action) return false;\n if (e1.ctrl !== e2.ctrl) return false;\n if (e1.alt !== e2.alt) return false;\n if (e1.shift !== e2.shift) return false;\n return true;\n }\n\n}\n\n/**\n * Toggles MouseEventCssClasses.ENABLE_MOUSE_EVENTS on the terminal element while alt is held when\n * `mouseEventsRequireAlt` is active. DOM listeners are only registered while active.\n */\nexport class AltMouseCursorController implements IDisposable {\n private readonly _listeners = new MutableDisposable();\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _document: Document,\n private readonly _isActive: () => boolean\n ) {\n }\n\n public dispose(): void {\n this._listeners.dispose();\n }\n\n public sync(): void {\n this._listeners.clear();\n\n if (!this._isActive()) {\n return;\n }\n\n const store = new DisposableStore();\n const syncFromModifier = (ev: KeyboardEvent | MouseEvent): void => this.syncFromModifier(ev);\n store.add(addDisposableListener(this._document, 'keydown', syncFromModifier));\n store.add(addDisposableListener(this._document, 'keyup', syncFromModifier));\n store.add(addDisposableListener(this._element, 'mousemove', syncFromModifier));\n const targetWindow = this._element.ownerDocument?.defaultView;\n if (targetWindow) {\n store.add(addDisposableListener(targetWindow, 'blur', () => {\n if (this._isActive()) {\n this.resetClass();\n }\n }));\n }\n this._listeners.value = store;\n }\n\n public resetClass(): void {\n this._updateClass(false);\n }\n\n public syncFromModifier(ev: KeyboardEvent | MouseEvent): void {\n if (!this._isActive()) {\n return;\n }\n this._updateClass(ev.getModifierState('Alt'));\n }\n\n private _updateClass(altHeld: boolean): void {\n if (altHeld) {\n this._element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncerWithCallback } from './Types';\nimport { ICoreBrowserService } from './services/Services';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IRenderDebouncerWithCallback {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n private _animationFrame: number | undefined;\n private _refreshCallbacks: FrameRequestCallback[] = [];\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _coreBrowserService: ICoreBrowserService\n ) {\n }\n\n public dispose(): void {\n if (this._animationFrame !== undefined) {\n this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = undefined;\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n this._refreshCallbacks.push(callback);\n this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n return this._animationFrame;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n if (this._animationFrame !== undefined) {\n return;\n }\n\n this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());\n }\n\n private _innerRefresh(): void {\n this._animationFrame = undefined;\n\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n this._runRefreshCallbacks();\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n this._runRefreshCallbacks();\n }\n\n private _runRefreshCallbacks(): void {\n for (const callback of this._refreshCallbacks) {\n callback(0);\n }\n this._refreshCallbacks = [];\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ILogService } from './services/Services';\n\ninterface ITaskQueue {\n /**\n * Adds a task to the queue which will run in a future idle callback.\n * To avoid perceivable stalls on the main thread, tasks with heavy workload\n * should split their work into smaller pieces and return `true` to get\n * called again until the work is done (on falsy return value).\n */\n enqueue(task: () => boolean | void): void;\n\n /**\n * Flushes the queue, running all remaining tasks synchronously.\n */\n flush(): void;\n\n /**\n * Clears any remaining tasks from the queue, these will not be run.\n */\n clear(): void;\n}\n\ninterface ITaskDeadline {\n timeRemaining(): number;\n}\ntype CallbackWithDeadline = (deadline: ITaskDeadline) => void;\n\nabstract class TaskQueue implements ITaskQueue {\n private _tasks: (() => boolean | void)[] = [];\n private _idleCallback?: number;\n private _i = 0;\n protected readonly _logService: ILogService;\n\n constructor(logService: ILogService) {\n this._logService = logService;\n }\n\n protected abstract _requestCallback(callback: CallbackWithDeadline): number;\n protected abstract _cancelCallback(identifier: number): void;\n\n public enqueue(task: () => boolean | void): void {\n this._tasks.push(task);\n this._start();\n }\n\n public flush(): void {\n while (this._i < this._tasks.length) {\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n }\n this.clear();\n }\n\n public clear(): void {\n if (this._idleCallback) {\n this._cancelCallback(this._idleCallback);\n this._idleCallback = undefined;\n }\n this._i = 0;\n this._tasks.length = 0;\n }\n\n private _start(): void {\n if (!this._idleCallback) {\n this._idleCallback = this._requestCallback(this._process.bind(this));\n }\n }\n\n private _process(deadline: ITaskDeadline): void {\n this._idleCallback = undefined;\n let taskDuration: number;\n let longestTask = 0;\n let lastDeadlineRemaining = deadline.timeRemaining();\n let deadlineRemaining: number;\n while (this._i < this._tasks.length) {\n taskDuration = performance.now();\n if (!this._tasks[this._i]()) {\n this._i++;\n }\n // other than performance.now, performance.now might not be stable (changes on wall clock\n // changes), this is not an issue here as a clock change during a short running task is very\n // unlikely in case it still happened and leads to negative duration, simply assume 1 msec\n taskDuration = Math.max(1, performance.now() - taskDuration);\n longestTask = Math.max(taskDuration, longestTask);\n // Guess the following task will take a similar time to the longest task in this batch, allow\n // additional room to try avoid exceeding the deadline\n deadlineRemaining = deadline.timeRemaining();\n if (longestTask * 1.5 > deadlineRemaining) {\n // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the\n // task should be split into sub-tasks to ensure the UI remains responsive.\n if (lastDeadlineRemaining - taskDuration < -20) {\n this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`);\n }\n this._start();\n return;\n }\n lastDeadlineRemaining = deadlineRemaining;\n }\n this.clear();\n }\n}\n\n/**\n * A queue of that runs tasks over several tasks via setTimeout, trying to maintain above 60 frames\n * per second. The tasks will run in the order they are enqueued, but they will run some time later,\n * and care should be taken to ensure they're non-urgent and will not introduce race conditions.\n */\nexport class PriorityTaskQueue extends TaskQueue {\n protected _requestCallback(callback: CallbackWithDeadline): number {\n return setTimeout(() => callback(this._createDeadline(16)));\n }\n\n protected _cancelCallback(identifier: number): void {\n clearTimeout(identifier);\n }\n\n private _createDeadline(duration: number): ITaskDeadline {\n const end = performance.now() + duration;\n return {\n timeRemaining: () => Math.max(0, end - performance.now())\n };\n }\n}\n\nclass IdleTaskQueueInternal extends TaskQueue {\n protected _requestCallback(callback: IdleRequestCallback): number {\n return requestIdleCallback(callback);\n }\n\n protected _cancelCallback(identifier: number): void {\n cancelIdleCallback(identifier);\n }\n}\n\n/**\n * A queue of that runs tasks over several idle callbacks, trying to respect the idle callback's\n * deadline given by the environment. The tasks will run in the order they are enqueued, but they\n * will run some time later, and care should be taken to ensure they're non-urgent and will not\n * introduce race conditions.\n *\n * This reverts to a {@link PriorityTaskQueue} if the environment does not support idle callbacks.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdleTaskQueue = ('requestIdleCallback' in globalThis) ? IdleTaskQueueInternal : PriorityTaskQueue;\n\n/**\n * An object that tracks a single debounced task that will run on the next idle frame. When called\n * multiple times, only the last set task will run.\n */\nexport class DebouncedIdleTask {\n private _queue: ITaskQueue;\n\n constructor(logService: ILogService) {\n this._queue = new IdleTaskQueue(logService);\n }\n\n public set(task: () => boolean | void): void {\n this._queue.clear();\n this._queue.enqueue(task);\n }\n\n public flush(): void {\n this._queue.flush();\n }\n\n public dispose(): void {\n this._queue.clear();\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { RenderDebouncer } from '../RenderDebouncer';\nimport { IRenderDebouncerWithCallback } from '../Types';\nimport { IRenderDimensions, IRenderer } from '../renderer/shared/Types';\nimport { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport { DebouncedIdleTask } from '../../common/TaskQueue';\nimport { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\ninterface ISelectionState {\n start: [number, number] | undefined;\n end: [number, number] | undefined;\n columnSelectMode: boolean;\n}\n\nconst enum Constants {\n SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000\n}\n\nexport class RenderService extends Disposable implements IRenderService {\n public serviceBrand: undefined;\n\n private _renderer: MutableDisposable = this._register(new MutableDisposable());\n private _renderDebouncer: IRenderDebouncerWithCallback;\n private _pausedResizeTask: DebouncedIdleTask;\n private _observerDisposable = this._register(new MutableDisposable());\n private _intersectionObserver: IntersectionObserver | undefined;\n\n private _isPaused: boolean = false;\n private _needsFullRefresh: boolean = false;\n private _isNextRenderRedrawOnly: boolean = true;\n private _needsSelectionRefresh: boolean = false;\n private _canvasWidth: number = 0;\n private _canvasHeight: number = 0;\n private _syncOutputHandler: SynchronizedOutputHandler;\n private _selectionState: ISelectionState = {\n start: undefined,\n end: undefined,\n columnSelectMode: false\n };\n\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;\n private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRefreshRequest = this._onRefreshRequest.event;\n\n public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }\n\n constructor(\n private _rowCount: number,\n screenElement: HTMLElement,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @ILogService private readonly _logService: ILogService,\n @ICharSizeService private readonly _charSizeService: ICharSizeService,\n @ICoreService private readonly _coreService: ICoreService,\n @IDecorationService decorationService: IDecorationService,\n @IBufferService bufferService: IBufferService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IThemeService themeService: IThemeService\n ) {\n super();\n\n this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));\n\n this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);\n this._register(this._renderDebouncer);\n\n this._syncOutputHandler = new SynchronizedOutputHandler(\n this._coreBrowserService,\n this._coreService,\n () => this._fullRefresh()\n );\n this._register(toDisposable(() => this._syncOutputHandler.dispose()));\n\n this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));\n\n this._register(bufferService.onResize(() => this._fullRefresh()));\n this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));\n this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));\n this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));\n\n // Do a full refresh whenever any decoration is added or removed. This may not actually result\n // in changes but since decorations should be used sparingly or added/removed all in the same\n // frame this should have minimal performance impact.\n this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));\n this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));\n\n // Clear the renderer when the a change that could affect glyphs occurs\n this._register(this._optionsService.onMultipleOptionChange([\n 'drawBoldTextInBrightColors',\n 'letterSpacing',\n 'lineHeight',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontWeightBold',\n 'minimumContrastRatio',\n 'rescaleOverlappingGlyphs'\n ], () => {\n this.clear();\n this.handleResize(bufferService.cols, bufferService.rows);\n this._fullRefresh();\n }));\n\n // Refresh the cursor line when the cursor changes\n this._register(this._optionsService.onMultipleOptionChange([\n 'cursorBlink',\n 'cursorStyle'\n ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));\n\n this._register(themeService.onChangeColors(() => this._fullRefresh()));\n\n this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);\n this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));\n }\n\n private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {\n // Detect whether IntersectionObserver is detected and enable renderer pause\n // and resume based on terminal visibility if so\n if ('IntersectionObserver' in w) {\n const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });\n this._observerDisposable.value = toDisposable(() => {\n this._intersectionObserver?.disconnect();\n this._intersectionObserver = undefined;\n });\n this._intersectionObserver = observer;\n observer.observe(screenElement);\n }\n }\n\n private _handleIntersectionChange(entry: IntersectionObserverEntry): void {\n this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;\n this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);\n\n // Terminal was hidden on open\n if (!this._isPaused && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n\n if (!this._isPaused && this._needsFullRefresh) {\n this._pausedResizeTask.flush();\n this.refreshRows(0, this._rowCount - 1);\n this._needsFullRefresh = false;\n }\n }\n\n public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n return;\n }\n\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n const buffered = this._syncOutputHandler.flush();\n if (buffered) {\n start = Math.min(start, buffered.start);\n end = Math.max(end, buffered.end);\n }\n\n if (!isRedrawOnly) {\n this._isNextRenderRedrawOnly = false;\n }\n\n if (sync) {\n this._renderRows(start, end);\n } else {\n this._renderDebouncer.refresh(start, end, this._rowCount);\n }\n }\n\n private _renderRows(start: number, end: number): void {\n if (!this._renderer.value) {\n return;\n }\n\n // Skip rendering if synchronized output mode is enabled. This check must happen here\n // (in addition to refreshRows) to handle renders that were queued before the mode was enabled.\n if (this._coreService.decPrivateModes.synchronizedOutput) {\n this._syncOutputHandler.bufferRows(start, end);\n return;\n }\n\n // Since this is debounced, a resize event could have happened between the time a refresh was\n // requested and when this triggers. Clamp the values of start and end to ensure they're valid\n // given the current viewport state.\n start = Math.min(start, this._rowCount - 1);\n end = Math.min(end, this._rowCount - 1);\n\n // Render\n this._renderer.value.renderRows(start, end);\n\n // Update selection if needed\n if (this._needsSelectionRefresh) {\n this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);\n this._needsSelectionRefresh = false;\n }\n\n // Fire render event only if it was not a redraw\n if (!this._isNextRenderRedrawOnly) {\n this._onRenderedViewportChange.fire({ start, end });\n }\n this._onRender.fire({ start, end });\n this._isNextRenderRedrawOnly = true;\n }\n\n public resize(cols: number, rows: number): void {\n this._rowCount = rows;\n this._fireOnCanvasResize();\n }\n\n private _handleOptionsChanged(): void {\n if (!this._renderer.value) {\n return;\n }\n this.refreshRows(0, this._rowCount - 1);\n this._fireOnCanvasResize();\n }\n\n private _fireOnCanvasResize(): void {\n if (!this._renderer.value) {\n return;\n }\n // Don't fire the event if the dimensions haven't changed\n if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {\n return;\n }\n this._onDimensionsChange.fire(this._renderer.value.dimensions);\n }\n\n public hasRenderer(): boolean {\n return !!this._renderer.value;\n }\n\n public setRenderer(renderer: IRenderer): void {\n this._renderer.value = renderer;\n // If the value was not set, the terminal is being disposed so ignore it\n if (this._renderer.value) {\n this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));\n\n // Force a refresh\n this._needsSelectionRefresh = true;\n this._fullRefresh();\n }\n }\n\n public addRefreshCallback(callback: FrameRequestCallback): number {\n return this._renderDebouncer.addRefreshCallback(callback);\n }\n\n private _fullRefresh(): void {\n if (this._isPaused) {\n this._needsFullRefresh = true;\n } else {\n this.refreshRows(0, this._rowCount - 1);\n }\n }\n\n public clearTextureAtlas(): void {\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.clearTextureAtlas?.();\n this._fullRefresh();\n }\n\n public handleDevicePixelRatioChange(): void {\n // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable\n // when devicePixelRatio changes\n this._charSizeService.measure();\n\n if (!this._renderer.value) {\n return;\n }\n this._renderer.value.handleDevicePixelRatioChange();\n this.refreshRows(0, this._rowCount - 1);\n }\n\n public handleResize(cols: number, rows: number): void {\n if (!this._renderer.value) {\n return;\n }\n if (this._isPaused) {\n this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));\n } else {\n this._renderer.value.handleResize(cols, rows);\n }\n this._fullRefresh();\n }\n\n // TODO: Is this useful when we have onResize?\n public handleCharSizeChanged(): void {\n this._renderer.value?.handleCharSizeChanged();\n }\n\n public handleBlur(): void {\n this._renderer.value?.handleBlur();\n }\n\n public handleFocus(): void {\n this._renderer.value?.handleFocus();\n }\n\n public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {\n this._selectionState.start = start;\n this._selectionState.end = end;\n this._selectionState.columnSelectMode = columnSelectMode;\n this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);\n }\n\n public handleCursorMove(): void {\n this._renderer.value?.handleCursorMove();\n }\n\n public clear(): void {\n this._renderer.value?.clear();\n }\n}\n\n/**\n * Buffers row refresh requests during synchronized output mode (DEC mode 2026).\n * When the mode is disabled, the accumulated row range is flushed for rendering.\n * A safety timeout ensures rendering occurs even if the end sequence is not received.\n */\nclass SynchronizedOutputHandler {\n private _start: number = 0;\n private _end: number = 0;\n private _timeout: number | undefined;\n private _isBuffering: boolean = false;\n\n constructor(\n private readonly _coreBrowserService: ICoreBrowserService,\n private readonly _coreService: ICoreService,\n private readonly _onTimeout: () => void\n ) {}\n\n public bufferRows(start: number, end: number): void {\n if (!this._isBuffering) {\n this._start = start;\n this._end = end;\n this._isBuffering = true;\n } else {\n this._start = Math.min(this._start, start);\n this._end = Math.max(this._end, end);\n }\n\n this._timeout ??= this._coreBrowserService.window.setTimeout(() => {\n this._timeout = undefined;\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onTimeout();\n }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);\n }\n\n public flush(): { start: number, end: number } | undefined {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n\n if (!this._isBuffering) {\n return undefined;\n }\n\n const result = { start: this._start, end: this._end };\n this._isBuffering = false;\n return result;\n }\n\n public dispose(): void {\n if (this._timeout !== undefined) {\n this._coreBrowserService.window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { C0 } from '../../common/data/EscapeSequences';\nimport { IBufferService } from '../../common/services/Services';\n\nconst enum Direction {\n UP = 'A',\n DOWN = 'B',\n RIGHT = 'C',\n LEFT = 'D'\n}\n\n/**\n * Concatenates all the arrow sequences together.\n * Resets the starting row to an unwrapped row, moves to the requested row,\n * then moves to requested col.\n */\nexport function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startX = bufferService.buffer.x;\n const startY = bufferService.buffer.y;\n\n // The alt buffer should try to navigate between rows\n if (!bufferService.buffer.hasScrollback) {\n return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +\n moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +\n moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);\n }\n\n // Only move horizontally for the normal buffer\n let direction;\n if (startY === targetY) {\n direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;\n return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));\n }\n direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;\n const rowDifference = Math.abs(startY - targetY);\n const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +\n (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +\n colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);\n return repeat(cellsToMove, sequence(direction, applicationCursor));\n}\n\n/**\n * Find the number of cols from a row beginning to a col.\n */\nfunction colsFromRowBeginning(currX: number, bufferService: IBufferService): number {\n return currX - 1;\n}\n\n/**\n * Find the number of cols from a col to row end.\n */\nfunction colsFromRowEnd(currX: number, bufferService: IBufferService): number {\n return bufferService.cols - currX;\n}\n\n/**\n * If the initial position of the cursor is on a row that is wrapped, move the\n * cursor up to the first row that is not wrapped to have accurate vertical\n * positioning.\n */\nfunction resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {\n return '';\n }\n return repeat(bufferLine(\n startX, startY, startX,\n startY - wrappedRowsForRow(startY, bufferService), false, bufferService\n ).length, sequence(Direction.LEFT, applicationCursor));\n}\n\n/**\n * Using the reset starting and ending row, move to the requested row,\n * ignoring wrapped rows\n */\nfunction moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);\n\n return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));\n}\n\n/**\n * Move to the requested col on the ending row\n */\nfunction moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n const endRow = targetY;\n const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);\n\n return repeat(bufferLine(\n startX, startRow, targetX, endRow,\n direction === Direction.RIGHT, bufferService\n ).length, sequence(direction, applicationCursor));\n}\n\n/**\n * Utility functions\n */\n\n/**\n * Calculates the number of wrapped rows between the unwrapped starting and\n * ending rows. These rows need to ignored since the cursor skips over them.\n */\nfunction wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {\n let wrappedRows = 0;\n const startRow = startY - wrappedRowsForRow(startY, bufferService);\n const endRow = targetY - wrappedRowsForRow(targetY, bufferService);\n\n for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;\n const line = bufferService.buffer.lines.get(startRow + (direction * i));\n if (line?.isWrapped) {\n wrappedRows++;\n }\n }\n\n return wrappedRows;\n}\n\n/**\n * Calculates the number of wrapped rows that make up a given row.\n * @param currentRow The row to determine how many wrapped rows make it up\n */\nfunction wrappedRowsForRow(currentRow: number, bufferService: IBufferService): number {\n let rowCount = 0;\n let line = bufferService.buffer.lines.get(currentRow);\n let lineWraps = line?.isWrapped;\n\n while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {\n rowCount++;\n line = bufferService.buffer.lines.get(--currentRow);\n lineWraps = line?.isWrapped;\n }\n\n return rowCount;\n}\n\n/**\n * Direction determiners\n */\n\n/**\n * Determines if the right or left arrow is needed\n */\nfunction horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {\n let startRow;\n if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {\n startRow = targetY - wrappedRowsForRow(targetY, bufferService);\n } else {\n startRow = startY;\n }\n\n if ((startX < targetX &&\n startRow <= targetY) || // down/right or same y/right\n (startX >= targetX &&\n startRow < targetY)) { // down/left or same y/left\n return Direction.RIGHT;\n }\n return Direction.LEFT;\n}\n\n/**\n * Determines if the up or down arrow is needed\n */\nfunction verticalDirection(startY: number, targetY: number): Direction {\n return startY > targetY ? Direction.UP : Direction.DOWN;\n}\n\n/**\n * Constructs the string of chars in the buffer from a starting row and col\n * to an ending row and col\n * @param startCol The starting column position\n * @param startRow The starting row position\n * @param endCol The ending column position\n * @param endRow The ending row position\n * @param forward Direction to move\n */\nfunction bufferLine(\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n forward: boolean,\n bufferService: IBufferService\n): string {\n let currentCol = startCol;\n let currentRow = startRow;\n let bufferStr = '';\n\n while ((currentCol !== endCol || currentRow !== endRow) &&\n currentRow >= 0 &&\n currentRow < bufferService.buffer.lines.length) {\n currentCol += forward ? 1 : -1;\n\n if (forward && currentCol > bufferService.cols - 1) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n currentCol = 0;\n startCol = 0;\n currentRow++;\n } else if (!forward && currentCol < 0) {\n bufferStr += bufferService.buffer.translateBufferLineToString(\n currentRow, false, 0, startCol + 1\n );\n currentCol = bufferService.cols - 1;\n startCol = currentCol;\n currentRow--;\n }\n }\n\n return bufferStr + bufferService.buffer.translateBufferLineToString(\n currentRow, false, startCol, currentCol\n );\n}\n\n/**\n * Constructs the escape sequence for clicking an arrow\n * @param direction The direction to move\n */\nfunction sequence(direction: Direction, applicationCursor: boolean): string {\n const mod = applicationCursor ? 'O' : '[';\n return C0.ESC + mod + direction;\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param str The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n count = Math.floor(count);\n let rpt = '';\n for (let i = 0; i < count; i++) {\n rpt += str;\n }\n return rpt;\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferService } from '../../common/services/Services';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean = false;\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number = 0;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number] | undefined;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number] | undefined;\n\n constructor(\n private _bufferService: IBufferService\n ) {\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = undefined;\n this.selectionEnd = undefined;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] | undefined {\n if (this.isSelectAllActive) {\n return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];\n }\n\n if (!this.selectionStart) {\n return undefined;\n }\n\n // Use the selection start + length if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n // Ensure the trailing EOL isn't included when the selection ends on the right edge\n if (startPlusLength % this._bufferService.cols === 0) {\n return [this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols) - 1];\n }\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [startPlusLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n // Keep the whole wrapped word/line selected if the content wraps multiple lines\n const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n if (startPlusLength > this._bufferService.cols) {\n return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];\n }\n return [Math.max(startPlusLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @returns Whether a refresh is necessary.\n */\n public handleTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start row is trimmed away, reset to the buffer origin.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart = [0, 0];\n return true;\n }\n return false;\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange } from '@xterm/xterm';\n\nexport function getRangeLength(range: IBufferRange, bufferCols: number): number {\n if (range.start.y > range.end.y) {\n throw new Error(`Buffer range end (${range.end.x}, ${range.end.y}) cannot be before start (${range.start.x}, ${range.start.y})`);\n }\n return bufferCols * (range.end.y - range.start.y) + (range.end.x - range.start.x + 1);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferRange, ILinkifier2 } from '../Types';\nimport { getCoordsRelativeToElement } from '../input/Mouse';\nimport { moveToCellSequence } from '../input/MoveToCell';\nimport { SelectionModel } from '../selection/SelectionModel';\nimport { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';\nimport { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';\nimport { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';\nimport * as Browser from '../../common/Platform';\nimport { IDisposable } from '../../common/Types';\nimport { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';\nimport { getRangeLength } from '../../common/buffer/BufferRange';\nimport { CellData } from '../../common/buffer/CellData';\nimport { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';\nimport { Emitter } from '../../common/Event';\n\nconst enum Constants {\n /**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\n DRAG_SCROLL_MAX_THRESHOLD = 50,\n /**\n * The maximum scrolling speed\n */\n DRAG_SCROLL_MAX_SPEED = 15,\n /**\n * The number of milliseconds between drag scroll updates.\n */\n DRAG_SCROLL_INTERVAL = 50,\n /**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\n ALT_CLICK_MOVE_CURSOR_TIME = 500\n}\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n NORMAL,\n WORD,\n LINE,\n COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionService handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionService but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionService extends Disposable implements ISelectionService {\n public serviceBrand: undefined;\n\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number = 0;\n\n /**\n * The current selection mode.\n */\n protected _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: number | undefined;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number | undefined;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n private readonly _trimListener = this._register(new MutableDisposable());\n private _workCell: CellData = new CellData();\n\n private _mouseDownTimeStamp: number = 0;\n private _oldHasSelection: boolean = false;\n private _oldSelectionStart: [number, number] | undefined = undefined;\n private _oldSelectionEnd: [number, number] | undefined = undefined;\n\n private readonly _onLinuxMouseSelection = this._register(new Emitter());\n public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;\n private readonly _onRedrawRequest = this._register(new Emitter());\n public readonly onRequestRedraw = this._onRedrawRequest.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onRequestScrollLines = this._register(new Emitter());\n public readonly onRequestScrollLines = this._onRequestScrollLines.event;\n\n constructor(\n private readonly _element: HTMLElement,\n private readonly _screenElement: HTMLElement,\n private readonly _linkifier: ILinkifier2,\n @IBufferService private readonly _bufferService: IBufferService,\n @ICoreService private readonly _coreService: ICoreService,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IOptionsService private readonly _optionsService: IOptionsService,\n @IMouseStateService private readonly _mouseStateService: IMouseStateService,\n @IRenderService private readonly _renderService: IRenderService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService\n ) {\n super();\n\n // Init listeners\n this._mouseMoveListener = event => this._handleMouseMove(event as MouseEvent);\n this._mouseUpListener = event => this._handleMouseUp(event as MouseEvent);\n this._coreService.onUserInput(() => {\n if (this.hasSelection) {\n this.clearSelection();\n }\n });\n this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));\n this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));\n\n this.enable();\n\n this._model = new SelectionModel(this._bufferService);\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n this._register(toDisposable(() => {\n this._removeMouseDownListeners();\n }));\n\n // Clear selection when resizing vertically. This experience could be improved, this is the\n // simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300\n this._register(this._bufferService.onResize(e => {\n if (e.rowsChanged) {\n this.clearSelection();\n }\n }));\n }\n\n public reset(): void {\n this.clearSelection();\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n const buffer = this._bufferService.buffer;\n const result: string[] = [];\n\n if (this._activeSelectionMode === SelectionMode.COLUMN) {\n // Ignore zero width selections\n if (start[0] === end[0]) {\n return '';\n }\n\n // For column selection it's not enough to rely on final selection's swapping of reversed\n // values, it also needs the x coordinates to swap independently of the y coordinate is needed\n const startCol = start[0] < end[0] ? start[0] : end[0];\n const endCol = start[0] < end[0] ? end[0] : start[0];\n for (let i = start[1]; i <= end[1]; i++) {\n const lineText = buffer.translateBufferLineToString(i, true, startCol, endCol);\n result.push(lineText);\n }\n } else {\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n result.push(buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = buffer.lines.get(i);\n const lineText = buffer.translateBufferLineToString(i, true);\n if (bufferLine?.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = buffer.lines.get(end[1]);\n const lineText = buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if (bufferLine && bufferLine!.isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isLinuxMouseSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isLinuxMouseSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isLinuxMouseSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this._onLinuxMouseSelection.fire(this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = undefined;\n this._onRedrawRequest.fire({\n start: this._model.finalSelectionStart,\n end: this._model.finalSelectionEnd,\n columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n });\n }\n\n /**\n * Checks if the current click was inside the current selection\n * @param event The mouse event\n */\n private _isClickInSelection(event: MouseEvent): boolean {\n const coords = this._getMouseBufferCoords(event);\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n\n if (!start || !end || !coords) {\n return false;\n }\n\n return this._areCoordsInSelection(coords, start, end);\n }\n\n public isCellInSelection(x: number, y: number): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return this._areCoordsInSelection([x, y], start, end);\n }\n\n protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n return (coords[1] > start[1] && coords[1] < end[1]) ||\n (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n }\n\n /**\n * Selects word at the current mouse event coordinates.\n * @param event The mouse event.\n */\n private _selectWordAtCursor(event: MouseEvent, allowWhitespaceOnlySelection: boolean): boolean {\n // Check if there is a link under the cursor first and select that if so\n const range = this._linkifier.currentLink?.link?.range;\n if (range) {\n this._model.selectionStart = [range.start.x - 1, range.start.y - 1];\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n this._model.selectionEnd = undefined;\n return true;\n }\n\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._selectWordAt(coords, allowWhitespaceOnlySelection);\n this._model.selectionEnd = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n public selectLines(start: number, end: number): void {\n this._model.clearSelection();\n start = Math.max(start, 0);\n end = Math.min(end, this._bufferService.buffer.lines.length - 1);\n this._model.selectionStart = [0, start];\n this._model.selectionEnd = [this._bufferService.cols, end];\n this.refresh();\n this._onSelectionChange.fire();\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _handleTrim(amount: number): void {\n const needsRefresh = this._model.handleTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {\n const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);\n if (!coords) {\n return undefined;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._bufferService.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = getCoordsRelativeToElement(this._coreBrowserService.window, event, this._screenElement)[1];\n const terminalHeight = this._renderService.dimensions.css.canvas.height;\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);\n offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return !event.altKey;\n }\n\n if (Browser.isMac) {\n return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;\n }\n\n return event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public handleMouseDown(event: MouseEvent): void {\n this._mouseDownTimeStamp = event.timeStamp;\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive && event.altKey) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._handleIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._handleSingleClick(event);\n } else if (event.detail === 2) {\n this._handleDoubleClick(event);\n } else if (event.detail === 3) {\n this._handleTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n }\n this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n if (this._screenElement.ownerDocument) {\n this._screenElement.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._screenElement.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n }\n this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = undefined;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _handleIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _handleSingleClick(event: MouseEvent): void {\n // Track if there was a selection before clearing\n const hadSelection = this.hasSelection;\n\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = undefined;\n\n // Fire selection change event if a selection was cleared\n if (hadSelection) {\n this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);\n }\n\n // Ensure the line exists\n const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length === this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current word.\n * @param event The mouse event.\n */\n private _handleDoubleClick(event: MouseEvent): void {\n if (this._selectWordAtCursor(event, true)) {\n this._activeSelectionMode = SelectionMode.WORD;\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _handleTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Returns whether the selection manager should operate in column select mode\n * @param event the mouse or keyboard event\n */\n public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n if (this._optionsService.rawOptions.mouseEventsRequireAlt && this._mouseStateService.areMouseEventsActive) {\n return false;\n }\n return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _handleMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propagation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Do nothing if there is no selection start, this can happen if the first\n // click in the terminal is an incremental click\n if (!this._model.selectionStart) {\n return;\n }\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n const buffer = this._bufferService.buffer;\n if (this._model.selectionEnd[1] < buffer.lines.length) {\n const line = buffer.lines.get(this._model.selectionEnd[1]);\n if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {\n if (this._model.selectionEnd[0] < this._bufferService.cols) {\n this._model.selectionEnd[0]++;\n }\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (!this._model.selectionEnd || !this._model.selectionStart) {\n return;\n }\n if (this._dragScrollAmount) {\n this._onRequestScrollLines.fire({ amount: this._dragScrollAmount, suppressScrollEvent: false });\n // Re-evaluate selection\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively. This should only happen when\n // NOT in column select mode.\n const buffer = this._bufferService.buffer;\n if (this._dragScrollAmount > 0) {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = this._bufferService.cols;\n }\n this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);\n } else {\n if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n this._model.selectionEnd[0] = 0;\n }\n this._model.selectionEnd[1] = buffer.ydisp;\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _handleMouseUp(event: MouseEvent): void {\n const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n this._removeMouseDownListeners();\n\n if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {\n if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {\n const coordinates = this._mouseCoordsService.getCoords(\n event,\n this._element,\n this._bufferService.cols,\n this._bufferService.rows,\n false\n );\n if (coordinates && coordinates[0] !== undefined && coordinates[1] !== undefined) {\n const sequence = moveToCellSequence(coordinates[0] - 1, coordinates[1] - 1, this._bufferService, this._coreService.decPrivateModes.applicationCursorKeys);\n this._coreService.triggerDataEvent(sequence, true);\n }\n }\n } else {\n this._fireEventIfSelectionChanged();\n }\n }\n\n private _fireEventIfSelectionChanged(): void {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n const hasSelection = !!start && !!end && (start[0] !== end[0] || start[1] !== end[1]);\n\n if (!hasSelection) {\n if (this._oldHasSelection) {\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n return;\n }\n\n // Sanity check, these should not be undefined as there is a selection\n if (!start || !end) {\n return;\n }\n\n if (!this._oldSelectionStart || !this._oldSelectionEnd || (\n start[0] !== this._oldSelectionStart[0] || start[1] !== this._oldSelectionStart[1] ||\n end[0] !== this._oldSelectionEnd[0] || end[1] !== this._oldSelectionEnd[1])) {\n\n this._fireOnSelectionChange(start, end, hasSelection);\n }\n }\n\n private _fireOnSelectionChange(start: [number, number] | undefined, end: [number, number] | undefined, hasSelection: boolean): void {\n this._oldSelectionStart = start;\n this._oldSelectionEnd = end;\n this._oldHasSelection = hasSelection;\n this._onSelectionChange.fire();\n }\n\n private _handleBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n this.clearSelection();\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));\n }\n\n /**\n * Converts a viewport column (0 to cols - 1) to the character index on the\n * buffer line, the latter takes into account wide and null characters.\n * @param bufferLine The buffer line to use.\n * @param x The x index in the buffer line to convert.\n */\n private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, x: number): number {\n let charIndex = x;\n for (let i = 0; x >= i; i++) {\n const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n if (this._workCell.getWidth() === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (length > 1 && x !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n this._fireEventIfSelectionChanged();\n }\n\n public rightClickSelect(ev: MouseEvent): void {\n if (!this._isClickInSelection(ev)) {\n if (this._selectWordAtCursor(ev, false)) {\n this.refresh(true);\n }\n this._fireEventIfSelectionChanged();\n }\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition | undefined {\n // Ensure coords are within viewport (eg. not within scroll bar)\n if (coords[0] >= this._bufferService.cols) {\n return undefined;\n }\n\n const buffer = this._bufferService.buffer;\n const bufferLine = buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return undefined;\n }\n\n const line = buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords[0]);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine.getWidth(startCol) === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine.getWidth(endCol) === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n const length = bufferLine.getString(endCol).length;\n if (length > 1) {\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n bufferLine.loadCell(startCol - 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += length - 1;\n startIndex -= length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n bufferLine.loadCell(endCol + 1, this._workCell);\n const length = this._workCell.getChars().length;\n if (this._workCell.getWidth() === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += length - 1;\n endIndex += length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n let start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n let length = Math.min(this._bufferService.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n return undefined;\n }\n\n // Recurse upwards if the line is wrapped and the word wraps to the above line\n if (followWrappedLinesAbove) {\n if (start === 0 && bufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const previousBufferLine = buffer.lines.get(coords[1] - 1);\n if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const previousLineWordPosition = this._getWordAt([this._bufferService.cols - 1, coords[1] - 1], false, true, false);\n if (previousLineWordPosition) {\n const offset = this._bufferService.cols - previousLineWordPosition.start;\n start -= offset;\n length += offset;\n }\n }\n }\n }\n\n // Recurse downwards if the line is wrapped and the word wraps to the next line\n if (followWrappedLinesBelow) {\n if (start + length === this._bufferService.cols && bufferLine.getCodePoint(this._bufferService.cols - 1) !== 32 /* ' ' */) {\n const nextBufferLine = buffer.lines.get(coords[1] + 1);\n if (nextBufferLine?.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /* ' ' */) {\n const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n if (nextLineWordPosition) {\n length += nextLineWordPosition.length;\n }\n }\n }\n }\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n * @param allowWhitespaceOnlySelection If whitespace should be selected\n */\n protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n if (wordPosition) {\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n coords[1]--;\n }\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords, true);\n if (wordPosition) {\n let endRow = coords[1];\n\n // Adjust negative start value\n while (wordPosition.start < 0) {\n wordPosition.start += this._bufferService.cols;\n endRow--;\n }\n\n // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n // case we're interested in the start of the word, not the end\n if (!this._model.areSelectionValuesReversed()) {\n while (wordPosition.start + wordPosition.length > this._bufferService.cols) {\n wordPosition.length -= this._bufferService.cols;\n endRow++;\n }\n }\n\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param cell The cell to check.\n */\n private _isCharWordSeparator(cell: ICellData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (cell.getWidth() === 0) {\n return false;\n }\n return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n const wrappedRange = this._bufferService.buffer.getWrappedRangeForLine(line);\n const range: IBufferRange = {\n start: { x: 0, y: wrappedRange.first },\n end: { x: this._bufferService.cols - 1, y: wrappedRange.last }\n };\n this._model.selectionStart = [0, wrappedRange.first];\n this._model.selectionEnd = undefined;\n this._model.selectionStartLength = getRangeLength(range, this._bufferService.cols);\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class TwoKeyMap {\n private _data: { [bg: string | number]: { [fg: string | number]: TValue | undefined } | undefined } = {};\n\n public set(first: TFirst, second: TSecond, value: TValue): void {\n if (!this._data[first]) {\n this._data[first] = {};\n }\n this._data[first as string | number]![second] = value;\n }\n\n public get(first: TFirst, second: TSecond): TValue | undefined {\n return this._data[first as string | number] ? this._data[first as string | number]![second] : undefined;\n }\n\n public clear(): void {\n this._data = {};\n }\n}\n\nexport class FourKeyMap {\n private _data: TwoKeyMap> = new TwoKeyMap();\n\n public set(first: TFirst, second: TSecond, third: TThird, fourth: TFourth, value: TValue): void {\n if (!this._data.get(first, second)) {\n this._data.set(first, second, new TwoKeyMap());\n }\n this._data.get(first, second)!.set(third, fourth, value);\n }\n\n public get(first: TFirst, second: TSecond, third: TThird, fourth: TFourth): TValue | undefined {\n return this._data.get(first, second)?.get(third, fourth);\n }\n\n public clear(): void {\n this._data.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorContrastCache } from './Types';\nimport { IColor } from '../common/Types';\nimport { TwoKeyMap } from '../common/MultiKeyMap';\n\nexport class ColorContrastCache implements IColorContrastCache {\n private _color: TwoKeyMap = new TwoKeyMap();\n private _css: TwoKeyMap = new TwoKeyMap();\n\n public setCss(bg: number, fg: number, value: string | null): void {\n this._css.set(bg, fg, value);\n }\n\n public getCss(bg: number, fg: number): string | null | undefined {\n return this._css.get(bg, fg);\n }\n\n public setColor(bg: number, fg: number, value: IColor | null): void {\n this._color.set(bg, fg, value);\n }\n\n public getColor(bg: number, fg: number): IColor | null | undefined {\n return this._color.get(bg, fg);\n }\n\n public clear(): void {\n this._color.clear();\n this._css.clear();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): boolean | void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n keypress?(text: string): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ColorContrastCache } from '../ColorContrastCache';\nimport { IThemeService } from './Services';\nimport { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';\nimport { color, css, NULL_COLOR } from '../../common/Color';\nimport { Disposable } from '../../common/Lifecycle';\nimport { IOptionsService, ITheme } from '../../common/services/Services';\nimport { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';\nimport { Emitter } from '../../common/Event';\n\ninterface IRestoreColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n ansi: IColor[];\n}\n\n\nconst DEFAULT_FOREGROUND = css.toColor('#ffffff');\nconst DEFAULT_BACKGROUND = css.toColor('#000000');\nconst DEFAULT_CURSOR = css.toColor('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;\nconst DEFAULT_SELECTION = {\n css: 'rgba(255, 255, 255, 0.3)',\n rgba: 0xFFFFFF4D\n};\nconst DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;\n\nexport class ThemeService extends Disposable implements IThemeService {\n public serviceBrand: undefined;\n\n private _colors: IColorSet;\n private _contrastCache: IColorContrastCache = new ColorContrastCache();\n private _halfContrastCache: IColorContrastCache = new ColorContrastCache();\n private _restoreColors!: IRestoreColorSet;\n\n public get colors(): ReadonlyColorSet { return this._colors; }\n\n private readonly _onChangeColors = this._register(new Emitter());\n public readonly onChangeColors = this._onChangeColors.event;\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n\n this._colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selectionForeground: undefined,\n selectionBackgroundTransparent: DEFAULT_SELECTION,\n selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,\n selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),\n scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),\n scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),\n scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),\n overviewRulerBorder: DEFAULT_FOREGROUND,\n ansi: DEFAULT_ANSI_COLORS.slice(),\n contrastCache: this._contrastCache,\n halfContrastCache: this._halfContrastCache\n };\n this._updateRestoreColors();\n this._setTheme(this._optionsService.rawOptions.theme);\n\n this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));\n this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n private _setTheme(theme: ITheme = {}): void {\n const colors = this._colors;\n colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);\n colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);\n colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));\n colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));\n colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);\n colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);\n colors.selectionInactiveBackgroundOpaque = color.blend(colors.background, colors.selectionInactiveBackgroundTransparent);\n colors.selectionForeground = theme.selectionForeground ? parseColor(theme.selectionForeground, NULL_COLOR) : undefined;\n if (colors.selectionForeground === NULL_COLOR) {\n colors.selectionForeground = undefined;\n }\n\n /**\n * If selection color is opaque, blend it with background with 0.3 opacity\n * Issue #2737\n */\n if (color.isOpaque(colors.selectionBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionBackgroundTransparent = color.opacity(colors.selectionBackgroundTransparent, opacity);\n }\n if (color.isOpaque(colors.selectionInactiveBackgroundTransparent)) {\n const opacity = 0.3;\n colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);\n }\n colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));\n colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));\n colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));\n colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);\n colors.ansi = DEFAULT_ANSI_COLORS.slice();\n colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n colors.ansi[2] = parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n colors.ansi[3] = parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n colors.ansi[4] = parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n colors.ansi[5] = parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n colors.ansi[6] = parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n colors.ansi[7] = parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n colors.ansi[8] = parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n colors.ansi[9] = parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n colors.ansi[10] = parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n colors.ansi[11] = parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n colors.ansi[12] = parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n colors.ansi[13] = parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n colors.ansi[14] = parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n colors.ansi[15] = parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n if (theme.extendedAnsi) {\n const colorCount = Math.min(colors.ansi.length - 16, theme.extendedAnsi.length);\n for (let i = 0; i < colorCount; i++) {\n colors.ansi[i + 16] = parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);\n }\n }\n // Clear the cache\n this._contrastCache.clear();\n this._halfContrastCache.clear();\n this._updateRestoreColors();\n this._onChangeColors.fire(this.colors);\n }\n\n public restoreColor(slot?: AllColorIndex): void {\n this._restoreColor(slot);\n this._onChangeColors.fire(this.colors);\n }\n\n private _restoreColor(slot: AllColorIndex | undefined): void {\n // unset slot restores all ansi colors\n if (slot === undefined) {\n for (let i = 0; i < this._restoreColors.ansi.length; ++i) {\n this._colors.ansi[i] = this._restoreColors.ansi[i];\n }\n return;\n }\n switch (slot) {\n case SpecialColorIndex.FOREGROUND:\n this._colors.foreground = this._restoreColors.foreground;\n break;\n case SpecialColorIndex.BACKGROUND:\n this._colors.background = this._restoreColors.background;\n break;\n case SpecialColorIndex.CURSOR:\n this._colors.cursor = this._restoreColors.cursor;\n break;\n default:\n this._colors.ansi[slot] = this._restoreColors.ansi[slot];\n }\n }\n\n public modifyColors(callback: (colors: IColorSet) => void): void {\n callback(this._colors);\n // Assume the change happened\n this._onChangeColors.fire(this.colors);\n }\n\n private _updateRestoreColors(): void {\n this._restoreColors = {\n foreground: this._colors.foreground,\n background: this._colors.background,\n cursor: this._colors.cursor,\n ansi: this._colors.ansi.slice()\n };\n }\n}\n\nfunction parseColor(\n cssString: string | undefined,\n fallback: IColor\n): IColor {\n if (cssString !== undefined) {\n try {\n return css.toColor(cssString);\n } catch {\n // no-op\n }\n }\n return fallback;\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n // digits 0-9\n 48: ['0', ')'],\n 49: ['1', '!'],\n 50: ['2', '@'],\n 51: ['3', '#'],\n 52: ['4', '$'],\n 53: ['5', '%'],\n 54: ['6', '^'],\n 55: ['7', '&'],\n 56: ['8', '*'],\n 57: ['9', '('],\n\n // special chars\n 186: [';', ':'],\n 187: ['=', '+'],\n 188: [',', '<'],\n 189: ['-', '_'],\n 190: ['.', '>'],\n 191: ['/', '?'],\n 192: ['`', '~'],\n 219: ['[', '{'],\n 220: ['\\\\', '|'],\n 221: [']', '}'],\n 222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n ev: IKeyboardEvent,\n applicationCursorMode: boolean,\n isMac: boolean,\n macOptionIsMeta: boolean\n): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key event to emit\n key: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n result.key = ev.ctrlKey ? '\\b' : C0.DEL; // ^H or ^?\n if (ev.altKey) {\n result.key = C0.ESC + result.key;\n }\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n if (ev.key === 'c' && ev.ctrlKey) {\n // HACK: Safari on iPad, iOS, AppleVisionPro sends key 13 when typing ctrl-c on hardware\n // keyboard\n result.key = C0.ETX;\n } else {\n result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;\n }\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n if (ev.altKey) {\n result.key = C0.ESC + C0.ESC;\n }\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (ev.metaKey) {\n break;\n }\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // or + are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OH';\n } else {\n result.key = C0.ESC + '[H';\n }\n break;\n case 35:\n // end\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n } else if (applicationCursorMode) {\n result.key = C0.ESC + 'OF';\n } else {\n result.key = C0.ESC + '[F';\n }\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_UP;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.type = KeyboardResultType.PAGE_DOWN;\n } else if (ev.ctrlKey) {\n result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n result.key = C0.NUL;\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n result.key = C0.DEL;\n } else if (ev.key === '/') {\n result.key = C0.US; // https://github.com/xtermjs/xterm.js/issues/5457\n } else if (ev.keyCode === 219) {\n result.key = C0.ESC;\n } else if (ev.keyCode === 220) {\n result.key = C0.FS;\n } else if (ev.keyCode === 221) {\n result.key = C0.GS;\n }\n } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n // On macOS this is a third level shift when !macOptionIsMeta. Use instead.\n const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n const key = keyMapping?.[!ev.shiftKey ? 0 : 1];\n if (key) {\n result.key = C0.ESC + key;\n } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n let keyString = String.fromCharCode(keyCode);\n if (ev.shiftKey) {\n keyString = keyString.toUpperCase();\n }\n result.key = C0.ESC + keyString;\n } else if (ev.keyCode === 32) {\n result.key = C0.ESC + (ev.ctrlKey ? C0.NUL : ' ');\n } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) {\n // Reference: https://github.com/xtermjs/xterm.js/issues/3725\n // Alt will produce a \"dead key\" (initate composition) with some\n // of the letters in US layout (e.g. N/E/U).\n // It's safe to match against Key* since no other `code` values begin with \"Key\".\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac\n let keyString = ev.code.slice(3, 4);\n if (!ev.shiftKey) {\n keyString = keyString.toLowerCase();\n }\n result.key = C0.ESC + keyString;\n result.cancel = true;\n }\n } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n result.type = KeyboardResultType.SELECT_ALL;\n }\n } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n // Include only keys that that result in a _single_ character; don't include num lock,\n // volume up, etc.\n result.key = ev.key;\n } else if (ev.key && ev.ctrlKey && ev.shiftKey) {\n switch (ev.code) {\n case 'Minus': result.key = C0.US; break; // ^_ (Ctrl+Shift+-_\n case 'Digit2': result.key = C0.NUL; break; // ^@ (Ctrl+Shift+2)\n case 'Digit6': result.key = C0.RS; break; // ^^ (Ctrl+Shift+6)\n }\n }\n break;\n }\n\n return result;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Kitty keyboard protocol implementation.\n * @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Kitty keyboard protocol enhancement flags (bitfield).\n */\nexport const enum KittyKeyboardFlags {\n NONE = 0b00000,\n /** Disambiguate escape codes - fixes ambiguous legacy encodings */\n DISAMBIGUATE_ESCAPE_CODES = 0b00001,\n /** Report event types - press/repeat/release */\n REPORT_EVENT_TYPES = 0b00010,\n /** Report alternate keys - shifted key and base layout key */\n REPORT_ALTERNATE_KEYS = 0b00100,\n /** Report all keys as escape codes - text-producing keys as CSI u */\n REPORT_ALL_KEYS_AS_ESCAPE_CODES = 0b01000,\n /** Report associated text - includes text codepoints in escape code */\n REPORT_ASSOCIATED_TEXT = 0b10000,\n}\n\n/**\n * Kitty keyboard event types.\n */\nexport const enum KittyKeyboardEventType {\n PRESS = 1,\n REPEAT = 2,\n RELEASE = 3,\n}\n\n/**\n * Kitty modifier bits (different from xterm modifier encoding).\n * Value sent = 1 + modifier_bits\n */\nexport const enum KittyKeyboardModifiers {\n SHIFT = 0b00000001,\n ALT = 0b00000010,\n CTRL = 0b00000100,\n SUPER = 0b00001000,\n HYPER = 0b00010000,\n META = 0b00100000,\n CAPS_LOCK = 0b01000000,\n NUM_LOCK = 0b10000000,\n}\n\n/**\n * Kitty keyboard protocol handler class.\n * Encapsulates all key code mappings and encoding logic.\n */\nexport class KittyKeyboard {\n /**\n * Functional key codes for Kitty protocol.\n * Keys that don't produce text have specific unicode codepoint mappings.\n */\n private readonly _functionalKeyCodes: { [key: string]: number } = {\n 'Escape': 27,\n 'Enter': 13,\n 'Tab': 9,\n 'Backspace': 127,\n 'CapsLock': 57358,\n 'ScrollLock': 57359,\n 'NumLock': 57360,\n 'PrintScreen': 57361,\n 'Pause': 57362,\n 'ContextMenu': 57363,\n // F13-F35 (F1-F12 use legacy encoding)\n 'F13': 57376,\n 'F14': 57377,\n 'F15': 57378,\n 'F16': 57379,\n 'F17': 57380,\n 'F18': 57381,\n 'F19': 57382,\n 'F20': 57383,\n 'F21': 57384,\n 'F22': 57385,\n 'F23': 57386,\n 'F24': 57387,\n 'F25': 57388,\n // Keypad keys\n 'KP_0': 57399,\n 'KP_1': 57400,\n 'KP_2': 57401,\n 'KP_3': 57402,\n 'KP_4': 57403,\n 'KP_5': 57404,\n 'KP_6': 57405,\n 'KP_7': 57406,\n 'KP_8': 57407,\n 'KP_9': 57408,\n 'KP_Decimal': 57409,\n 'KP_Divide': 57410,\n 'KP_Multiply': 57411,\n 'KP_Subtract': 57412,\n 'KP_Add': 57413,\n 'KP_Enter': 57414,\n 'KP_Equal': 57415,\n // Modifier keys\n 'ShiftLeft': 57441,\n 'ShiftRight': 57447,\n 'ControlLeft': 57442,\n 'ControlRight': 57448,\n 'AltLeft': 57443,\n 'AltRight': 57449,\n 'MetaLeft': 57444,\n 'MetaRight': 57450,\n // Media keys\n 'MediaPlayPause': 57430,\n 'MediaStop': 57432,\n 'MediaTrackNext': 57435,\n 'MediaTrackPrevious': 57436,\n 'AudioVolumeDown': 57438,\n 'AudioVolumeUp': 57439,\n 'AudioVolumeMute': 57440\n };\n\n /**\n * Keys that use CSI ~ encoding with a number parameter.\n */\n private readonly _csiTildeKeys: { [key: string]: number } = {\n 'Insert': 2,\n 'Delete': 3,\n 'PageUp': 5,\n 'PageDown': 6,\n 'F5': 15,\n 'F6': 17,\n 'F7': 18,\n 'F8': 19,\n 'F9': 20,\n 'F10': 21,\n 'F11': 23,\n 'F12': 24\n };\n\n /**\n * Keys that use CSI letter encoding (arrows, Home, End).\n */\n private readonly _csiLetterKeys: { [key: string]: string } = {\n 'ArrowUp': 'A',\n 'ArrowDown': 'B',\n 'ArrowRight': 'C',\n 'ArrowLeft': 'D',\n 'Home': 'H',\n 'End': 'F'\n };\n\n /**\n * Function keys F1-F4 use SS3 encoding without modifiers.\n */\n private readonly _ss3FunctionKeys: { [key: string]: string } = {\n 'F1': 'P',\n 'F2': 'Q',\n 'F3': 'R',\n 'F4': 'S'\n };\n\n /**\n * Map browser key codes to Kitty numpad codes.\n */\n private _getNumpadKeyCode(ev: IKeyboardEvent): number | undefined {\n if (ev.code.startsWith('Numpad')) {\n const suffix = ev.code.slice(6);\n if (suffix >= '0' && suffix <= '9') {\n return 57399 + parseInt(suffix, 10);\n }\n switch (suffix) {\n case 'Decimal': return 57409;\n case 'Divide': return 57410;\n case 'Multiply': return 57411;\n case 'Subtract': return 57412;\n case 'Add': return 57413;\n case 'Enter': return 57414;\n case 'Equal': return 57415;\n }\n }\n return undefined;\n }\n\n /**\n * Get modifier key code from code property.\n */\n private _getModifierKeyCode(ev: IKeyboardEvent): number | undefined {\n switch (ev.code) {\n case 'ShiftLeft': return 57441;\n case 'ShiftRight': return 57447;\n case 'ControlLeft': return 57442;\n case 'ControlRight': return 57448;\n case 'AltLeft': return 57443;\n case 'AltRight': return 57449;\n case 'MetaLeft': return 57444;\n case 'MetaRight': return 57450;\n }\n return undefined;\n }\n\n /**\n * Encode modifiers for Kitty protocol.\n * Returns 1 + modifier bits, or 0 if no modifiers.\n */\n private _encodeModifiers(ev: IKeyboardEvent): number {\n let mods = 0;\n if (ev.shiftKey) mods |= KittyKeyboardModifiers.SHIFT;\n if (ev.altKey) mods |= KittyKeyboardModifiers.ALT;\n if (ev.ctrlKey) mods |= KittyKeyboardModifiers.CTRL;\n if (ev.metaKey) mods |= KittyKeyboardModifiers.SUPER;\n return mods > 0 ? mods + 1 : 0;\n }\n\n /**\n * Get the unicode key code for a keyboard event.\n * Returns the lowercase codepoint for letters.\n * For shifted keys, uses the code property to get the base key.\n */\n private _getKeyCode(ev: IKeyboardEvent, macOptionAsAlt: boolean): number | undefined {\n const numpadCode = this._getNumpadKeyCode(ev);\n if (numpadCode !== undefined) {\n return numpadCode;\n }\n\n const modifierCode = this._getModifierKeyCode(ev);\n if (modifierCode !== undefined) {\n return modifierCode;\n }\n\n const funcCode = this._functionalKeyCodes[ev.key];\n if (funcCode !== undefined) {\n return funcCode;\n }\n\n if ((ev.shiftKey || (macOptionAsAlt && ev.altKey)) && ev.code) {\n if (ev.code.startsWith('Digit') && ev.code.length === 6) {\n const digit = ev.code.charAt(5);\n if (digit >= '0' && digit <= '9') {\n return digit.charCodeAt(0);\n }\n }\n if (ev.code.startsWith('Key') && ev.code.length === 4) {\n const letter = ev.code.charAt(3).toLowerCase();\n return letter.charCodeAt(0);\n }\n }\n\n if (ev.key.length === 1) {\n const code = ev.key.codePointAt(0)!;\n if (code >= 65 && code <= 90) {\n return code + 32;\n }\n return code;\n }\n\n return undefined;\n }\n\n /**\n * Check if a key is a modifier key.\n */\n private _isModifierKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';\n }\n\n /**\n * Check if a key is a lock key (CapsLock/NumLock/ScrollLock).\n *\n * Kitty's reference implementation classifies these as modifier keys for the\n * purpose of suppressing press events (kitty/keys.c `is_modifier_key()`\n * includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),\n * and its test suite asserts that a CapsLock press with no protocol flags\n * produces empty output.\n */\n private _isLockKey(ev: IKeyboardEvent): boolean {\n return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';\n }\n\n /**\n * Build CSI letter sequence for arrow keys, Home, End.\n * Format: CSI [1;mod] letter\n */\n private _buildCsiLetterSequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + '[' + letter;\n }\n\n /**\n * Build SS3 sequence for F1-F4.\n * Without modifiers: SS3 letter\n * With modifiers: CSI 1;mod letter\n */\n private _buildSs3Sequence(\n letter: string,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n if (modifiers > 0 || needsEventType) {\n let seq = C0.ESC + '[1;' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n seq += letter;\n return seq;\n }\n return C0.ESC + 'O' + letter;\n }\n\n /**\n * Build CSI ~ sequence for Insert, Delete, PageUp/Down, F5-F12.\n * Format: CSI number [;mod[:event]] ~\n */\n private _buildCsiTildeSequence(\n number: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n reportEventTypes: boolean\n ): string {\n const needsEventType = reportEventTypes && eventType !== KittyKeyboardEventType.PRESS;\n\n let seq = C0.ESC + '[' + number;\n if (modifiers > 0 || needsEventType) {\n seq += ';' + (modifiers > 0 ? modifiers : '1');\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n seq += '~';\n return seq;\n }\n\n /**\n * Build CSI u sequence.\n * Format: CSI keycode[:shifted[:base]] [;mod[:event][;text]] u\n */\n private _buildCsiUSequence(\n ev: IKeyboardEvent,\n keyCode: number,\n modifiers: number,\n eventType: KittyKeyboardEventType,\n flags: number,\n isFunc: boolean,\n isMod: boolean\n ): string {\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n const reportAlternateKeys = !!(flags & KittyKeyboardFlags.REPORT_ALTERNATE_KEYS);\n\n let seq = C0.ESC + '[' + keyCode;\n\n let shiftedKey: number | undefined;\n if (reportAlternateKeys && ev.shiftKey && ev.key.length === 1 && !isFunc && !isMod) {\n shiftedKey = ev.key.codePointAt(0);\n seq += ':' + shiftedKey;\n }\n\n const reportAssociatedText = !!(flags & KittyKeyboardFlags.REPORT_ASSOCIATED_TEXT) &&\n eventType !== KittyKeyboardEventType.RELEASE &&\n ev.key.length === 1 &&\n !isFunc &&\n !isMod &&\n !ev.ctrlKey;\n const textCode = reportAssociatedText ? ev.key.codePointAt(0) : undefined;\n\n const needsEventType = reportEventTypes &&\n eventType !== KittyKeyboardEventType.PRESS &&\n (eventType === KittyKeyboardEventType.RELEASE || textCode === undefined);\n\n if (modifiers > 0 || needsEventType || textCode !== undefined) {\n seq += ';';\n if (modifiers > 0) {\n seq += modifiers;\n } else if (needsEventType) {\n seq += '1';\n }\n if (needsEventType) {\n seq += ':' + eventType;\n }\n }\n\n if (textCode !== undefined) {\n seq += ';' + textCode;\n }\n\n seq += 'u';\n return seq;\n }\n\n /**\n * Evaluate a keyboard event using Kitty keyboard protocol.\n *\n * @param ev The keyboard event.\n * @param flags The active Kitty keyboard enhancement flags.\n * @param eventType The event type (press, repeat, release).\n * @param macOptionAsAlt When true, macOS Option-composed ev.key values are unwound via ev.code.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluate(\n ev: IKeyboardEvent,\n flags: number,\n eventType: KittyKeyboardEventType = KittyKeyboardEventType.PRESS,\n macOptionAsAlt: boolean = false\n ): IKeyboardResult {\n const result: IKeyboardResult = {\n type: KeyboardResultType.SEND_KEY,\n cancel: false,\n key: undefined\n };\n\n const modifiers = this._encodeModifiers(ev);\n const isMod = this._isModifierKey(ev);\n const reportEventTypes = !!(flags & KittyKeyboardFlags.REPORT_EVENT_TYPES);\n\n if (!reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) {\n return result;\n }\n\n if (isMod && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n // Spec \u00A7 \"Report all keys as escape codes\": \"Additionally, with this mode,\n // events for pressing modifier keys are reported.\" \u2014 i.e. *without* this\n // mode, modifier-key press events are suppressed. Kitty's is_modifier_key()\n // treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.\n if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const csiLetter = this._csiLetterKeys[ev.key];\n if (csiLetter) {\n result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const ss3Letter = this._ss3FunctionKeys[ev.key];\n if (ss3Letter) {\n result.key = this._buildSs3Sequence(ss3Letter, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const tildeCode = this._csiTildeKeys[ev.key];\n if (tildeCode !== undefined) {\n result.key = this._buildCsiTildeSequence(tildeCode, modifiers, eventType, reportEventTypes);\n result.cancel = true;\n return result;\n }\n\n const keyCode = this._getKeyCode(ev, macOptionAsAlt);\n if (keyCode === undefined) {\n return result;\n }\n\n // Special handling for Enter/Tab/Backspace.\n const specialKey = keyCode === 13 || keyCode === 9 || keyCode === 127;\n\n // Per spec, Enter/Tab/Backspace will not have release events unless \"Report all keys as escape\n // codes\" is also set.\n if (specialKey && eventType === KittyKeyboardEventType.RELEASE && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {\n return result;\n }\n\n const isFunc = this._functionalKeyCodes[ev.key] !== undefined || this._getNumpadKeyCode(ev) !== undefined;\n\n const useCsiU = !!(\n flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES ||\n (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) ||\n // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so\n // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity.\n // See: https://github.com/kovidgoyal/kitty/issues/9999\n ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) &&\n (\n // Per spec, Enter/Tab/Backspace \"still generate the same bytes as in legacy mode\" and\n // consider space to be a text-generating key, so these skip the isFunc fast-path and only\n // get CSI u when modifiers are present (handled below).\n (isFunc && !specialKey) ||\n (\n (modifiers > 0 && ev.key.length !== 1) ||\n modifiers - 1 > KittyKeyboardModifiers.SHIFT\n )\n )\n )\n );\n\n if (useCsiU) {\n result.key = this._buildCsiUSequence(ev, keyCode, modifiers, eventType, flags, isFunc, isMod);\n result.cancel = true;\n } else {\n const legacyByte = keyCode === 13 ? '\\r' : keyCode === 9 ? '\\t' : keyCode === 127 ? '\\x7f' : undefined;\n if (legacyByte) {\n result.key = legacyByte;\n } else if (ev.key.length === 1 && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n result.key = ev.key;\n }\n }\n\n return result;\n }\n\n /**\n * Check if Kitty protocol should be used based on flags.\n */\n public static shouldUseProtocol(flags: number): boolean {\n return flags > 0;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Win32 input mode implementation.\n * @see https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md\n *\n * Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n * Vk: Virtual key code (decimal)\n * Sc: Scan code (decimal)\n * Uc: Unicode character (decimal codepoint, 0 if none)\n * Kd: Key down (1) or up (0)\n * Cs: Control key state (modifier flags)\n * Rc: Repeat count (usually 1)\n */\n\nimport { IKeyboardEvent, IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../data/EscapeSequences';\n\n/**\n * Win32 control key state flags (from Windows API).\n */\nexport const enum Win32ControlKeyState {\n RIGHT_ALT_PRESSED = 0b000000001,\n LEFT_ALT_PRESSED = 0b000000010,\n RIGHT_CTRL_PRESSED = 0b000000100,\n LEFT_CTRL_PRESSED = 0b000001000,\n SHIFT_PRESSED = 0b000010000,\n NUMLOCK_ON = 0b000100000,\n SCROLLLOCK_ON = 0b001000000,\n CAPSLOCK_ON = 0b010000000,\n ENHANCED_KEY = 0b100000000,\n}\n\n/**\n * Win32 input mode handler. Lookup tables are only initialized when this class\n * is instantiated, reducing bundle size for environments that don't use this mode.\n */\nexport class Win32InputMode {\n /**\n * Mapping from browser KeyboardEvent.code to Win32 virtual key codes.\n * Based on https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes\n */\n private readonly _codeToVk: { [code: string]: number } = {\n // Letters\n 'KeyA': 0x41, 'KeyB': 0x42, 'KeyC': 0x43, 'KeyD': 0x44, 'KeyE': 0x45,\n 'KeyF': 0x46, 'KeyG': 0x47, 'KeyH': 0x48, 'KeyI': 0x49, 'KeyJ': 0x4A,\n 'KeyK': 0x4B, 'KeyL': 0x4C, 'KeyM': 0x4D, 'KeyN': 0x4E, 'KeyO': 0x4F,\n 'KeyP': 0x50, 'KeyQ': 0x51, 'KeyR': 0x52, 'KeyS': 0x53, 'KeyT': 0x54,\n 'KeyU': 0x55, 'KeyV': 0x56, 'KeyW': 0x57, 'KeyX': 0x58, 'KeyY': 0x59,\n 'KeyZ': 0x5A,\n\n // Digits\n 'Digit0': 0x30, 'Digit1': 0x31, 'Digit2': 0x32, 'Digit3': 0x33, 'Digit4': 0x34,\n 'Digit5': 0x35, 'Digit6': 0x36, 'Digit7': 0x37, 'Digit8': 0x38, 'Digit9': 0x39,\n\n // Function keys\n 'F1': 0x70, 'F2': 0x71, 'F3': 0x72, 'F4': 0x73, 'F5': 0x74, 'F6': 0x75,\n 'F7': 0x76, 'F8': 0x77, 'F9': 0x78, 'F10': 0x79, 'F11': 0x7A, 'F12': 0x7B,\n 'F13': 0x7C, 'F14': 0x7D, 'F15': 0x7E, 'F16': 0x7F, 'F17': 0x80, 'F18': 0x81,\n 'F19': 0x82, 'F20': 0x83, 'F21': 0x84, 'F22': 0x85, 'F23': 0x86, 'F24': 0x87,\n\n // Numpad\n 'Numpad0': 0x60, 'Numpad1': 0x61, 'Numpad2': 0x62, 'Numpad3': 0x63, 'Numpad4': 0x64,\n 'Numpad5': 0x65, 'Numpad6': 0x66, 'Numpad7': 0x67, 'Numpad8': 0x68, 'Numpad9': 0x69,\n 'NumpadMultiply': 0x6A, 'NumpadAdd': 0x6B, 'NumpadSeparator': 0x6C,\n 'NumpadSubtract': 0x6D, 'NumpadDecimal': 0x6E, 'NumpadDivide': 0x6F,\n 'NumpadEnter': 0x0D, // Same as Enter but with ENHANCED_KEY flag\n 'NumLock': 0x90,\n\n // Navigation\n 'ArrowUp': 0x26, 'ArrowDown': 0x28, 'ArrowLeft': 0x25, 'ArrowRight': 0x27,\n 'Home': 0x24, 'End': 0x23, 'PageUp': 0x21, 'PageDown': 0x22,\n 'Insert': 0x2D, 'Delete': 0x2E,\n\n // Modifiers\n 'ShiftLeft': 0x10, 'ShiftRight': 0x10,\n 'ControlLeft': 0x11, 'ControlRight': 0x11,\n 'AltLeft': 0x12, 'AltRight': 0x12,\n 'MetaLeft': 0x5B, 'MetaRight': 0x5C,\n 'CapsLock': 0x14, 'ScrollLock': 0x91,\n\n // Special keys\n 'Escape': 0x1B, 'Enter': 0x0D, 'Tab': 0x09, 'Space': 0x20,\n 'Backspace': 0x08, 'Pause': 0x13, 'ContextMenu': 0x5D, 'PrintScreen': 0x2C,\n\n // OEM keys (US keyboard layout)\n 'Semicolon': 0xBA, // ;:\n 'Equal': 0xBB, // =+\n 'Comma': 0xBC, // ,<\n 'Minus': 0xBD, // -_\n 'Period': 0xBE, // .>\n 'Slash': 0xBF, // /?\n 'Backquote': 0xC0, // `~\n 'BracketLeft': 0xDB, // [{\n 'Backslash': 0xDC, // \\|\n 'BracketRight': 0xDD, // ]}\n 'Quote': 0xDE, // '\"\n 'IntlBackslash': 0xE2 // Non-US backslash\n };\n\n /**\n * Mapping from browser KeyboardEvent.code to approximate Win32 scan codes.\n * Note: Scan codes can vary by keyboard layout. These are approximations\n * based on standard US keyboard layout.\n */\n private readonly _codeToScancode: { [code: string]: number } = {\n // Letters (row by row)\n 'KeyQ': 0x10, 'KeyW': 0x11, 'KeyE': 0x12, 'KeyR': 0x13, 'KeyT': 0x14,\n 'KeyY': 0x15, 'KeyU': 0x16, 'KeyI': 0x17, 'KeyO': 0x18, 'KeyP': 0x19,\n 'KeyA': 0x1E, 'KeyS': 0x1F, 'KeyD': 0x20, 'KeyF': 0x21, 'KeyG': 0x22,\n 'KeyH': 0x23, 'KeyJ': 0x24, 'KeyK': 0x25, 'KeyL': 0x26,\n 'KeyZ': 0x2C, 'KeyX': 0x2D, 'KeyC': 0x2E, 'KeyV': 0x2F, 'KeyB': 0x30,\n 'KeyN': 0x31, 'KeyM': 0x32,\n\n // Digits\n 'Digit1': 0x02, 'Digit2': 0x03, 'Digit3': 0x04, 'Digit4': 0x05, 'Digit5': 0x06,\n 'Digit6': 0x07, 'Digit7': 0x08, 'Digit8': 0x09, 'Digit9': 0x0A, 'Digit0': 0x0B,\n\n // Function keys\n 'F1': 0x3B, 'F2': 0x3C, 'F3': 0x3D, 'F4': 0x3E, 'F5': 0x3F, 'F6': 0x40,\n 'F7': 0x41, 'F8': 0x42, 'F9': 0x43, 'F10': 0x44, 'F11': 0x57, 'F12': 0x58,\n\n // Numpad\n 'Numpad0': 0x52, 'Numpad1': 0x4F, 'Numpad2': 0x50, 'Numpad3': 0x51, 'Numpad4': 0x4B,\n 'Numpad5': 0x4C, 'Numpad6': 0x4D, 'Numpad7': 0x47, 'Numpad8': 0x48, 'Numpad9': 0x49,\n 'NumpadMultiply': 0x37, 'NumpadAdd': 0x4E, 'NumpadSubtract': 0x4A,\n 'NumpadDecimal': 0x53, 'NumpadDivide': 0x35, 'NumpadEnter': 0x1C,\n 'NumLock': 0x45,\n\n // Navigation (extended keys)\n 'ArrowUp': 0x48, 'ArrowDown': 0x50, 'ArrowLeft': 0x4B, 'ArrowRight': 0x4D,\n 'Home': 0x47, 'End': 0x4F, 'PageUp': 0x49, 'PageDown': 0x51,\n 'Insert': 0x52, 'Delete': 0x53,\n\n // Modifiers\n 'ShiftLeft': 0x2A, 'ShiftRight': 0x36,\n 'ControlLeft': 0x1D, 'ControlRight': 0x1D,\n 'AltLeft': 0x38, 'AltRight': 0x38,\n 'CapsLock': 0x3A, 'ScrollLock': 0x46,\n\n // Special keys\n 'Escape': 0x01, 'Enter': 0x1C, 'Tab': 0x0F, 'Space': 0x39,\n 'Backspace': 0x0E, 'Pause': 0x45,\n\n // OEM keys\n 'Semicolon': 0x27, 'Equal': 0x0D, 'Comma': 0x33, 'Minus': 0x0C,\n 'Period': 0x34, 'Slash': 0x35, 'Backquote': 0x29,\n 'BracketLeft': 0x1A, 'Backslash': 0x2B, 'BracketRight': 0x1B, 'Quote': 0x28\n };\n\n /**\n * Codes that represent enhanced keys (extended keyboard keys).\n */\n private readonly _enhancedKeyCodes = new Set([\n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n 'Home', 'End', 'PageUp', 'PageDown', 'Insert', 'Delete',\n 'NumpadEnter', 'NumpadDivide',\n 'ControlRight', 'AltRight',\n 'PrintScreen', 'Pause', 'ContextMenu',\n 'MetaLeft', 'MetaRight'\n ]);\n\n /**\n * Mapping of special keys (ev.key values) to their Unicode control character codes.\n * These keys have multi-character ev.key strings but produce control characters.\n * @see https://docs.microsoft.com/en-us/windows/console/key-event-record-str\n */\n private readonly _keyToControlChar: { [key: string]: number } = {\n 'Enter': 0x0D, // Carriage return\n 'Backspace': 0x08, // Backspace\n 'Tab': 0x09, // Horizontal tab\n 'Escape': 0x1B // Escape\n };\n\n /**\n * Get the Win32 virtual key code for a keyboard event.\n */\n private _getVirtualKeyCode(ev: IKeyboardEvent): number {\n const vk = this._codeToVk[ev.code];\n if (vk !== undefined) {\n return vk;\n }\n // Fall back to keyCode for unmapped keys\n return ev.keyCode || 0;\n }\n\n /**\n * Get the Win32 scan code for a keyboard event.\n * Returns 0 if unknown (scan codes vary by hardware).\n */\n private _getScanCode(ev: IKeyboardEvent): number {\n return this._codeToScancode[ev.code] || 0;\n }\n\n /**\n * Get the unicode character for a keyboard event.\n * Returns 0 for non-character keys.\n */\n private _getUnicodeChar(ev: IKeyboardEvent): number {\n // Handle special keys that produce control characters\n // Ctrl modifies some of these: Ctrl+Enter=LF, Ctrl+Backspace=DEL\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n if (ev.key === 'Enter') {\n return 0x0A; // Line feed (Ctrl+Enter)\n }\n if (ev.key === 'Backspace') {\n return 0x7F; // DEL (Ctrl+Backspace)\n }\n }\n\n // Check for special keys that always produce control characters\n const controlChar = this._keyToControlChar[ev.key];\n if (controlChar !== undefined) {\n return controlChar;\n }\n\n // Only single-character keys produce unicode output\n if (ev.key.length === 1) {\n const codePoint = ev.key.codePointAt(0) || 0;\n\n // Handle Ctrl+letter combinations - these produce control characters (0x01-0x1A)\n if (ev.ctrlKey && !ev.altKey && !ev.metaKey) {\n // Convert A-Z or a-z to control character (Ctrl+A = 0x01, Ctrl+C = 0x03, etc.)\n if (codePoint >= 0x41 && codePoint <= 0x5A) { // A-Z\n return codePoint - 0x40;\n }\n if (codePoint >= 0x61 && codePoint <= 0x7A) { // a-z\n return codePoint - 0x60;\n }\n }\n\n return codePoint;\n }\n return 0;\n }\n\n /**\n * Get the Win32 control key state flags.\n */\n private _getControlKeyState(ev: IKeyboardEvent): number {\n let state = 0;\n\n if (ev.shiftKey) {\n state |= Win32ControlKeyState.SHIFT_PRESSED;\n }\n\n // Note: We can't distinguish left/right for ctrl/alt in standard browser events,\n // so we use the generic pressed flags. The right-side flags are used when\n // we can detect them (e.g., via code property).\n if (ev.ctrlKey) {\n if (ev.code === 'ControlRight') {\n state |= Win32ControlKeyState.RIGHT_CTRL_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_CTRL_PRESSED;\n }\n }\n\n if (ev.altKey) {\n if (ev.code === 'AltRight') {\n state |= Win32ControlKeyState.RIGHT_ALT_PRESSED;\n } else {\n state |= Win32ControlKeyState.LEFT_ALT_PRESSED;\n }\n }\n\n // Check for enhanced key\n if (this._enhancedKeyCodes.has(ev.code)) {\n state |= Win32ControlKeyState.ENHANCED_KEY;\n }\n\n return state;\n }\n\n /**\n * Evaluate a keyboard event using Win32 input mode.\n *\n * @param ev The keyboard event.\n * @param isKeyDown Whether this is a keydown (true) or keyup (false) event.\n * @returns The keyboard result with the encoded key sequence.\n */\n public evaluateKeyboardEvent(ev: IKeyboardEvent, isKeyDown: boolean): IKeyboardResult {\n const vk = this._getVirtualKeyCode(ev);\n const sc = this._getScanCode(ev);\n const uc = this._getUnicodeChar(ev);\n const kd = isKeyDown ? 1 : 0;\n const cs = this._getControlKeyState(ev);\n const rc = 1; // Repeat count, always 1 for now\n\n // Format: CSI Vk ; Sc ; Uc ; Kd ; Cs ; Rc _\n return {\n type: KeyboardResultType.SEND_KEY,\n cancel: true,\n key: `${C0.ESC}[${vk};${sc};${uc};${kd};${cs};${rc}_`\n };\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IKeyboardService } from './Services';\nimport { evaluateKeyboardEvent } from '../../common/input/Keyboard';\nimport { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';\nimport { Win32InputMode } from '../../common/input/Win32InputMode';\nimport { isMac } from '../../common/Platform';\nimport { ICoreService, IOptionsService } from '../../common/services/Services';\nimport { IKeyboardResult } from '../../common/Types';\n\nexport class KeyboardService implements IKeyboardService {\n public serviceBrand: undefined;\n\n private _win32InputMode: Win32InputMode | undefined;\n private _kittyKeyboard: KittyKeyboard | undefined;\n\n constructor(\n @ICoreService private readonly _coreService: ICoreService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n }\n\n private _getWin32InputMode(): Win32InputMode {\n this._win32InputMode ??= new Win32InputMode();\n return this._win32InputMode;\n }\n\n private _getKittyKeyboard(): KittyKeyboard {\n this._kittyKeyboard ??= new KittyKeyboard();\n return this._kittyKeyboard;\n }\n\n public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {\n // Win32 input mode takes priority (most raw)\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, true);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return this.useKitty\n ? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS, isMac && this._optionsService.rawOptions.macOptionIsMeta)\n : evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);\n }\n\n public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {\n // Win32 input mode sends key up events\n if (this.useWin32InputMode) {\n return this._getWin32InputMode().evaluateKeyboardEvent(event, false);\n }\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {\n return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE, isMac && this._optionsService.rawOptions.macOptionIsMeta);\n }\n return undefined;\n }\n\n public get useKitty(): boolean {\n const kittyFlags = this._coreService.kittyKeyboard.flags;\n return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));\n }\n\n public get useWin32InputMode(): boolean {\n return !!(this._optionsService.rawOptions.vtExtensions?.win32InputMode && this._coreService.decPrivateModes.win32InputMode);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This was heavily inspired from microsoft/vscode's dependency injection system (MIT).\n */\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IInstantiationService } from './Services';\nimport { IServiceIdentifier, getServiceDependencies } from './ServiceRegistry';\n\nexport class ServiceCollection {\n\n private _entries = new Map, any>();\n\n constructor(...entries: [IServiceIdentifier, any][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n public set(id: IServiceIdentifier, instance: T): T {\n const result = this._entries.get(id);\n this._entries.set(id, instance);\n return result;\n }\n\n public forEach(callback: (id: IServiceIdentifier, instance: any) => any): void {\n for (const [key, value] of this._entries.entries()) {\n callback(key, value);\n }\n }\n\n public has(id: IServiceIdentifier): boolean {\n return this._entries.has(id);\n }\n\n public get(id: IServiceIdentifier): T | undefined {\n return this._entries.get(id);\n }\n}\n\nexport class InstantiationService implements IInstantiationService {\n public serviceBrand: undefined;\n\n private readonly _services: ServiceCollection = new ServiceCollection();\n\n constructor() {\n this._services.set(IInstantiationService, this);\n }\n\n public setService(id: IServiceIdentifier, instance: T): void {\n this._services.set(id, instance);\n }\n\n public getService(id: IServiceIdentifier): T | undefined {\n return this._services.get(id);\n }\n\n public createInstance(ctor: any, ...args: any[]): T {\n const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index);\n\n const serviceArgs: any[] = [];\n for (const dependency of serviceDependencies) {\n const service = this._services.get(dependency.id);\n if (!service) {\n throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id._id}.`);\n }\n serviceArgs.push(service);\n }\n\n const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;\n\n // check for argument mismatches, adjust static args if needed\n if (args.length !== firstServiceArgPos) {\n throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);\n }\n\n // now create the instance\n return new ctor(...[...args, ...serviceArgs]);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { ILogService, IOptionsService, LogLevelEnum } from './Services';\n\ntype LogType = (message?: any, ...optionalParams: any[]) => void;\n\ninterface IConsole {\n log: LogType;\n error: LogType;\n info: LogType;\n trace: LogType;\n warn: LogType;\n}\n\n// console is available on both node.js and browser contexts but the common\n// module doesn't depend on them so we need to explicitly declare it.\ndeclare const console: IConsole;\n\nconst optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {\n trace: LogLevelEnum.TRACE,\n debug: LogLevelEnum.DEBUG,\n info: LogLevelEnum.INFO,\n warn: LogLevelEnum.WARN,\n error: LogLevelEnum.ERROR,\n off: LogLevelEnum.OFF\n};\n\nconst LOG_PREFIX = 'xterm.js: ';\n\nexport class LogService extends Disposable implements ILogService {\n public serviceBrand: any;\n\n private _logLevel: LogLevelEnum = LogLevelEnum.OFF;\n public get logLevel(): LogLevelEnum { return this._logLevel; }\n\n constructor(\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this._updateLogLevel();\n this._register(this._optionsService.onSpecificOptionChange('logLevel', () => this._updateLogLevel()));\n }\n\n private _updateLogLevel(): void {\n this._logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];\n }\n\n private _evalLazyOptionalParams(optionalParams: any[]): void {\n for (let i = 0; i < optionalParams.length; i++) {\n if (typeof optionalParams[i] === 'function') {\n optionalParams[i] = optionalParams[i]();\n }\n }\n }\n\n private _log(type: LogType, message: string, optionalParams: any[]): void {\n this._evalLazyOptionalParams(optionalParams);\n type.call(console, (this._optionsService.options.logger ? '' : LOG_PREFIX) + message, ...optionalParams);\n }\n\n public trace(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.TRACE) {\n this._log(this._optionsService.options.logger?.trace.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public debug(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.DEBUG) {\n this._log(this._optionsService.options.logger?.debug.bind(this._optionsService.options.logger) ?? console.log, message, optionalParams);\n }\n }\n\n public info(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.INFO) {\n this._log(this._optionsService.options.logger?.info.bind(this._optionsService.options.logger) ?? console.info, message, optionalParams);\n }\n }\n\n public warn(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.WARN) {\n this._log(this._optionsService.options.logger?.warn.bind(this._optionsService.options.logger) ?? console.warn, message, optionalParams);\n }\n }\n\n public error(message: string, ...optionalParams: any[]): void {\n if (this._logLevel <= LogLevelEnum.ERROR) {\n this._log(this._optionsService.options.logger?.error.bind(this._optionsService.options.logger) ?? console.error, message, optionalParams);\n }\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from './Lifecycle';\nimport { Emitter, type IEvent } from './Event';\n\nexport interface IInsertEvent {\n index: number;\n amount: number;\n}\n\nexport interface IDeleteEvent {\n index: number;\n amount: number;\n}\n\nexport interface ICircularList {\n length: number;\n maxLength: number;\n isFull: boolean;\n\n onDeleteEmitter: Emitter;\n onDelete: IEvent;\n onInsertEmitter: Emitter;\n onInsert: IEvent;\n onTrimEmitter: Emitter;\n onTrim: IEvent;\n\n get(index: number): T | undefined;\n set(index: number, value: T): void;\n push(value: T): void;\n recycle(): T;\n pop(): T | undefined;\n splice(start: number, deleteCount: number, ...items: T[]): void;\n trimStart(count: number): void;\n shiftElements(start: number, count: number, offset: number): void;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList extends Disposable implements ICircularList {\n protected _array: (T | undefined)[];\n private _startIndex: number;\n private _length: number;\n\n public readonly onDeleteEmitter = this._register(new Emitter());\n public readonly onDelete = this.onDeleteEmitter.event;\n public readonly onInsertEmitter = this._register(new Emitter());\n public readonly onInsert = this.onInsertEmitter.event;\n public readonly onTrimEmitter = this._register(new Emitter());\n public readonly onTrim = this.onTrimEmitter.event;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n const newArray = new Array(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @returns The value corresponding to the index.\n */\n public get(index: number): T | undefined {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T | undefined): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Advance ringbuffer index and return current element for recycling.\n * Note: The buffer must be full for this method to work.\n * @throws When the buffer is not full.\n */\n public recycle(): T {\n if (this._length !== this._maxLength) {\n throw new Error('Can only recycle when the buffer is full');\n }\n this._startIndex = ++this._startIndex % this._maxLength;\n this.onTrimEmitter.fire(1);\n return this._array[this._getCyclicIndex(this._length - 1)]!;\n }\n\n /**\n * Ringbuffer is at max length.\n */\n public get isFull(): boolean {\n return this._length === this._maxLength;\n }\n\n /**\n * Removes and returns the last value on the list.\n * @returns The popped value.\n */\n public pop(): T | undefined {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n this.onDeleteEmitter.fire({ index: start, amount: deleteCount });\n }\n\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n if (items.length) {\n this.onInsertEmitter.fire({ index: start, amount: items.length });\n }\n\n // Adjust length as needed\n if (this._length + items.length > this._maxLength) {\n const countToTrim = (this._length + items.length) - this._maxLength;\n this._startIndex += countToTrim;\n this._length = this._maxLength;\n this.onTrimEmitter.fire(countToTrim);\n } else {\n this._length += items.length;\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.onTrimEmitter.fire(count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this._maxLength) {\n this._length--;\n this._startIndex++;\n this.onTrimEmitter.fire(1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this._maxLength;\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Accumulates string data from multiple chunks without O(n\u00B2) string concatenation.\n */\nexport class StringBuilder {\n private _chunks: string[] = [];\n private _length = 0;\n\n public get length(): number {\n return this._length;\n }\n\n public reset(): void {\n this._chunks.length = 0;\n this._length = 0;\n }\n\n public append(chunk: string): void {\n this._chunks.push(chunk);\n this._length += chunk.length;\n }\n\n public toString(): string {\n return this._chunks.join('');\n }\n}\n\n/**\n * String builder that rejects payloads larger than a fixed limit.\n */\nexport class LimitedStringBuilder {\n private readonly _builder = new StringBuilder();\n\n constructor(private readonly _limit: number) { }\n\n public get length(): number {\n return this._builder.length;\n }\n\n public get limit(): number {\n return this._limit;\n }\n\n public reset(): void {\n this._builder.reset();\n }\n\n /**\n * @returns true if the limit was exceeded (buffer is cleared in that case)\n */\n public append(chunk: string): boolean {\n this._builder.append(chunk);\n if (this._builder.length > this._limit) {\n this._builder.reset();\n return true;\n }\n return false;\n }\n\n public toString(): string {\n return this._builder.toString();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from './Types';\nimport { AttributeData } from './AttributeData';\nimport { CellData } from './CellData';\nimport { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from './Constants';\nimport { stringFromCodePoint } from '../input/TextDecoder';\nimport { StringBuilder } from '../StringBuilder';\n\n// Buffer memory layout:\n//\n// [0]: content `uint32_t` - wcwidth(2) comb(1) codepoint(21)\n// [1]: fg `uint32_t` - flags(8) r(8) g(8) b(8)\n// [2]: bg `uint32_t` - flags(8) r(8) g(8) b(8)\n\nconst enum Constants {\n /** The number of 32 bit array indices taken by one cell. */\n CELL_INDICIES = 3,\n /** Factor when to cleanup underlying array buffer after shrinking. */\n CLEANUP_THRESHOLD = 2\n}\n\n/**\n * Cell member indices.\n *\n * Direct access:\n * `content = data[column * Constants.CELL_INDICIES + Cell.CONTENT];`\n * `fg = data[column * Constants.CELL_INDICIES + Cell.FG];`\n * `bg = data[column * Constants.CELL_INDICIES + Cell.BG];`\n */\nconst enum Cell {\n CONTENT = 0,\n FG = 1, // currently simply holds all known attrs\n BG = 2 // currently unused\n}\n\nexport const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData());\n\n// Work variables to avoid garbage collection\nlet $startIndex = 0;\nconst $workCell = new CellData();\nconst $translateToStringBuilder = new StringBuilder();\n\nexport interface IBufferLineStringCacheEntry {\n value: string | undefined;\n isTrimmed: boolean;\n generation: number;\n}\n\nexport interface IBufferLineStringCache {\n generation: number;\n allocateEntry(): IBufferLineStringCacheEntry;\n touch?(): void;\n}\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n * Use these for data that is already UTF32.\n * Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n * This method takes a CellData object and stores the data in the buffer.\n * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n protected _data: Uint32Array;\n /** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */\n protected _combined: {[index: number]: string} = {};\n /** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */\n protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};\n protected _stringCacheEntryRef: WeakRef | undefined;\n public length: number;\n\n constructor(\n protected readonly _stringCache: IBufferLineStringCache,\n cols: number,\n fillCellData?: ICellData,\n public isWrapped: boolean = false\n ) {\n this._data = new Uint32Array(cols * Constants.CELL_INDICIES);\n const cell = fillCellData ?? CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n for (let i = 0; i < cols; ++i) {\n this.setCell(i, cell);\n }\n this.length = cols;\n }\n\n /**\n * Get cell data CharData.\n * @deprecated\n */\n public get(index: number): CharData {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n return [\n this._data[index * Constants.CELL_INDICIES + Cell.FG],\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index]\n : (cp) ? stringFromCodePoint(cp) : '',\n content >> Content.WIDTH_SHIFT,\n (content & Content.IS_COMBINED_MASK)\n ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n : cp\n ];\n }\n\n /**\n * Set cell data from CharData.\n * @deprecated\n */\n public set(index: number, value: CharData): void {\n this._invalidateStringCache();\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n this._combined[index] = value[1];\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n } else {\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n }\n }\n\n /**\n * primitive getters\n * use these when only one value is needed, otherwise use `loadCell`\n */\n public getWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n }\n\n /** Test whether content has width. */\n public hasWidth(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.WIDTH_MASK;\n }\n\n /** Get FG cell component. */\n public getFg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.FG];\n }\n\n /** Get BG cell component. */\n public getBg(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG];\n }\n\n /**\n * Test whether contains any chars.\n * Basically an empty has no content, but other cells might differ in FG/BG\n * from real empty cells.\n */\n public hasContent(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n }\n\n /**\n * Get codepoint of the cell.\n * To be in line with `code` in CharData this either returns\n * a single UTF32 codepoint or the last codepoint of a combined string.\n */\n public getCodePoint(index: number): number {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index].charCodeAt(this._combined[index].length - 1);\n }\n return content & Content.CODEPOINT_MASK;\n }\n\n /** Test whether the cell contains a combined string. */\n public isCombined(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n }\n\n /** Returns the string content of the cell. */\n public getString(index: number): string {\n const content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n return this._combined[index];\n }\n if (content & Content.CODEPOINT_MASK) {\n return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n }\n // return empty string for empty cells\n return '';\n }\n\n /** Get state of protected flag. */\n public isProtected(index: number): number {\n return this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.PROTECTED;\n }\n\n /**\n * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n * to GC as it significantly reduced the amount of new objects/references needed.\n */\n public loadCell(index: number, cell: ICellData): ICellData {\n $startIndex = index * Constants.CELL_INDICIES;\n cell.content = this._data[$startIndex + Cell.CONTENT];\n cell.fg = this._data[$startIndex + Cell.FG];\n cell.bg = this._data[$startIndex + Cell.BG];\n if (cell.content & Content.IS_COMBINED_MASK) {\n cell.combinedData = this._combined[index];\n } else {\n cell.combinedData = '';\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n cell.extended = this._extendedAttrs[index]!;\n } else {\n // Do not mutate cell.extended in place: it may still reference this line's map entry from a\n // prior loadCell into a reused CellData (e.g. $workCell during insert/delete).\n cell.extended = DEFAULT_ATTR_DATA.extended.clone();\n }\n return cell;\n }\n\n /**\n * Set data at `index` to `cell`.\n */\n public setCell(index: number, cell: ICellData): void {\n this._invalidateStringCache();\n if (cell.content & Content.IS_COMBINED_MASK) {\n this._combined[index] = cell.combinedData;\n }\n if (cell.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = cell.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = cell.bg;\n }\n\n /**\n * Set cell data from input handler.\n * Since the input handler see the incoming chars as UTF32 codepoints,\n * it gets an optimized access method.\n */\n public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {\n this._invalidateStringCache();\n if (attrs.bg & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[index] = attrs.extended;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n this._data[index * Constants.CELL_INDICIES + Cell.FG] = attrs.fg;\n this._data[index * Constants.CELL_INDICIES + Cell.BG] = attrs.bg;\n }\n\n /**\n * Add a codepoint to a cell from input handler.\n * During input stage combining chars with a width of 0 follow and stack\n * onto a leading char. Since we already set the attrs\n * by the previous `setDataFromCodePoint` call, we can omit it here.\n */\n public addCodepointToCell(index: number, codePoint: number, width: number): void {\n this._invalidateStringCache();\n let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];\n if (content & Content.IS_COMBINED_MASK) {\n // we already have a combined string, simply add\n this._combined[index] += stringFromCodePoint(codePoint);\n } else {\n if (content & Content.CODEPOINT_MASK) {\n // normal case for combining chars:\n // - move current leading char + new one into combined string\n // - set combined flag\n this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n content |= Content.IS_COMBINED_MASK;\n } else {\n // should not happen - we actually have no data in the cell yet\n // simply set the data in the cell buffer with a width of 1\n content = codePoint | (1 << Content.WIDTH_SHIFT);\n }\n }\n if (width) {\n content &= ~Content.WIDTH_MASK;\n content |= width << Content.WIDTH_SHIFT;\n }\n this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = content;\n }\n\n public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n\n // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n\n if (n < this.length - pos) {\n for (let i = this.length - pos - n - 1; i >= 0; --i) {\n this.setCell(pos + n + i, this.loadCell(pos + i, $workCell));\n }\n for (let i = 0; i < n; ++i) {\n this.setCell(pos + i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at line end: reset last cell if it is first cell of a wide char\n if (this.getWidth(this.length - 1) === 2) {\n this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);\n }\n }\n\n public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n this._invalidateStringCache();\n pos %= this.length;\n if (n < this.length - pos) {\n for (let i = 0; i < this.length - pos - n; ++i) {\n this.setCell(pos + i, this.loadCell(pos + n + i, $workCell));\n }\n for (let i = this.length - n; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n for (let i = pos; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n // handle fullwidth at pos:\n // - reset pos-1 if wide char\n // - reset pos if width==0 (previous second cell of a wide char)\n if (pos && this.getWidth(pos - 1) === 2) {\n this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData);\n }\n if (this.getWidth(pos) === 0 && !this.hasContent(pos)) {\n this.setCellFromCodepoint(pos, 0, 1, fillCellData);\n }\n }\n\n public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n while (start < end && start < this.length) {\n if (!this.isProtected(start)) {\n this.setCell(start, fillCellData);\n }\n start++;\n }\n return;\n }\n\n // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char\n if (start && this.getWidth(start - 1) === 2) {\n this.setCellFromCodepoint(start - 1, 0, 1, fillCellData);\n }\n // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char\n if (end < this.length && this.getWidth(end - 1) === 2) {\n this.setCellFromCodepoint(end, 0, 1, fillCellData);\n }\n\n while (start < end && start < this.length) {\n this.setCell(start++, fillCellData);\n }\n }\n\n /**\n * Resize BufferLine to `cols` filling excess cells with `fillCellData`.\n * The underlying array buffer will not change if there is still enough space\n * to hold the new buffer line data.\n * Returns a boolean indicating, whether a `cleanupMemory` call would free\n * excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).\n */\n public resize(cols: number, fillCellData: ICellData): boolean {\n this._invalidateStringCache();\n if (cols === this.length) {\n return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n const uint32Cells = cols * Constants.CELL_INDICIES;\n if (cols > this.length) {\n if (this._data.buffer.byteLength >= uint32Cells * 4) {\n // optimization: avoid alloc and data copy if buffer has enough room\n this._data = new Uint32Array(this._data.buffer, 0, uint32Cells);\n } else {\n // slow path: new alloc and full data copy\n const data = new Uint32Array(uint32Cells);\n data.set(this._data);\n this._data = data;\n }\n for (let i = this.length; i < cols; ++i) {\n this.setCell(i, fillCellData);\n }\n } else {\n // optimization: just shrink the view on existing buffer\n this._data = this._data.subarray(0, uint32Cells);\n // Remove any cut off combined data\n const keys = Object.keys(this._combined);\n for (let i = 0; i < keys.length; i++) {\n const key = parseInt(keys[i], 10);\n if (key >= cols) {\n delete this._combined[key];\n }\n }\n // remove any cut off extended attributes\n const extKeys = Object.keys(this._extendedAttrs);\n for (let i = 0; i < extKeys.length; i++) {\n const key = parseInt(extKeys[i], 10);\n if (key >= cols) {\n delete this._extendedAttrs[key];\n }\n }\n }\n this.length = cols;\n return uint32Cells * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;\n }\n\n /**\n * Cleanup underlying array buffer.\n * A cleanup will be triggered if the array buffer exceeds the actual used\n * memory by a factor of Constants.CLEANUP_THRESHOLD.\n * Returns 0 or 1 indicating whether a cleanup happened.\n */\n public cleanupMemory(): number {\n if (this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength) {\n const data = new Uint32Array(this._data.length);\n data.set(this._data);\n this._data = data;\n return 1;\n }\n return 0;\n }\n\n /** fill a line with fillCharData */\n public fill(fillCellData: ICellData, respectProtect: boolean = false): void {\n this._invalidateStringCache();\n // full branching on respectProtect==true, hopefully getting fast JIT for standard case\n if (respectProtect) {\n for (let i = 0; i < this.length; ++i) {\n if (!this.isProtected(i)) {\n this.setCell(i, fillCellData);\n }\n }\n return;\n }\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < this.length; ++i) {\n this.setCell(i, fillCellData);\n }\n }\n\n /** alter to a full copy of line */\n public copyFrom(line: BufferLine): void {\n this._invalidateStringCache();\n if (this.length !== line.length) {\n this._data = new Uint32Array(line._data);\n } else {\n // use high speed copy if lengths are equal\n this._data.set(line._data);\n }\n this.length = line.length;\n this._copySparseMapsFrom(line);\n this.isWrapped = line.isWrapped;\n }\n\n /** create a new clone */\n public clone(): IBufferLine {\n const newLine = new BufferLine(this._stringCache, 0, undefined, false);\n newLine._data = new Uint32Array(this._data);\n newLine.length = this.length;\n newLine._copySparseMapsFrom(this);\n newLine.isWrapped = this.isWrapped;\n return newLine;\n }\n\n public getTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public getNoBgTrimmedLength(): number {\n for (let i = this.length - 1; i >= 0; --i) {\n if ((this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * Constants.CELL_INDICIES + Cell.BG] & Attributes.CM_MASK)) {\n return i + (this._data[i * Constants.CELL_INDICIES + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n }\n }\n return 0;\n }\n\n public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n this._invalidateStringCache();\n const srcData = src._data;\n if (applyInReverse) {\n for (let cell = length - 1; cell >= 0; cell--) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n } else {\n for (let cell = 0; cell < length; cell++) {\n for (let i = 0; i < Constants.CELL_INDICIES; i++) {\n this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];\n }\n this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);\n }\n }\n }\n\n /**\n * Translates the buffer line to a string. Caching only applies to canonical full-line translation\n * requests (regardless of `trimRight` value).\n *\n * @param trimRight Whether to trim any empty cells on the right.\n * @param startCol The column to start the string (0-based inclusive).\n * @param endCol The column to end the string (0-based exclusive).\n * @param outColumns if specified, this array will be filled with column numbers such that\n * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]`\n * is where the character following `returnedString` will be displayed.\n *\n * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the\n * returned string, the corresponding entries in `outColumns` will have the same column number.\n */\n public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {\n const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;\n if (isCanonicalRequest) {\n this._stringCache.touch?.();\n }\n const stringCacheEntry = isCanonicalRequest ? this._getStringCacheEntry(false) : undefined;\n if (isCanonicalRequest && stringCacheEntry?.value !== undefined) {\n if (trimRight) {\n return stringCacheEntry.isTrimmed ? stringCacheEntry.value : stringCacheEntry.value.trimEnd();\n }\n if (!stringCacheEntry.isTrimmed) {\n return stringCacheEntry.value;\n }\n }\n startCol = startCol ?? 0;\n endCol = endCol ?? this.length;\n if (trimRight) {\n endCol = Math.min(endCol, this.getTrimmedLength());\n }\n if (outColumns) {\n outColumns.length = 0;\n }\n $translateToStringBuilder.reset();\n while (startCol < endCol) {\n const content = this._data[startCol * Constants.CELL_INDICIES + Cell.CONTENT];\n const cp = content & Content.CODEPOINT_MASK;\n const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n $translateToStringBuilder.append(chars);\n if (outColumns) {\n for (let i = 0; i < chars.length; ++i) {\n outColumns.push(startCol);\n }\n }\n startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1\n }\n if (outColumns) {\n outColumns.push(startCol);\n }\n const result = $translateToStringBuilder.toString();\n $translateToStringBuilder.reset();\n if (isCanonicalRequest) {\n const cacheEntry = this._getStringCacheEntry(true)!;\n cacheEntry.value = result;\n cacheEntry.isTrimmed = !!trimRight;\n }\n return result;\n }\n\n protected _getStringCacheEntry(createIfNeeded: boolean): IBufferLineStringCacheEntry | undefined {\n const cachedEntry = this._stringCacheEntryRef?.deref();\n if (cachedEntry) {\n if (cachedEntry.generation === this._stringCache.generation) {\n return cachedEntry;\n }\n }\n if (!createIfNeeded) {\n return undefined;\n }\n const cacheEntry = this._stringCache.allocateEntry();\n this._stringCacheEntryRef = new WeakRef(cacheEntry);\n return cacheEntry;\n }\n\n private _invalidateStringCache(): void {\n const cacheEntry = this._getStringCacheEntry(false);\n if (cacheEntry) {\n cacheEntry.value = undefined;\n cacheEntry.isTrimmed = false;\n }\n }\n\n /** Copy sparse map entries for a single cell when `_data` flags require them. */\n private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {\n const srcStart = srcCol * Constants.CELL_INDICIES;\n if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {\n this._combined[destCol] = src._combined[srcCol];\n }\n if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {\n this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];\n }\n }\n\n /** Rebuild sparse maps from another line, keyed only by `_data` flags. */\n private _copySparseMapsFrom(line: BufferLine): void {\n this._combined = {};\n this._extendedAttrs = {};\n for (let i = 0; i < line.length; i++) {\n this._copyCellMapsFrom(line, i, i);\n }\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { IBufferLineStringCache, IBufferLineStringCacheEntry } from './BufferLine';\nimport { disposableTimeout } from '../Async';\nimport { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../Lifecycle';\n\nconst enum Constants {\n CACHE_TTL_MS = 15000\n}\n\nexport class BufferLineStringCache extends Disposable implements IBufferLineStringCache {\n public generation: number = 0;\n public readonly entries: Set = new Set();\n private readonly _clearTimeout = this._register(new MutableDisposable());\n private _lastAccessTimestamp: number = 0;\n\n constructor() {\n super();\n this._register(toDisposable(() => this.entries.clear()));\n }\n\n public touch(): void {\n this._scheduleClear();\n }\n\n public allocateEntry(): IBufferLineStringCacheEntry {\n const entry: IBufferLineStringCacheEntry = {\n value: undefined,\n isTrimmed: false,\n generation: this.generation\n };\n this.entries.add(entry);\n this._scheduleClear();\n return entry;\n }\n\n public clear(): void {\n this._clearTimeout.clear();\n this._lastAccessTimestamp = 0;\n this.generation++;\n for (const entry of this.entries) {\n entry.value = undefined;\n entry.isTrimmed = false;\n }\n this.entries.clear();\n }\n\n private _scheduleClear(): void {\n this._lastAccessTimestamp = Date.now();\n if (this._clearTimeout.value) {\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS);\n }\n\n private _scheduleClearTimeout(timeoutMs: number): void {\n this._clearTimeout.value = disposableTimeout(() => {\n const elapsed = Date.now() - this._lastAccessTimestamp;\n if (elapsed >= Constants.CACHE_TTL_MS) {\n this.clear();\n return;\n }\n this._scheduleClearTimeout(Constants.CACHE_TTL_MS - elapsed);\n }, timeoutMs);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from '../CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n layout: number[];\n countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param oldCols The columns before resize\n * @param newCols The columns after resize.\n * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).\n * @param nullCell The cell data to use when filling in empty cells.\n * @param reflowCursorLine Whether to reflow the line containing the cursor.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData, reflowCursorLine: boolean): number[] {\n // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n // batched up and only committed once\n const toRemove: number[] = [];\n\n for (let y = 0; y < lines.length - 1; y++) {\n // Check if this row is wrapped\n let i = y;\n let nextLine = lines.get(++i) as BufferLine;\n if (!nextLine.isWrapped) {\n continue;\n }\n\n // Check how many lines it's wrapped for\n const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n while (i < lines.length && nextLine.isWrapped) {\n wrappedLines.push(nextLine);\n nextLine = lines.get(++i) as BufferLine;\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n y += wrappedLines.length - 1;\n continue;\n }\n }\n\n // Copy buffer data to new locations\n let destLineIndex = 0;\n let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n let srcLineIndex = 1;\n let srcCol = 0;\n while (srcLineIndex < wrappedLines.length) {\n const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n const srcRemainingCells = srcTrimmedTineLength - srcCol;\n const destRemainingCells = newCols - destCol;\n const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n destCol += cellsToCopy;\n if (destCol === newCols) {\n destLineIndex++;\n destCol = 0;\n }\n srcCol += cellsToCopy;\n if (srcCol === srcTrimmedTineLength) {\n srcLineIndex++;\n srcCol = 0;\n }\n\n // Make sure the last cell isn't wide, if it is copy it to the current dest\n if (destCol === 0 && destLineIndex !== 0) {\n if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n // Null out the end of the last row\n wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n }\n }\n }\n\n // Clear out remaining cells or fragments could remain;\n wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n // Work backwards and remove any rows at the end that only contain null cells\n let countToRemove = 0;\n for (let i = wrappedLines.length - 1; i > 0; i--) {\n if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n countToRemove++;\n } else {\n break;\n }\n }\n\n if (countToRemove > 0) {\n toRemove.push(y + wrappedLines.length - countToRemove); // index\n toRemove.push(countToRemove);\n }\n\n y += wrappedLines.length - 1;\n }\n return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList, toRemove: number[]): INewLayoutResult {\n const layout: number[] = [];\n // First iterate through the list and get the actual indexes to use for rows\n let nextToRemoveIndex = 0;\n let nextToRemoveStart = toRemove[nextToRemoveIndex];\n let countRemovedSoFar = 0;\n for (let i = 0; i < lines.length; i++) {\n if (nextToRemoveStart === i) {\n const countToRemove = toRemove[++nextToRemoveIndex];\n\n // Tell markers that there was a deletion\n lines.onDeleteEmitter.fire({\n index: i - countRemovedSoFar,\n amount: countToRemove\n });\n\n i += countToRemove - 1;\n countRemovedSoFar += countToRemove;\n nextToRemoveStart = toRemove[++nextToRemoveIndex];\n } else {\n layout.push(i);\n }\n }\n return {\n layout,\n countRemoved: countRemovedSoFar\n };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList, newLayout: number[]): void {\n // Record original lines so they don't get overridden when we rearrange the list\n const newLayoutLines: BufferLine[] = [];\n for (let i = 0; i < newLayout.length; i++) {\n newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n }\n\n // Rearrange the list\n for (let i = 0; i < newLayoutLines.length; i++) {\n lines.set(i, newLayoutLines[i]);\n }\n lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n const newLineLengths: number[] = [];\n let cellsNeeded = 0;\n for (let i = 0; i < wrappedLines.length; i++) {\n cellsNeeded += getWrappedLineTrimmedLength(wrappedLines, i, oldCols);\n }\n\n // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n // linesNeeded\n let srcCol = 0;\n let srcLine = 0;\n let cellsAvailable = 0;\n while (cellsAvailable < cellsNeeded) {\n if (cellsNeeded - cellsAvailable < newCols) {\n // Add the final line and exit the loop\n newLineLengths.push(cellsNeeded - cellsAvailable);\n break;\n }\n srcCol += newCols;\n const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n if (srcCol > oldTrimmedLength) {\n srcCol -= oldTrimmedLength;\n srcLine++;\n }\n const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n if (endsWithWide) {\n srcCol--;\n }\n const lineLength = endsWithWide ? newCols - 1 : newCols;\n newLineLengths.push(lineLength);\n cellsAvailable += lineLength;\n }\n\n return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n // If this is the last row in the wrapped line, get the actual trimmed length\n if (i === lines.length - 1) {\n return lines[i].getTrimmedLength();\n }\n // Detect whether the following line starts with a wide character and the end of the current line\n // is null, if so then we can be pretty sure the null character should be excluded from the line\n // length]\n const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n if (endsInNull && followingLineStartsWithWide) {\n return cols - 1;\n }\n return cols;\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { dispose, IDisposable } from '../Lifecycle';\nimport { IMarker } from './Types';\nimport { Emitter } from '../Event';\n\nexport class Marker implements IMarker {\n private static _nextId = 1;\n\n public isDisposed: boolean = false;\n private readonly _disposables: IDisposable[] = [];\n\n private readonly _id: number = Marker._nextId++;\n public get id(): number { return this._id; }\n\n private readonly _onDispose = this.register(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n constructor(\n public line: number\n ) {\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.isDisposed = true;\n this.line = -1;\n // Emit before super.dispose such that dispose listeners get a chance to react\n this._onDispose.fire();\n dispose(this._disposables);\n this._disposables.length = 0;\n }\n\n public register(disposable: T): T {\n this._disposables.push(disposable);\n return disposable;\n }\n}\n", "/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | undefined } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | undefined = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '\u25C6'\n 'a': '\\u2592', // '\u2592'\n 'b': '\\u2409', // '\u2409' (HT)\n 'c': '\\u240c', // '\u240C' (FF)\n 'd': '\\u240d', // '\u240D' (CR)\n 'e': '\\u240a', // '\u240A' (LF)\n 'f': '\\u00b0', // '\u00B0'\n 'g': '\\u00b1', // '\u00B1'\n 'h': '\\u2424', // '\u2424' (NL)\n 'i': '\\u240b', // '\u240B' (VT)\n 'j': '\\u2518', // '\u2518'\n 'k': '\\u2510', // '\u2510'\n 'l': '\\u250c', // '\u250C'\n 'm': '\\u2514', // '\u2514'\n 'n': '\\u253c', // '\u253C'\n 'o': '\\u23ba', // '\u23BA'\n 'p': '\\u23bb', // '\u23BB'\n 'q': '\\u2500', // '\u2500'\n 'r': '\\u23bc', // '\u23BC'\n 's': '\\u23bd', // '\u23BD'\n 't': '\\u251c', // '\u251C'\n 'u': '\\u2524', // '\u2524'\n 'v': '\\u2534', // '\u2534'\n 'w': '\\u252c', // '\u252C'\n 'x': '\\u2502', // '\u2502'\n 'y': '\\u2264', // '\u2264'\n 'z': '\\u2265', // '\u2265'\n '{': '\\u03c0', // '\u03C0'\n '|': '\\u2260', // '\u2260'\n '}': '\\u00a3', // '\u00A3'\n '~': '\\u00b7' // '\u00B7'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '\u00A3'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = undefined;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '\u00A3',\n '@': '\u00BE',\n '[': 'ij',\n '\\\\': '\u00BD',\n ']': '|',\n '{': '\u00A8',\n '|': 'f',\n '}': '\u00BC',\n '~': '\u00B4'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] = CHARSETS['5'] = {\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '\u00A3',\n '@': '\u00E0',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00A7',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00A8'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': '\u00E0',\n '[': '\u00E2',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n '`': '\u00F4',\n '{': '\u00E9',\n '|': '\u00F9',\n '}': '\u00E8',\n '~': '\u00FB'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '\u00A7',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00DC',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00DF'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00B0',\n '\\\\': '\u00E7',\n ']': '\u00E9',\n '`': '\u00F9',\n '{': '\u00E0',\n '|': '\u00F2',\n '}': '\u00E8',\n '~': '\u00EC'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] = CHARSETS['6'] = {\n '@': '\u00C4',\n '[': '\u00C6',\n '\\\\': '\u00D8',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E4',\n '{': '\u00E6',\n '|': '\u00F8',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '\u00A3',\n '@': '\u00A7',\n '[': '\u00A1',\n '\\\\': '\u00D1',\n ']': '\u00BF',\n '{': '\u00B0',\n '|': '\u00F1',\n '}': '\u00E7'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] = CHARSETS['7'] = {\n '@': '\u00C9',\n '[': '\u00C4',\n '\\\\': '\u00D6',\n ']': '\u00C5',\n '^': '\u00DC',\n '`': '\u00E9',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00E5',\n '~': '\u00FC'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': '\u00F9',\n '@': '\u00E0',\n '[': '\u00E9',\n '\\\\': '\u00E7',\n ']': '\u00EA',\n '^': '\u00EE',\n\n '_': '\u00E8',\n '`': '\u00F4',\n '{': '\u00E4',\n '|': '\u00F6',\n '}': '\u00FC',\n '~': '\u00FB'\n};\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from '../CircularList';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IdleTaskQueue } from '../TaskQueue';\nimport { ICharset } from '../Types';\nimport { IAttributeData, IBuffer, IBufferLine, ICellData } from './Types';\nimport { ExtendedAttrs } from './AttributeData';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './BufferLine';\nimport { BufferLineStringCache } from './BufferLineStringCache';\nimport { getWrappedLineTrimmedLength, reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths } from './BufferReflow';\nimport { CellData } from './CellData';\nimport { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, WHITESPACE_CELL_WIDTH } from './Constants';\nimport { Marker } from './Marker';\nimport { DEFAULT_CHARSET } from '../data/Charsets';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\n\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer extends Disposable implements IBuffer {\n public lines: CircularList;\n public ydisp: number = 0;\n public ybase: number = 0;\n public y: number = 0;\n public x: number = 0;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: { [column: number]: boolean | undefined } = {};\n public savedY: number = 0;\n public savedX: number = 0;\n public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n public savedCharset: ICharset | undefined = DEFAULT_CHARSET;\n public savedCharsets: (ICharset | undefined)[] = [];\n public savedGlevel: number = 0;\n public savedOriginMode: boolean = false;\n public savedWraparoundMode: boolean = true;\n public markers: Marker[] = [];\n private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n private _cols: number;\n private _rows: number;\n private _isClearing: boolean = false;\n private _memoryCleanupQueue: InstanceType;\n private _memoryCleanupPosition = 0;\n private readonly _stringCache: BufferLineStringCache;\n\n constructor(\n private _hasScrollback: boolean,\n private _optionsService: IOptionsService,\n private _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this._cols = this._bufferService.cols;\n this._rows = this._bufferService.rows;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n this._memoryCleanupQueue = new IdleTaskQueue(this._logService);\n this._register(toDisposable(() => this._memoryCleanupQueue.clear()));\n this._register(toDisposable(() => this.clearAllMarkers()));\n this._stringCache = this._register(new BufferLineStringCache());\n }\n\n public getNullCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._nullCell.fg = attr.fg;\n this._nullCell.bg = attr.bg;\n this._nullCell.extended = attr.extended;\n } else {\n this._nullCell.fg = 0;\n this._nullCell.bg = 0;\n this._nullCell.extended = new ExtendedAttrs();\n }\n return this._nullCell;\n }\n\n public getWhitespaceCell(attr?: IAttributeData): ICellData {\n if (attr) {\n this._whitespaceCell.fg = attr.fg;\n this._whitespaceCell.bg = attr.bg;\n this._whitespaceCell.extended = attr.extended;\n } else {\n this._whitespaceCell.fg = 0;\n this._whitespaceCell.bg = 0;\n this._whitespaceCell.extended = new ExtendedAttrs();\n }\n return this._whitespaceCell;\n }\n\n public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n return new BufferLine(this._stringCache, this._bufferService.cols, this.getNullCell(attr), isWrapped);\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(fillAttr?: IAttributeData): void {\n if (this.lines.length === 0) {\n fillAttr ??= DEFAULT_ATTR_DATA;\n let i = this._rows;\n while (i--) {\n this.lines.push(this.getBlankLine(fillAttr));\n }\n }\n }\n\n /**\n * Clears the buffer to its initial state, discarding all previous data.\n */\n public clear(): void {\n this._stringCache.clear();\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this.lines = new CircularList(this._getCorrectBufferLength(this._rows));\n this.scrollTop = 0;\n this.scrollBottom = this._rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // store reference to null cell with default attrs\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n this._stringCache.clear();\n\n // count bufferlines with overly big memory to be cleaned afterwards\n let dirtyMemoryLines = 0;\n\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this.lines.maxLength) {\n this.lines.maxLength = newMaxLength;\n }\n\n // if (this._cols > newCols) {\n // console.log('increase!');\n // }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this.lines.length > 0) {\n // Deal with columns increasing (reducing needs to happen after reflow)\n if (this._cols < newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._rows < newRows) {\n for (let y = this._rows; y < newRows; y++) {\n if (this.lines.length < newRows + this.ybase) {\n if (this._optionsService.rawOptions.windowsPty.backend !== undefined || this._optionsService.rawOptions.windowsPty.buildNumber !== undefined) {\n // Just add the new missing rows on Windows as conpty reprints the screen with its\n // view of the world. Once a line enters scrollback for conpty it remains there\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n } else {\n if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n }\n }\n }\n } else { // (this._rows >= newRows)\n for (let y = this._rows; y > newRows; y--) {\n if (this.lines.length > newRows + this.ybase) {\n if (this.lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this.lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this.lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this.lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this.lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n this.savedY = Math.max(this.savedY - amountToTrim, 0);\n }\n this.lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n this.x = Math.min(this.x, newCols - 1);\n this.y = Math.min(this.y, newRows - 1);\n if (addToY) {\n this.y += addToY;\n }\n this.savedX = Math.min(this.savedX, newCols - 1);\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n\n if (this._isReflowEnabled) {\n this._reflow(newCols, newRows);\n\n // Trim the end of the line off if cols shrunk\n if (this._cols > newCols) {\n for (let i = 0; i < this.lines.length; i++) {\n // +boolean for fast 0 or 1 conversion\n dirtyMemoryLines += +this.lines.get(i)!.resize(newCols, nullCell);\n }\n }\n }\n\n this._cols = newCols;\n this._rows = newRows;\n\n // Ensure the cursor position invariant: ybase + y must be within buffer bounds\n // This can be violated during reflow or when shrinking rows\n if (this.lines.length > 0) {\n const maxY = Math.max(0, this.lines.length - this.ybase - 1);\n this.y = Math.min(this.y, maxY);\n }\n\n this._memoryCleanupQueue.clear();\n // schedule memory cleanup only, if more than 10% of the lines are affected\n if (dirtyMemoryLines > 0.1 * this.lines.length) {\n this._memoryCleanupPosition = 0;\n this._memoryCleanupQueue.enqueue(() => this._batchedMemoryCleanup());\n }\n }\n\n private _batchedMemoryCleanup(): boolean {\n let normalRun = true;\n if (this._memoryCleanupPosition >= this.lines.length) {\n // cleanup made it once through all lines, thus rescan in loop below to also catch shifted\n // lines, which should finish rather quick if there are no more cleanups pending\n this._memoryCleanupPosition = 0;\n normalRun = false;\n }\n let counted = 0;\n while (this._memoryCleanupPosition < this.lines.length) {\n counted += this.lines.get(this._memoryCleanupPosition++)!.cleanupMemory();\n // cleanup max 100 lines per batch\n if (counted > 100) {\n return true;\n }\n }\n // normal runs always need another rescan afterwards\n // if we made it here with normalRun=false, we are in a final run\n // and can end the cleanup task for sure\n return normalRun;\n }\n\n private get _isReflowEnabled(): boolean {\n const windowsPty = this._optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.buildNumber) {\n return this._hasScrollback && windowsPty.backend === 'conpty' && windowsPty.buildNumber >= 21376;\n }\n return this._hasScrollback;\n }\n\n private _reflow(newCols: number, newRows: number): void {\n if (this._cols === newCols) {\n return;\n }\n\n // Iterate through rows, ignore the last one as it cannot be wrapped\n if (newCols > this._cols) {\n this._reflowLarger(newCols, newRows);\n } else {\n this._reflowSmaller(newCols, newRows);\n }\n }\n\n private _reflowLarger(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA), reflowCursorLine);\n if (toRemove.length > 0) {\n const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n }\n }\n\n private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Adjust viewport based on number of items removed\n let viewportAdjustments = countRemoved;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y > 0) {\n this.y--;\n }\n if (this.lines.length < newRows) {\n // Add an extra row at the bottom of the viewport\n this.lines.push(new BufferLine(this._stringCache, newCols, nullCell, false));\n }\n } else {\n if (this.ydisp === this.ybase) {\n this.ydisp--;\n }\n this.ybase--;\n }\n }\n this.savedY = Math.max(this.savedY - countRemoved, 0);\n }\n\n private _reflowSmaller(newCols: number, newRows: number): void {\n const reflowCursorLine = this._optionsService.rawOptions.reflowCursorLine;\n const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n // batched up and only committed once\n const toInsert = [];\n let countToInsert = 0;\n // Go backwards as many lines may be trimmed and this will avoid considering them\n for (let y = this.lines.length - 1; y >= 0; y--) {\n // Check whether this line is a problem\n let nextLine = this.lines.get(y) as BufferLine;\n if (!nextLine || !nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n continue;\n }\n\n // Gather wrapped lines and adjust y to be the starting line\n const wrappedLines: BufferLine[] = [nextLine];\n while (nextLine.isWrapped && y > 0) {\n nextLine = this.lines.get(--y) as BufferLine;\n wrappedLines.unshift(nextLine);\n }\n\n if (!reflowCursorLine) {\n // If these lines contain the cursor don't touch them, the program will handle fixing up\n // wrapped lines with the cursor\n const absoluteY = this.ybase + this.y;\n if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n continue;\n }\n }\n\n const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n const linesToAdd = destLineLengths.length - wrappedLines.length;\n let trimmedLines: number;\n if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n // If the top section of the buffer is not yet filled\n trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n } else {\n trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n }\n\n // Add the new lines\n const newLines: BufferLine[] = [];\n for (let i = 0; i < linesToAdd; i++) {\n const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n newLines.push(newLine);\n }\n if (newLines.length > 0) {\n toInsert.push({\n // countToInsert here gets the actual index, taking into account other inserted items.\n // using this we can iterate through the list forwards\n start: y + wrappedLines.length + countToInsert,\n newLines\n });\n countToInsert += newLines.length;\n }\n wrappedLines.push(...newLines);\n\n // Copy buffer data to new locations, this needs to happen backwards to do in-place\n let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n let srcCol = lastLineLength;\n while (srcLineIndex >= 0) {\n const cellsToCopy = Math.min(srcCol, destCol);\n if (wrappedLines[destLineIndex] === undefined) {\n // Sanity check that the line exists, this has been known to fail for an unknown reason\n // which would stop the reflow from happening if an exception would throw.\n break;\n }\n wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n destCol -= cellsToCopy;\n if (destCol === 0) {\n destLineIndex--;\n destCol = destLineLengths[destLineIndex];\n }\n srcCol -= cellsToCopy;\n if (srcCol === 0) {\n srcLineIndex--;\n const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n }\n }\n\n // Null out the end of the line ends if a wide character wrapped to the following line\n for (let i = 0; i < wrappedLines.length; i++) {\n if (destLineLengths[i] < newCols) {\n wrappedLines[i].setCell(destLineLengths[i], nullCell);\n }\n }\n\n // Adjust viewport as needed\n let viewportAdjustments = linesToAdd - trimmedLines;\n while (viewportAdjustments-- > 0) {\n if (this.ybase === 0) {\n if (this.y < newRows - 1) {\n this.y++;\n this.lines.pop();\n } else {\n this.ybase++;\n this.ydisp++;\n }\n } else {\n // Ensure ybase does not exceed its maximum value\n if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n if (this.ybase === this.ydisp) {\n this.ydisp++;\n }\n this.ybase++;\n }\n }\n }\n this.savedY = Math.min(this.savedY + linesToAdd, this.ybase + newRows - 1);\n }\n\n // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n // costly calls to CircularList.splice.\n if (toInsert.length > 0) {\n // Record buffer insert events and then play them back backwards so that the indexes are\n // correct\n const insertEvents: IInsertEvent[] = [];\n\n // Record original lines so they don't get overridden when we rearrange the list\n const originalLines: BufferLine[] = [];\n for (let i = 0; i < this.lines.length; i++) {\n originalLines.push(this.lines.get(i) as BufferLine);\n }\n const originalLinesLength = this.lines.length;\n\n let originalLineIndex = originalLinesLength - 1;\n let nextToInsertIndex = 0;\n let nextToInsert = toInsert[nextToInsertIndex];\n this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n let countInsertedSoFar = 0;\n for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n // Insert extra lines here, adjusting i as needed\n for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n this.lines.set(i--, nextToInsert.newLines[nextI]);\n }\n i++;\n\n // Create insert events for later\n insertEvents.push({\n index: originalLineIndex + 1,\n amount: nextToInsert.newLines.length\n });\n\n countInsertedSoFar += nextToInsert.newLines.length;\n nextToInsert = toInsert[++nextToInsertIndex];\n } else {\n this.lines.set(i, originalLines[originalLineIndex--]);\n }\n }\n\n // Update markers\n let insertCountEmitted = 0;\n for (let i = insertEvents.length - 1; i >= 0; i--) {\n insertEvents[i].index += insertCountEmitted;\n this.lines.onInsertEmitter.fire(insertEvents[i]);\n insertCountEmitted += insertEvents[i].amount;\n }\n const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n if (amountToTrim > 0) {\n this.lines.onTrimEmitter.fire(amountToTrim);\n }\n }\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The absolute index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n return line.translateToString(trimRight, startCol, endCol);\n }\n\n public getWrappedRangeForLine(y: number): { first: number, last: number } {\n let first = y;\n let last = y;\n // Scan upwards for wrapped lines\n while (first > 0 && this.lines.get(first)!.isWrapped) {\n first--;\n }\n // Scan downwards for wrapped lines\n while (last + 1 < this.lines.length && this.lines.get(last + 1)!.isWrapped) {\n last++;\n }\n return { first, last };\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i !== null && i !== undefined) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[--x] && x > 0);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n x ??= this.x;\n while (!this.tabs[++x] && x < this._cols);\n return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Clears markers on single line.\n * @param y The line to clear.\n */\n public clearMarkers(y: number): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].line === y) {\n this.markers[i].dispose();\n this.markers.splice(i--, 1);\n }\n }\n this._isClearing = false;\n }\n\n /**\n * Clears markers on all lines\n */\n public clearAllMarkers(): void {\n this._isClearing = true;\n for (let i = 0; i < this.markers.length; i++) {\n this.markers[i].dispose();\n }\n this.markers.length = 0;\n this._isClearing = false;\n }\n\n public addMarker(y: number): Marker {\n const marker = new Marker(y);\n this.markers.push(marker);\n marker.register(this.lines.onTrim(amount => {\n marker.line -= amount;\n // The marker should be disposed when the line is trimmed from the buffer\n if (marker.line < 0) {\n marker.dispose();\n }\n }));\n marker.register(this.lines.onInsert(event => {\n if (marker.line >= event.index) {\n marker.line += event.amount;\n }\n }));\n marker.register(this.lines.onDelete(event => {\n // Delete the marker if it's within the range\n if (marker.line >= event.index && marker.line < event.index + event.amount) {\n marker.dispose();\n }\n\n // Shift the marker if it's after the deleted range\n if (marker.line > event.index) {\n marker.line -= event.amount;\n }\n }));\n marker.register(marker.onDispose(() => this._removeMarker(marker)));\n return marker;\n }\n\n private _removeMarker(marker: Marker): void {\n if (!this._isClearing) {\n this.markers.splice(this.markers.indexOf(marker), 1);\n }\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, MutableDisposable } from '../Lifecycle';\nimport { Buffer } from './Buffer';\nimport { IAttributeData, IBuffer, IBufferSet } from './Types';\nimport { IBufferService, ILogService, IOptionsService } from '../services/Services';\nimport { Emitter } from '../Event';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends Disposable implements IBufferSet {\n private _normal!: Buffer;\n private _alt!: Buffer;\n private _activeBuffer!: Buffer;\n private readonly _normalBuffer = this._register(new MutableDisposable());\n private readonly _altBuffer = this._register(new MutableDisposable());\n\n private readonly _onBufferActivate = this._register(new Emitter<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>());\n public readonly onBufferActivate = this._onBufferActivate.event;\n\n /**\n * Create a new BufferSet for the given terminal.\n */\n constructor(\n private readonly _optionsService: IOptionsService,\n private readonly _bufferService: IBufferService,\n private readonly _logService: ILogService\n ) {\n super();\n this.reset();\n this._register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));\n this._register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));\n }\n\n public reset(): void {\n this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService);\n this._normalBuffer.value = this._normal;\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService);\n this._altBuffer.value = this._alt;\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n if (this._activeBuffer === this._normal) {\n return;\n }\n this._normal.x = this._alt.x;\n this._normal.y = this._alt.y;\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clearAllMarkers();\n this._alt.clear();\n this._activeBuffer = this._normal;\n this._onBufferActivate.fire({\n activeBuffer: this._normal,\n inactiveBuffer: this._alt\n });\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(fillAttr?: IAttributeData): void {\n if (this._activeBuffer === this._alt) {\n return;\n }\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows(fillAttr);\n this._alt.x = this._normal.x;\n this._alt.y = this._normal.y;\n this._activeBuffer = this._alt;\n this._onBufferActivate.fire({\n activeBuffer: this._alt,\n inactiveBuffer: this._normal\n });\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n this.setupTabStops(newCols);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IAttributeData, IBuffer, IBufferLine, IBufferSet } from '../buffer/Types';\nimport { BufferSet } from '../buffer/BufferSet';\nimport { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from './Services';\nimport { Emitter } from '../Event';\n\nexport const enum BufferServiceConstants {\n MINIMUM_COLS = 2, // Less than 2 can mess with wide chars\n MINIMUM_ROWS = 1\n}\n\nexport class BufferService extends Disposable implements IBufferService {\n public serviceBrand: any;\n\n public cols: number;\n public rows: number;\n public buffers: IBufferSet;\n /** Whether the user is scrolling (locks the scroll position) */\n public isUserScrolling: boolean = false;\n\n private readonly _onResize = this._register(new Emitter());\n public readonly onResize = this._onResize.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n\n public get buffer(): IBuffer { return this.buffers.active; }\n\n /** An IBufferline to clone/copy from for new blank lines */\n private _cachedBlankLine: IBufferLine | undefined;\n\n constructor(\n @IOptionsService optionsService: IOptionsService,\n @ILogService logService: ILogService\n ) {\n super();\n this.cols = Math.max(optionsService.rawOptions.cols || 0, BufferServiceConstants.MINIMUM_COLS);\n this.rows = Math.max(optionsService.rawOptions.rows || 0, BufferServiceConstants.MINIMUM_ROWS);\n this.buffers = this._register(new BufferSet(optionsService, this, logService));\n this._register(this.buffers.onBufferActivate(e => {\n this._onScroll.fire(e.activeBuffer.ydisp);\n }));\n }\n\n public resize(cols: number, rows: number): void {\n const colsChanged = this.cols !== cols;\n const rowsChanged = this.rows !== rows;\n this.cols = cols;\n this.rows = rows;\n this.buffers.resize(cols, rows);\n this._onResize.fire({ cols, rows, colsChanged, rowsChanged });\n }\n\n public reset(): void {\n this.buffers.reset();\n this.isUserScrolling = false;\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n const buffer = this.buffer;\n\n let newLine: IBufferLine | undefined;\n newLine = this._cachedBlankLine;\n if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n newLine = buffer.getBlankLine(eraseAttr, isWrapped);\n this._cachedBlankLine = newLine;\n }\n newLine.isWrapped = isWrapped;\n\n const topRow = buffer.ybase + buffer.scrollTop;\n const bottomRow = buffer.ybase + buffer.scrollBottom;\n\n if (buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = buffer.lines.isFull;\n\n // Insert the line using the fastest method\n if (bottomRow === buffer.lines.length - 1) {\n if (willBufferBeTrimmed) {\n buffer.lines.recycle().copyFrom(newLine);\n } else {\n buffer.lines.push(newLine.clone());\n }\n } else {\n buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.isUserScrolling) {\n buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.isUserScrolling) {\n buffer.ydisp = Math.max(buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1 /* as it's zero-based */;\n buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n buffer.lines.set(bottomRow, newLine.clone());\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.isUserScrolling) {\n buffer.ydisp = buffer.ybase;\n }\n\n this._onScroll.fire(buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n const buffer = this.buffer;\n if (disp < 0) {\n if (buffer.ydisp === 0) {\n return;\n }\n this.isUserScrolling = true;\n } else if (disp + buffer.ydisp >= buffer.ybase) {\n this.isUserScrolling = false;\n }\n\n const oldYdisp = buffer.ydisp;\n buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this._onScroll.fire(buffer.ydisp);\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { isMac } from '../Platform';\nimport { CursorStyle, IDisposable } from '../Types';\nimport { FontWeight, IOptionsService, ITerminalOptions } from './Services';\nimport { Emitter } from '../Event';\n\nexport const DEFAULT_OPTIONS: Readonly> = {\n cols: 80,\n rows: 24,\n showCursorImmediately: false,\n cursorBlink: false,\n blinkIntervalDuration: 0,\n cursorStyle: 'block',\n cursorWidth: 1,\n cursorInactiveStyle: 'outline',\n drawBoldTextInBrightColors: true,\n documentOverride: null,\n fastScrollSensitivity: 5,\n fontFamily: 'monospace',\n fontSize: 15,\n fontWeight: 'normal',\n fontWeightBold: 'bold',\n ignoreBracketedPasteMode: false,\n lineHeight: 1.0,\n letterSpacing: 0,\n linkHandler: null,\n logLevel: 'info',\n logger: null,\n scrollback: 1000,\n scrollbar: { showScrollbar: true },\n scrollOnEraseInDisplay: false,\n scrollOnUserInput: true,\n scrollSensitivity: 1,\n screenReaderMode: false,\n smoothScrollDuration: 0,\n macOptionIsMeta: false,\n macOptionClickForcesSelection: false,\n minimumContrastRatio: 1,\n mouseEventsRequireAlt: false,\n disableStdin: false,\n allowProposedApi: false,\n allowTransparency: false,\n tabStopWidth: 8,\n theme: {},\n reflowCursorLine: false,\n rescaleOverlappingGlyphs: false,\n rightClickSelectsWord: isMac,\n windowOptions: {},\n windowsPty: {},\n wordSeparator: ' ()[]{}\\',\"`',\n altClickMovesCursor: true,\n convertEol: false,\n termName: 'xterm',\n quirks: {},\n vtExtensions: {}\n};\n\nconst FONT_WEIGHT_OPTIONS: Extract[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\nexport class OptionsService extends Disposable implements IOptionsService {\n public serviceBrand: any;\n\n public readonly rawOptions: Required;\n public options: Required;\n\n private readonly _onOptionChange = this._register(new Emitter());\n public readonly onOptionChange = this._onOptionChange.event;\n\n constructor(options: Partial) {\n super();\n // set the default value of each option\n const defaultOptions = { ...DEFAULT_OPTIONS };\n for (const key in options) {\n if (key in defaultOptions) {\n try {\n const newValue = options[key];\n defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n // set up getters and setters for each option\n this.rawOptions = defaultOptions;\n this.options = { ... defaultOptions };\n this._setupOptions();\n\n // Clear out options that could link outside xterm.js as they could easily cause an embedder\n // memory leak\n this._register(toDisposable(() => {\n this.rawOptions.linkHandler = null;\n this.rawOptions.documentOverride = null;\n }));\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onSpecificOptionChange(key: T, listener: (value: ITerminalOptions[T]) => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (eventKey === key) {\n listener(this.rawOptions[key]);\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable {\n return this.onOptionChange(eventKey => {\n if (keys.indexOf(eventKey) !== -1) {\n listener();\n }\n });\n }\n\n private _setupOptions(): void {\n const getter = (propName: string): any => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n return this.rawOptions[propName];\n };\n\n const setter = (propName: string, value: any): void => {\n if (!(propName in DEFAULT_OPTIONS)) {\n throw new Error(`No option with key \"${propName}\"`);\n }\n\n value = this._sanitizeAndValidateOption(propName, value);\n // Don't fire an option change event if they didn't change\n if (this.rawOptions[propName] !== value) {\n this.rawOptions[propName] = value;\n this._onOptionChange.fire(propName);\n }\n };\n\n for (const propName in this.rawOptions) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this.options, propName, desc);\n }\n }\n\n private _sanitizeAndValidateOption(key: string, value: any): any {\n switch (key) {\n case 'cursorStyle':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n if (!isCursorStyle(value)) {\n throw new Error(`\"${value}\" is not a valid value for ${key}`);\n }\n break;\n case 'wordSeparator':\n if (!value) {\n value = DEFAULT_OPTIONS[key];\n }\n break;\n case 'fontWeight':\n case 'fontWeightBold':\n if (typeof value === 'number' && 1 <= value && value <= 1000) {\n // already valid numeric value\n break;\n }\n value = FONT_WEIGHT_OPTIONS.includes(value) ? value : DEFAULT_OPTIONS[key];\n break;\n case 'blinkIntervalDuration':\n value = Math.floor(value);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'cursorWidth':\n value = Math.floor(value);\n // Fall through for bounds check\n case 'lineHeight':\n case 'tabStopWidth':\n if (value < 1) {\n throw new Error(`${key} cannot be less than 1, value: ${value}`);\n }\n break;\n case 'minimumContrastRatio':\n value = Math.max(1, Math.min(21, Math.round(value * 10) / 10));\n break;\n case 'scrollback':\n value = Math.min(value, 4294967295);\n if (value < 0) {\n throw new Error(`${key} cannot be less than 0, value: ${value}`);\n }\n break;\n case 'fastScrollSensitivity':\n case 'scrollSensitivity':\n if (value <= 0) {\n throw new Error(`${key} cannot be less than or equal to 0, value: ${value}`);\n }\n break;\n case 'rows':\n case 'cols':\n if (!value && value !== 0) {\n throw new Error(`${key} must be numeric, value: ${value}`);\n }\n break;\n case 'windowsPty':\n value = value ?? {};\n break;\n }\n return value;\n }\n}\n\nfunction isCursorStyle(value: unknown): value is CursorStyle {\n return value === 'block' || value === 'underline' || value === 'bar';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../Lifecycle';\nimport { IDecPrivateModes, IKittyKeyboardState, IModes } from '../Types';\nimport { IBufferService, ICoreService, ILogService, IOptionsService } from './Services';\nimport { Emitter } from '../Event';\n\nconst DEFAULT_MODES: IModes = Object.freeze({\n insertMode: false\n});\n\nconst DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({\n applicationCursorKeys: false,\n applicationKeypad: false,\n bracketedPasteMode: false,\n colorSchemeUpdates: false,\n cursorBlink: undefined,\n cursorStyle: undefined,\n origin: false,\n reverseWraparound: false,\n sendFocus: false,\n synchronizedOutput: false,\n win32InputMode: false,\n wraparound: true // defaults: xterm - true, vt100 - false\n});\n\nconst DEFAULT_KITTY_KEYBOARD_STATE = (): IKittyKeyboardState => ({\n flags: 0,\n mainFlags: 0,\n altFlags: 0,\n mainStack: [],\n altStack: []\n});\n\nexport class CoreService extends Disposable implements ICoreService {\n public serviceBrand: any;\n\n public isCursorInitialized: boolean;\n public isCursorHidden: boolean = false;\n public modes: IModes;\n public decPrivateModes: IDecPrivateModes;\n public kittyKeyboard: IKittyKeyboardState;\n\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n private readonly _onUserInput = this._register(new Emitter());\n public readonly onUserInput = this._onUserInput.event;\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onRequestScrollToBottom = this._register(new Emitter());\n public readonly onRequestScrollToBottom = this._onRequestScrollToBottom.event;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService,\n @ILogService private readonly _logService: ILogService,\n @IOptionsService private readonly _optionsService: IOptionsService\n ) {\n super();\n this.isCursorInitialized = _optionsService.rawOptions.showCursorImmediately ?? false;\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public reset(): void {\n this.modes = structuredClone(DEFAULT_MODES);\n this.decPrivateModes = structuredClone(DEFAULT_DEC_PRIVATE_MODES);\n this.kittyKeyboard = DEFAULT_KITTY_KEYBOARD_STATE();\n }\n\n public triggerDataEvent(data: string, wasUserInput: boolean = false): void {\n // Prevents all events to pty process if stdin is disabled\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n const buffer = this._bufferService.buffer;\n if (wasUserInput && this._optionsService.rawOptions.scrollOnUserInput && buffer.ybase !== buffer.ydisp) {\n this._onRequestScrollToBottom.fire();\n }\n\n // Fire onUserInput so listeners can react as well (eg. clear selection)\n if (wasUserInput) {\n this._onUserInput.fire();\n }\n\n // Fire onData API\n this._logService.debug(`sending data \"${data}\"`);\n this._logService.trace(`sending data (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onData.fire(data);\n }\n\n public triggerBinaryEvent(data: string): void {\n if (this._optionsService.rawOptions.disableStdin) {\n return;\n }\n this._logService.debug(`sending binary \"${data}\"`);\n this._logService.trace(`sending binary (codes)`, () => data.split('').map(e => e.charCodeAt(0)));\n this._onBinary.fire(data);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IMouseStateService } from './Services';\nimport { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from '../Types';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\n/**\n * Supported default protocols.\n */\nconst DEFAULT_PROTOCOLS: { [key: string]: ICoreMouseProtocol } = {\n /**\n * NONE\n * Events: none\n * Modifiers: none\n */\n NONE: {\n events: CoreMouseEventType.NONE,\n restrict: () => false\n },\n /**\n * X10\n * Events: mousedown\n * Modifiers: none\n */\n X10: {\n events: CoreMouseEventType.DOWN,\n restrict: (e: ICoreMouseEvent) => {\n // no wheel, no move, no up\n if (e.button === CoreMouseButton.WHEEL || e.action !== CoreMouseAction.DOWN) {\n return false;\n }\n // no modifiers\n e.ctrl = false;\n e.alt = false;\n e.shift = false;\n return true;\n }\n },\n /**\n * VT200\n * Events: mousedown / mouseup / wheel\n * Modifiers: all\n */\n VT200: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL,\n restrict: (e: ICoreMouseEvent) => {\n // no move\n if (e.action === CoreMouseAction.MOVE) {\n return false;\n }\n return true;\n }\n },\n /**\n * DRAG\n * Events: mousedown / mouseup / wheel / mousedrag\n * Modifiers: all\n */\n DRAG: {\n events: CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL | CoreMouseEventType.DRAG,\n restrict: (e: ICoreMouseEvent) => {\n // no move without button\n if (e.action === CoreMouseAction.MOVE && e.button === CoreMouseButton.NONE) {\n return false;\n }\n return true;\n }\n },\n /**\n * ANY\n * Events: all mouse related events\n * Modifiers: all\n */\n ANY: {\n events:\n CoreMouseEventType.DOWN | CoreMouseEventType.UP | CoreMouseEventType.WHEEL\n | CoreMouseEventType.DRAG | CoreMouseEventType.MOVE,\n restrict: (e: ICoreMouseEvent) => true\n }\n};\n\nconst enum Modifiers {\n SHIFT = 4,\n ALT = 8,\n CTRL = 16\n}\n\n// helper for default encoders to generate the event code.\nfunction eventCode(e: ICoreMouseEvent, isSGR: boolean): number {\n let code = (e.ctrl ? Modifiers.CTRL : 0) | (e.shift ? Modifiers.SHIFT : 0) | (e.alt ? Modifiers.ALT : 0);\n if (e.button === CoreMouseButton.WHEEL) {\n code |= 64;\n code |= e.action;\n } else {\n code |= e.button & 3;\n if (e.button & 4) {\n code |= 64;\n }\n if (e.button & 8) {\n code |= 128;\n }\n if (e.action === CoreMouseAction.MOVE) {\n code |= CoreMouseAction.MOVE;\n } else if (e.action === CoreMouseAction.UP && !isSGR) {\n // special case - only SGR can report button on release\n // all others have to go with NONE\n code |= CoreMouseButton.NONE;\n }\n }\n return code;\n}\n\nconst S = String.fromCharCode;\n\n/**\n * Supported default encodings.\n */\nconst DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {\n /**\n * DEFAULT - CSI M Pb Px Py\n * Single byte encoding for coords and event code.\n * Can encode values up to 223 (1-based).\n */\n DEFAULT: (e: ICoreMouseEvent) => {\n const params = [eventCode(e, false) + 32, e.col + 32, e.row + 32];\n // supress mouse report if we exceed addressible range\n // Note this is handled differently by emulators\n // - xterm: sends 0;0 coords instead\n // - vte, konsole: no report\n if (params[0] > 255 || params[1] > 255 || params[2] > 255) {\n return '';\n }\n return `\\x1b[M${S(params[0])}${S(params[1])}${S(params[2])}`;\n },\n /**\n * SGR - CSI < Pb ; Px ; Py M|m\n * No encoding limitation.\n * Can report button on release and works with a well formed sequence.\n */\n SGR: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.col};${e.row}${final}`;\n },\n SGR_PIXELS: (e: ICoreMouseEvent) => {\n const final = (e.action === CoreMouseAction.UP && e.button !== CoreMouseButton.WHEEL) ? 'm' : 'M';\n return `\\x1b[<${eventCode(e, true)};${e.x};${e.y}${final}`;\n }\n};\n\n/**\n * MouseStateService\n *\n * Provides mouse tracking reports with different protocols and encodings.\n * - protocols: NONE (default), X10, VT200, DRAG, ANY\n * - encodings: DEFAULT, SGR (UTF8, URXVT removed in #2507)\n *\n * Custom protocols/encodings can be added by `addProtocol` / `addEncoding`.\n * To activate a protocol/encoding, set `activeProtocol` / `activeEncoding`.\n * Switching a protocol will send a notification event `onProtocolChange`\n * with a list of needed events to track.\n *\n * The service handles the mouse tracking state and decides whether to send\n * a tracking report to the backend based on protocol and encoding limitations.\n * To send a mouse event call `triggerMouseEvent`.\n */\nexport class MouseStateService extends Disposable implements IMouseStateService {\n public serviceBrand: any;\n\n private _protocols: { [name: string]: ICoreMouseProtocol } = {};\n private _encodings: { [name: string]: CoreMouseEncoding } = {};\n private _activeProtocol: string = '';\n private _activeEncoding: string = '';\n private _customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined;\n\n private readonly _onProtocolChange = this._register(new Emitter());\n public readonly onProtocolChange = this._onProtocolChange.event;\n\n constructor() {\n super();\n\n // register default protocols and encodings\n for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);\n for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);\n // call reset to set defaults\n this.reset();\n }\n\n public addProtocol(name: string, protocol: ICoreMouseProtocol): void {\n this._protocols[name] = protocol;\n }\n\n public addEncoding(name: string, encoding: CoreMouseEncoding): void {\n this._encodings[name] = encoding;\n }\n\n public get activeProtocol(): string {\n return this._activeProtocol;\n }\n\n public get areMouseEventsActive(): boolean {\n return this._protocols[this._activeProtocol].events !== 0;\n }\n\n public set activeProtocol(name: string) {\n if (!this._protocols[name]) {\n throw new Error(`unknown protocol \"${name}\"`);\n }\n this._activeProtocol = name;\n this._onProtocolChange.fire(this._protocols[name].events);\n }\n\n public get activeEncoding(): string {\n return this._activeEncoding;\n }\n\n public set activeEncoding(name: string) {\n if (!this._encodings[name]) {\n throw new Error(`unknown encoding \"${name}\"`);\n }\n this._activeEncoding = name;\n }\n\n public reset(): void {\n this.activeProtocol = 'NONE';\n this.activeEncoding = 'DEFAULT';\n }\n\n public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void {\n this._customWheelEventHandler = customWheelEventHandler;\n }\n\n public allowCustomWheelEvent(ev: WheelEvent): boolean {\n return this._customWheelEventHandler ? this._customWheelEventHandler(ev) !== false : true;\n }\n\n public restrictMouseEvent(e: ICoreMouseEvent): boolean {\n return this._protocols[this._activeProtocol].restrict(e);\n }\n\n public encodeMouseEvent(e: ICoreMouseEvent): string {\n return this._encodings[this._activeEncoding](e);\n }\n\n public get isDefaultEncoding(): boolean {\n return this._activeEncoding === 'DEFAULT';\n }\n\n public get isPixelEncoding(): boolean {\n return this._activeEncoding === 'SGR_PIXELS';\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IUnicodeService, IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from './Services';\nimport { Emitter } from '../Event';\n\nexport class UnicodeService implements IUnicodeService {\n public serviceBrand: any;\n\n private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);\n private _active: string = '';\n private _activeProvider!: IUnicodeVersionProvider;\n\n private readonly _onChange = new Emitter();\n public readonly onChange = this._onChange.event;\n\n public static extractShouldJoin(value: UnicodeCharProperties): boolean {\n return (value & 1) !== 0;\n }\n public static extractWidth(value: UnicodeCharProperties): UnicodeCharWidth {\n return ((value >> 1) & 0x3) as UnicodeCharWidth;\n }\n public static extractCharKind(value: UnicodeCharProperties): number {\n return value >> 3;\n }\n public static createPropertyValue(state: number, width: number, shouldJoin: boolean = false): UnicodeCharProperties {\n return ((state & 0xffffff) << 3) | ((width & 3) << 1) | (shouldJoin?1:0);\n }\n\n public dispose(): void {\n this._onChange.dispose();\n }\n\n public get versions(): string[] {\n return Object.keys(this._providers);\n }\n\n public get activeVersion(): string {\n return this._active;\n }\n\n public set activeVersion(version: string) {\n if (!this._providers[version]) {\n throw new Error(`unknown Unicode version \"${version}\"`);\n }\n this._active = version;\n this._activeProvider = this._providers[version];\n this._onChange.fire(version);\n }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._providers[provider.version] = provider;\n if (!this._active) {\n this.activeVersion = provider.version;\n }\n }\n\n /**\n * Unicode version dependent interface.\n */\n public wcwidth(num: number): UnicodeCharWidth {\n return this._activeProvider.wcwidth(num);\n }\n\n public getStringCellWidth(s: string): number {\n let result = 0;\n let precedingInfo = 0;\n const length = s.length;\n for (let i = 0; i < length; ++i) {\n let code = s.charCodeAt(i);\n // surrogate pair first\n if (0xD800 <= code && code <= 0xDBFF) {\n if (++i >= length) {\n // this should not happen with strings retrieved from\n // Buffer.translateToString as it converts from UTF-32\n // and therefore always should contain the second part\n // for any other string we still have to handle it somehow:\n // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n return result + this.wcwidth(code);\n }\n const second = s.charCodeAt(i);\n // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n // otherwise treat them independently (UCS-2 behavior)\n if (0xDC00 <= second && second <= 0xDFFF) {\n code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n } else {\n result += this.wcwidth(second);\n }\n }\n const currentInfo = this.charProperties(code, precedingInfo);\n let chWidth = UnicodeService.extractWidth(currentInfo);\n if (UnicodeService.extractShouldJoin(currentInfo)) {\n chWidth -= UnicodeService.extractWidth(precedingInfo);\n }\n result += chWidth;\n precedingInfo = currentInfo;\n }\n return result;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n return this._activeProvider.charProperties(codepoint, preceding);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IUnicodeVersionProvider, UnicodeCharProperties, UnicodeCharWidth } from '../services/Services';\nimport { UnicodeService } from '../services/UnicodeService';\n\nconst BMP_COMBINING = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n];\nconst HIGH_COMBINING = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n];\n\n// BMP lookup table, lazy initialized during first addon loading\nlet table: Uint8Array;\n\nfunction bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1]) {\n return false;\n }\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1]) {\n min = mid + 1;\n } else if (ucs < data[mid][0]) {\n max = mid - 1;\n } else {\n return true;\n }\n }\n return false;\n}\n\nexport class UnicodeV6 implements IUnicodeVersionProvider {\n public readonly version = '6';\n\n constructor() {\n // init lookup table once\n if (!table) {\n table = new Uint8Array(65536);\n table.fill(1);\n table[0] = 0;\n // control chars\n table.fill(0, 1, 32);\n table.fill(0, 0x7f, 0xa0);\n\n // apply wide char rules first\n // wide chars\n table.fill(2, 0x1100, 0x1160);\n table[0x2329] = 2;\n table[0x232a] = 2;\n table.fill(2, 0x2e80, 0xa4d0);\n table[0x303f] = 1; // wrongly in last line\n\n table.fill(2, 0xac00, 0xd7a4);\n table.fill(2, 0xf900, 0xfb00);\n table.fill(2, 0xfe10, 0xfe1a);\n table.fill(2, 0xfe30, 0xfe70);\n table.fill(2, 0xff00, 0xff61);\n table.fill(2, 0xffe0, 0xffe7);\n\n // apply combining last to ensure we overwrite\n // wrongly wide set chars:\n // the original algo evals combining first and falls\n // through to wide check so we simply do here the opposite\n // combining 0\n for (let r = 0; r < BMP_COMBINING.length; ++r) {\n table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);\n }\n }\n }\n\n public wcwidth(num: number): UnicodeCharWidth {\n if (num < 32) return 0;\n if (num < 127) return 1;\n if (num < 65536) return table[num] as UnicodeCharWidth;\n if (bisearch(num, HIGH_COMBINING)) return 0;\n if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2;\n return 1;\n }\n\n public charProperties(codepoint: number, preceding: UnicodeCharProperties): UnicodeCharProperties {\n let width = this.wcwidth(codepoint);\n let shouldJoin = width === 0 && preceding !== 0;\n // HACK: Ideally this file would not depend on the service which uses it\n if (shouldJoin) {\n const oldWidth = UnicodeService.extractWidth(preceding);\n if (oldWidth === 0) {\n shouldJoin = false;\n } else if (oldWidth > width) {\n width = oldWidth;\n }\n }\n return UnicodeService.createPropertyValue(0, width, shouldJoin);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharsetService } from './Services';\nimport { ICharset } from '../Types';\n\nexport class CharsetService implements ICharsetService {\n public serviceBrand: any;\n\n public charset: ICharset | undefined;\n public glevel: number = 0;\n\n private _charsets: (ICharset | undefined)[] = [];\n\n public get charsets(): (ICharset | undefined)[] {\n return this._charsets;\n }\n\n public reset(): void {\n this.charset = undefined;\n this._charsets = [];\n this.glevel = 0;\n }\n\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this._charsets[g];\n }\n\n public setgCharset(g: number, charset: ICharset | undefined): void {\n this._charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './buffer/Constants';\nimport { IBufferService } from './services/Services';\n\nexport function updateWindowsModeWrappedState(bufferService: IBufferService): void {\n // Winpty does not support wraparound mode which means that lines will never\n // be marked as wrapped. This causes issues for things like copying a line\n // retaining the wrapped new line characters or if consumers are listening\n // in on the data stream.\n //\n // The workaround for this is to listen to every incoming line feed and mark\n // the line as wrapped if the last character in the previous line is not a\n // space. This is certainly not without its problems, but generally on\n // Windows when text reaches the end of the terminal it's likely going to be\n // wrapped.\n const line = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y - 1);\n const lastChar = line?.get(bufferService.cols - 1);\n\n const nextLine = bufferService.buffer.lines.get(bufferService.buffer.ybase + bufferService.buffer.y);\n if (nextLine && lastChar) {\n nextLine.isWrapped = (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE);\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IParams, ParamsArray } from './Types';\n\nconst enum Constants {\n /**\n * Max value supported for a single param/subparam (clamped to positive int32 range)\n */\n MAX_VALUE = 0x7FFFFFFF,\n /**\n * Max allowed subparams for a single sequence (hardcoded limitation)\n */\n MAX_SUBPARAMS = 256\n}\n\n/**\n * Params storage class.\n * This type is used by the parser to accumulate sequence parameters and sub parameters\n * and transmit them to the input handler actions.\n *\n * NOTES:\n * - params object for action handlers is borrowed, use `.toArray` or `.clone` to get a copy\n * - never read beyond `params.length - 1` (likely to contain arbitrary data)\n * - `.getSubParams` returns a borrowed typed array, use `.getSubParamsAll` for cloned sub params\n * - hardcoded limitations:\n * - max. value for a single (sub) param is 2^31 - 1 (greater values are clamped to that)\n * - max. 256 sub params possible\n * - negative values are not allowed beside -1 (placeholder for default value)\n *\n * About ZDM (Zero Default Mode):\n * ZDM is not orchestrated by this class. If the parser is in ZDM,\n * it should add 0 for empty params, otherwise -1. This does not apply\n * to subparams, empty subparams should always be added with -1.\n */\nexport class Params implements IParams {\n // params store and length\n public params: Int32Array;\n public length: number;\n\n // sub params store and length\n protected _subParams: Int32Array;\n protected _subParamsLength: number;\n\n // sub params offsets from param: param idx --> [start, end] offset\n private _subParamsIdx: Uint16Array;\n private _rejectDigits: boolean;\n private _rejectSubDigits: boolean;\n private _digitIsSub: boolean;\n\n /**\n * Create a `Params` type from JS array representation.\n */\n public static fromArray(values: ParamsArray): Params {\n const params = new Params();\n if (!values.length) {\n return params;\n }\n // skip leading sub params\n for (let i = (Array.isArray(values[0])) ? 1 : 0; i < values.length; ++i) {\n const value = values[i];\n if (Array.isArray(value)) {\n for (let k = 0; k < value.length; ++k) {\n params.addSubParam(value[k]);\n }\n } else {\n params.addParam(value);\n }\n }\n return params;\n }\n\n /**\n * @param maxLength max length of storable parameters\n * @param maxSubParamsLength max length of storable sub parameters\n */\n constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {\n if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {\n throw new Error('maxSubParamsLength must not be greater than 256');\n }\n this.params = new Int32Array(maxLength);\n this.length = 0;\n this._subParams = new Int32Array(maxSubParamsLength);\n this._subParamsLength = 0;\n this._subParamsIdx = new Uint16Array(maxLength);\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Clone object.\n */\n public clone(): Params {\n const newParams = new Params(this.maxLength, this.maxSubParamsLength);\n newParams.params.set(this.params);\n newParams.length = this.length;\n newParams._subParams.set(this._subParams);\n newParams._subParamsLength = this._subParamsLength;\n newParams._subParamsIdx.set(this._subParamsIdx);\n newParams._rejectDigits = this._rejectDigits;\n newParams._rejectSubDigits = this._rejectSubDigits;\n newParams._digitIsSub = this._digitIsSub;\n return newParams;\n }\n\n /**\n * Get a JS array representation of the current parameters and sub parameters.\n * The array is structured as follows:\n * sequence: \"1;2:3:4;5::6\"\n * array : [1, 2, [3, 4], 5, [-1, 6]]\n */\n public toArray(): ParamsArray {\n const res: ParamsArray = [];\n for (let i = 0; i < this.length; ++i) {\n res.push(this.params[i]);\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n res.push(Array.prototype.slice.call(this._subParams, start, end));\n }\n }\n return res;\n }\n\n /**\n * Reset to initial empty state.\n */\n public reset(): void {\n this.length = 0;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n }\n\n /**\n * Reset and add 0 as first param (ZDM).\n */\n public resetZdm(): void {\n this.length = 1;\n this._subParamsLength = 0;\n this._rejectDigits = false;\n this._rejectSubDigits = false;\n this._digitIsSub = false;\n this._subParamsIdx[0] = 0;\n this.params[0] = 0;\n }\n\n /**\n * Add a parameter value.\n * `Params` only stores up to `maxLength` parameters, any later\n * parameter will be ignored.\n * Note: VT devices only stored up to 16 values, xterm seems to\n * store up to 30.\n */\n public addParam(value: number): void {\n this._digitIsSub = false;\n if (this.length >= this.maxLength) {\n this._rejectDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;\n this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n }\n\n /**\n * Add a sub parameter value.\n * The sub parameter is automatically associated with the last parameter value.\n * Thus it is not possible to add a subparameter without any parameter added yet.\n * `Params` only stores up to `maxSubParamsLength` sub parameters, any later\n * sub parameter will be ignored.\n */\n public addSubParam(value: number): void {\n this._digitIsSub = true;\n if (!this.length) {\n return;\n }\n if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) {\n this._rejectSubDigits = true;\n return;\n }\n if (value < -1) {\n throw new Error('values less than -1 are not allowed');\n }\n this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;\n this._subParamsIdx[this.length - 1]++;\n }\n\n /**\n * Whether parameter at index `idx` has sub parameters.\n */\n public hasSubParams(idx: number): boolean {\n return ((this._subParamsIdx[idx] & 0xFF) - (this._subParamsIdx[idx] >> 8) > 0);\n }\n\n /**\n * Return sub parameters for parameter at index `idx`.\n * Note: The values are borrowed, thus you need to copy\n * the values if you need to hold them in nonlocal scope.\n */\n public getSubParams(idx: number): Int32Array | null {\n const start = this._subParamsIdx[idx] >> 8;\n const end = this._subParamsIdx[idx] & 0xFF;\n if (end - start > 0) {\n return this._subParams.subarray(start, end);\n }\n return null;\n }\n\n /**\n * Return all sub parameters as {idx: subparams} mapping.\n * Note: The values are not borrowed.\n */\n public getSubParamsAll(): {[idx: number]: Int32Array} {\n const result: {[idx: number]: Int32Array} = {};\n for (let i = 0; i < this.length; ++i) {\n const start = this._subParamsIdx[i] >> 8;\n const end = this._subParamsIdx[i] & 0xFF;\n if (end - start > 0) {\n result[i] = this._subParams.slice(start, end);\n }\n }\n return result;\n }\n\n /**\n * Add a single digit value to current parameter.\n * This is used by the parser to account digits on a char by char basis.\n */\n public addDigit(value: number): void {\n let length;\n if (this._rejectDigits\n || !(length = this._digitIsSub ? this._subParamsLength : this.length)\n || (this._digitIsSub && this._rejectSubDigits)\n ) {\n return;\n }\n\n const store = this._digitIsSub ? this._subParams : this.params;\n const cur = store[length - 1];\n store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from './Types';\nimport { OscState, ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IOscHandler[] = [];\n\nexport class OscParser implements IOscParser {\n private _state = OscState.START;\n private _active = EMPTY_HANDLERS;\n private _id = -1;\n private _handlers: IHandlerCollection = Object.create(null);\n private _handlerFb: OscFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public registerHandler(ident: number, handler: IOscHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n public setHandlerFallback(handler: OscFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers if payload was already sent\n if (this._state === OscState.PAYLOAD) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n\n private _start(): void {\n this._active = this._handlers[this._id] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._id, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n private _put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._id, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public start(): void {\n // always reset leftover handlers\n this.reset();\n this._state = OscState.ID;\n }\n\n /**\n * Put data to current OSC command.\n * Expects the identifier of the OSC command in the form\n * OSC id ; payload ST/BEL\n * Payload chunks are not further processed and get\n * directly passed to the handlers.\n */\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._state === OscState.ABORT) {\n return;\n }\n if (this._state === OscState.ID) {\n while (start < end) {\n const code = data[start++];\n if (code === 0x3b) {\n this._state = OscState.PAYLOAD;\n this._start();\n break;\n }\n if (code < 0x30 || 0x39 < code) {\n this._state = OscState.ABORT;\n return;\n }\n if (this._id === -1) {\n this._id = 0;\n }\n this._id = this._id * 10 + code - 48;\n }\n }\n if (this._state === OscState.PAYLOAD && end - start > 0) {\n this._put(data, start, end);\n }\n }\n\n /**\n * Indicates end of an OSC command.\n * Whether the OSC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (this._state === OscState.START) {\n return;\n }\n // do nothing if command was faulty\n if (this._state !== OscState.ABORT) {\n // if we are still in ID state and get an early end\n // means that the command has no payload thus we still have\n // to announce START and send END right after\n if (this._state === OscState.ID) {\n this._start();\n }\n\n if (!this._active.length) {\n this._handlerFb(this._id, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers\n // we always have to call .end for proper cleanup,\n // here we use `success` to indicate whether a handler should execute\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n\n }\n this._active = EMPTY_HANDLERS;\n this._id = -1;\n this._state = OscState.START;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as OSC handlers.\n */\nexport class OscHandler implements IOscHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(OscHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../Types';\nimport { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from './Types';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { Params } from './Params';\nimport { ParserConstants } from './Constants';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IDcsHandler[] = [];\n\nexport class DcsParser implements IDcsParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active: IDcsHandler[] = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: DcsFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public registerHandler(ident: number, handler: IDcsHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public reset(): void {\n // force cleanup leftover handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].unhook(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public hook(ident: number, params: IParams): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'HOOK', params);\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].hook(params);\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n public unhook(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'UNHOOK', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].unhook(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n// predefine empty params as [0] (ZDM)\nconst EMPTY_PARAMS = new Params();\nEMPTY_PARAMS.addParam(0);\n\n/**\n * Convenient class to create a DCS handler from a single callback function.\n * Note: The payload is currently limited to 50 MB (hardcoded).\n */\nexport class DcsHandler implements IDcsHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);\n private _params: IParams = EMPTY_PARAMS;\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string, params: IParams) => boolean | Promise) { }\n\n public hook(params: IParams): void {\n // since we need to preserve params until `unhook`, we have to clone it\n // (only borrowed from parser and spans multiple parser states)\n // perf optimization:\n // clone only, if we have non empty params, otherwise stick with default\n this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public unhook(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString(), this._params);\n if (ret instanceof Promise) {\n // need to hold data and params until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._params = EMPTY_PARAMS;\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, ISubParserStackState } from './Types';\nimport { ParserConstants } from './Constants';\nimport { utf32ToString } from '../input/TextDecoder';\nimport { IDisposable } from '../Types';\nimport { LimitedStringBuilder } from '../StringBuilder';\n\nconst EMPTY_HANDLERS: IApcHandler[] = [];\n\n/**\n * APC Parser for handling Application Program Command sequences.\n * APC sequences use the format: ESC _ ESC \\\n *\n * Unlike OSC which uses numeric identifiers (e.g., OSC 1337),\n * APC uses the first character as the identifier (e.g., 'G' for Kitty graphics).\n * The identifier is the character code of the first byte after ESC _.\n */\nexport class ApcParser implements IApcParser {\n private _handlers: IHandlerCollection = Object.create(null);\n private _active = EMPTY_HANDLERS;\n private _ident: number = 0;\n private _handlerFb: ApcFallbackHandlerType = () => { };\n private _stack: ISubParserStackState = {\n paused: false,\n loopPosition: 0,\n fallThrough: false\n };\n\n /**\n * Register an APC handler for a specific identifier.\n * @param ident The character code of the first byte (e.g., 0x47 for 'G')\n * @param handler The handler to register\n */\n public registerHandler(ident: number, handler: IApcHandler): IDisposable {\n this._handlers[ident] ??= [];\n const handlerList = this._handlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n\n public clearHandler(ident: number): void {\n if (this._handlers[ident]) delete this._handlers[ident];\n }\n\n public setHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._handlerFb = handler;\n }\n\n public dispose(): void {\n this._handlers = Object.create(null);\n this._handlerFb = () => { };\n this._active = EMPTY_HANDLERS;\n }\n\n public reset(): void {\n // force cleanup handlers\n if (this._active.length) {\n for (let j = this._stack.paused ? this._stack.loopPosition - 1 : this._active.length - 1; j >= 0; --j) {\n this._active[j].end(false);\n }\n }\n this._stack.paused = false;\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n\n public start(ident: number): void {\n // always reset leftover handlers\n this.reset();\n this._ident = ident;\n this._active = this._handlers[ident] || EMPTY_HANDLERS;\n if (!this._active.length) {\n this._handlerFb(this._ident, 'START');\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].start();\n }\n }\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));\n } else {\n for (let j = this._active.length - 1; j >= 0; j--) {\n this._active[j].put(data, start, end);\n }\n }\n }\n\n /**\n * Indicates end of an APC command.\n * Whether the APC got aborted or finished normally\n * is indicated by `success`.\n */\n public end(success: boolean, promiseResult: boolean = true): void | Promise {\n if (!this._active.length) {\n this._handlerFb(this._ident, 'END', success);\n } else {\n let handlerResult: boolean | Promise = false;\n let j = this._active.length - 1;\n let fallThrough = false;\n if (this._stack.paused) {\n j = this._stack.loopPosition - 1;\n handlerResult = promiseResult;\n fallThrough = this._stack.fallThrough;\n this._stack.paused = false;\n }\n if (!fallThrough && handlerResult === false) {\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(success);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = false;\n return handlerResult;\n }\n }\n j--;\n }\n // cleanup left over handlers (fallThrough for async)\n for (; j >= 0; j--) {\n handlerResult = this._active[j].end(false);\n if (handlerResult instanceof Promise) {\n this._stack.paused = true;\n this._stack.loopPosition = j;\n this._stack.fallThrough = true;\n return handlerResult;\n }\n }\n }\n this._active = EMPTY_HANDLERS;\n this._ident = 0;\n }\n}\n\n/**\n * Convenient class to allow attaching string based handler functions\n * as APC handlers.\n */\nexport class ApcHandler implements IApcHandler {\n private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;\n\n private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);\n private _hitLimit: boolean = false;\n\n constructor(private _handler: (data: string) => boolean | Promise) { }\n\n public start(): void {\n this._data.reset();\n this._hitLimit = false;\n }\n\n public put(data: Uint32Array, start: number, end: number): void {\n if (this._hitLimit) {\n return;\n }\n if (this._data.append(utf32ToString(data, start, end))) {\n this._hitLimit = true;\n }\n }\n\n public end(success: boolean): boolean | Promise {\n let ret: boolean | Promise = false;\n if (this._hitLimit) {\n ret = false;\n } else if (success) {\n ret = this._handler(this._data.toString());\n if (ret instanceof Promise) {\n // need to hold data until `ret` got resolved\n // dont care for errors, data will be freed anyway on next start\n return ret.then(res => {\n this._data.reset();\n this._hitLimit = false;\n return res;\n });\n }\n }\n this._data.reset();\n this._hitLimit = false;\n return ret;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from './Types';\nimport { ParserState, ParserAction } from './Constants';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { IDisposable } from '../Types';\nimport { Params } from './Params';\nimport { OscParser } from './OscParser';\nimport { DcsParser } from './DcsParser';\nimport { ApcParser } from './ApcParser';\n\n/**\n * VT commands done by the parser\n */\n// @vt: #Y ESC CSI \"Control Sequence Introducer\" \"ESC [\" \"Start of a CSI sequence.\"\n// @vt: #Y ESC OSC \"Operating System Command\" \"ESC ]\" \"Start of an OSC sequence.\"\n// @vt: #Y ESC DCS \"Device Control String\" \"ESC P\" \"Start of a DCS sequence.\"\n// @vt: #Y ESC ST \"String Terminator\" \"ESC \\\\\" \"Terminator used for string type sequences.\"\n// @vt: #Y ESC PM \"Privacy Message\" \"ESC ^\" \"Start of a privacy message.\"\n// @vt: #Y ESC APC \"Application Program Command\" \"ESC _\" \"Start of an APC sequence.\"\n// @vt: #Y C1 CSI \"Control Sequence Introducer\" \"\\x9B\" \"Start of a CSI sequence.\"\n// @vt: #Y C1 OSC \"Operating System Command\" \"\\x9D\" \"Start of an OSC sequence.\"\n// @vt: #Y C1 DCS \"Device Control String\" \"\\x90\" \"Start of a DCS sequence.\"\n// @vt: #Y C1 ST \"String Terminator\" \"\\x9C\" \"Terminator used for string type sequences.\"\n// @vt: #Y C1 PM \"Privacy Message\" \"\\x9E\" \"Start of a privacy message.\"\n// @vt: #Y C1 APC \"Application Program Command\" \"\\x9F\" \"Start of an APC sequence.\"\n// @vt: #Y C0 NUL \"Null\" \"\\0, \\x00\" \"NUL is ignored.\"\n// @vt: #Y C0 ESC \"Escape\" \"\\e, \\x1B\" \"Start of a sequence. Cancels any other sequence.\"\n\n/**\n * Table values are generated like this:\n * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode\n * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState\n */\nconst enum TableAccess {\n TRANSITION_ACTION_SHIFT = 8,\n TRANSITION_STATE_MASK = 255,\n INDEX_STATE_SHIFT = 8\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n */\nexport class TransitionTable {\n public table: Uint16Array;\n\n constructor(length: number) {\n this.table = new Uint16Array(length);\n }\n\n /**\n * Set default transition.\n * @param action default action\n * @param next default next state\n */\n public setDefault(action: ParserAction, next: ParserState): void {\n this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);\n }\n\n /**\n * Add a transition to the transition table.\n * @param code input character code\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n\n /**\n * Add transitions for multiple input character codes.\n * @param codes input character code array\n * @param state current parser state\n * @param action parser action to be done\n * @param next next parser state\n */\n public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {\n for (let i = 0; i < codes.length; i++) {\n this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;\n }\n }\n}\n\n\n// Pseudo-character placeholder for printable non-ascii characters (unicode).\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n // table size:\n // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1\n const table: TransitionTable = new TransitionTable(4257);\n\n // range macro for byte\n const BYTE_VALUES = 256;\n const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);\n const r = (start: number, end: number): number[] => blueprint.slice(start, end);\n\n // Default definitions.\n const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded\n const EXECUTABLES = r(0x00, 0x18);\n EXECUTABLES.push(0x19);\n EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n\n const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);\n\n // set default transition\n table.setDefault(ParserAction.ERROR, ParserState.GROUND);\n // printables\n table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n // global anywhere rules\n for (const state of states) {\n table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC\n table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC\n table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM\n table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC\n table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI\n table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS\n }\n // rules for executables and 7f\n table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n // osc\n table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n // sos/pm\n table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);\n table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);\n // apc\n table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);\n table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);\n table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);\n table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);\n // csi entries\n table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n // esc_intermediate\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n // dcs entry\n table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n // special handling of unicode chars\n table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);\n return table;\n})();\n\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n *\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` constructor argument and\n * reimplement the `parse` method.\n *\n * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)\n * as suggested by the original parser, thus empty parameters are set to 0.\n * This is not in line with the latest ECMA-48 specification\n * (ZDM was part of the early specs and got completely removed later on).\n *\n * Other than the original parser from vt100.net this parser supports\n * sub parameters in digital parameters separated by colons. Empty sub parameters\n * are set to -1 (no ZDM for sub parameters).\n *\n * About prefix and intermediate bytes:\n * This parser follows the assumptions of the vt100.net parser with these restrictions:\n * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f\n * - max. two intermediates are respected, byte range 0x20 .. 0x2f\n * Note that this is not in line with ECMA-48 which does not limit either of those.\n * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently\n * there are no known sequences that follow the broader definition of the specification.\n *\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n public initialState: number;\n public currentState: number;\n public precedingJoinState: number; // UnicodeJoinProperties\n\n // buffers over several parse calls\n protected _params: Params;\n protected _collect: number;\n\n // handler lookup containers\n protected _printHandler: PrintHandlerType;\n protected _executeHandlers: { [flag: number]: ExecuteHandlerType };\n // fast path for EXE bytes < 0x18\n protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];\n protected _csiHandlers: IHandlerCollection;\n protected _escHandlers: IHandlerCollection;\n protected readonly _oscParser: IOscParser;\n protected readonly _dcsParser: IDcsParser;\n protected readonly _apcParser: IApcParser;\n protected _errorHandler: (state: IParsingState) => IParsingState;\n\n // fallback handlers\n protected _printHandlerFb: PrintFallbackHandlerType;\n protected _executeHandlerFb: ExecuteFallbackHandlerType;\n protected _csiHandlerFb: CsiFallbackHandlerType;\n protected _escHandlerFb: EscFallbackHandlerType;\n protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n // parser stack save for async handler support\n protected _parseStack: IParserStackState = {\n state: ParserStackType.NONE,\n handlers: [],\n handlerPos: 0,\n transition: 0,\n chunkPos: 0\n };\n\n constructor(\n protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE\n ) {\n super();\n\n this.initialState = ParserState.GROUND;\n this.currentState = this.initialState;\n this._params = new Params(); // defaults to 32 storable params/subparams\n this._params.addParam(0); // ZDM\n this._collect = 0;\n this.precedingJoinState = 0;\n\n // set default fallback handlers and handler lookup containers\n this._printHandlerFb = (data, start, end): void => { };\n this._executeHandlerFb = (code: number): void => { };\n this._csiHandlerFb = (ident: number, params: IParams): void => { };\n this._escHandlerFb = (ident: number): void => { };\n this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n this._printHandler = this._printHandlerFb;\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._csiHandlers = Object.create(null);\n this._escHandlers = Object.create(null);\n this._register(toDisposable(() => {\n this._csiHandlers = Object.create(null);\n this._executeHandlers = Object.create(null);\n this._executeHandlersArr = new Array(0x18).fill(undefined);\n this._escHandlers = Object.create(null);\n }));\n this._oscParser = this._register(new OscParser());\n this._dcsParser = this._register(new DcsParser());\n this._apcParser = this._register(new ApcParser());\n this._errorHandler = this._errorHandlerFb;\n\n // swallow 7bit ST (ESC+\\)\n this.registerEscHandler({ final: '\\\\' }, () => true);\n }\n\n protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {\n let res = 0;\n if (id.prefix) {\n if (id.prefix.length > 1) {\n throw new Error('only one byte as prefix supported');\n }\n res = id.prefix.charCodeAt(0);\n if (res < 0x3c || res > 0x3f) {\n throw new Error('prefix must be in range 0x3c .. 0x3f');\n }\n }\n if (id.intermediates) {\n if (id.intermediates.length > 2) {\n throw new Error('only two bytes as intermediates are supported');\n }\n for (let i = 0; i < id.intermediates.length; ++i) {\n const intermediate = id.intermediates.charCodeAt(i);\n if (0x20 > intermediate || intermediate > 0x2f) {\n throw new Error('intermediate must be in range 0x20 .. 0x2f');\n }\n res <<= 8;\n res |= intermediate;\n }\n }\n if (id.final.length !== 1) {\n throw new Error('final must be a single byte');\n }\n const finalCode = id.final.charCodeAt(0);\n if (finalRange[0] > finalCode || finalCode > finalRange[1]) {\n throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);\n }\n res <<= 8;\n res |= finalCode;\n\n return res;\n }\n\n public identToString(ident: number): string {\n const res: string[] = [];\n while (ident) {\n res.push(String.fromCharCode(ident & 0xFF));\n ident >>= 8;\n }\n return res.reverse().join('');\n }\n\n public setPrintHandler(handler: PrintHandlerType): void {\n this._printHandler = handler;\n }\n public clearPrintHandler(): void {\n this._printHandler = this._printHandlerFb;\n }\n\n public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {\n const ident = this._identifier(id, [0x30, 0x7e]);\n this._escHandlers[ident] ??= [];\n const handlerList = this._escHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearEscHandler(id: IFunctionIdentifier): void {\n if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];\n }\n public setEscHandlerFallback(handler: EscFallbackHandlerType): void {\n this._escHandlerFb = handler;\n }\n\n public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {\n const code = flag.charCodeAt(0);\n this._executeHandlers[code] = handler;\n if (code < 0x18) this._executeHandlersArr[code] = handler;\n }\n public clearExecuteHandler(flag: string): void {\n const code = flag.charCodeAt(0);\n if (this._executeHandlers[code]) delete this._executeHandlers[code];\n if (code < 0x18) this._executeHandlersArr[code] = undefined;\n }\n public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {\n this._executeHandlerFb = handler;\n }\n\n public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {\n const ident = this._identifier(id);\n this._csiHandlers[ident] ??= [];\n const handlerList = this._csiHandlers[ident];\n handlerList.push(handler);\n return {\n dispose: () => {\n const handlerIndex = handlerList.indexOf(handler);\n if (handlerIndex !== -1) {\n handlerList.splice(handlerIndex, 1);\n }\n }\n };\n }\n public clearCsiHandler(id: IFunctionIdentifier): void {\n if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];\n }\n public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {\n this._csiHandlerFb = callback;\n }\n\n public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {\n return this._dcsParser.registerHandler(this._identifier(id), handler);\n }\n public clearDcsHandler(id: IFunctionIdentifier): void {\n this._dcsParser.clearHandler(this._identifier(id));\n }\n public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {\n this._dcsParser.setHandlerFallback(handler);\n }\n\n public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {\n return this._oscParser.registerHandler(ident, handler);\n }\n public clearOscHandler(ident: number): void {\n this._oscParser.clearHandler(ident);\n }\n public setOscHandlerFallback(handler: OscFallbackHandlerType): void {\n this._oscParser.setHandlerFallback(handler);\n }\n\n public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {\n id.prefix = undefined; // APC does not support prefix byte\n return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);\n }\n public clearApcHandler(id: IFunctionIdentifier): void {\n id.prefix = undefined; // APC does not support prefix byte\n this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));\n }\n public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {\n this._apcParser.setHandlerFallback(handler);\n }\n\n public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n this._errorHandler = callback;\n }\n public clearErrorHandler(): void {\n this._errorHandler = this._errorHandlerFb;\n }\n\n /**\n * Reset parser to initial values.\n *\n * This can also be used to lift the improper continuation error condition\n * when dealing with async handlers. Use this only as a last resort to silence\n * that error when the terminal has no pending data to be processed. Note that\n * the interrupted async handler might continue its work in the future messing\n * up the terminal state even further.\n */\n public reset(): void {\n this.currentState = this.initialState;\n this._oscParser.reset();\n this._dcsParser.reset();\n this._apcParser.reset();\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n // abort pending continuation from async handler\n // Here the RESET type indicates, that the next parse call will\n // ignore any saved stack, instead continues sync with next codepoint from GROUND\n if (this._parseStack.state !== ParserStackType.NONE) {\n this._parseStack.state = ParserStackType.RESET;\n this._parseStack.handlers = []; // also release handlers ref\n }\n }\n\n /**\n * Async parse support.\n */\n protected _preserveStack(\n state: ParserStackType,\n handlers: ResumableHandlersType,\n handlerPos: number,\n transition: number,\n chunkPos: number\n ): void {\n this._parseStack.state = state;\n this._parseStack.handlers = handlers;\n this._parseStack.handlerPos = handlerPos;\n this._parseStack.transition = transition;\n this._parseStack.chunkPos = chunkPos;\n }\n\n /**\n * Parse UTF32 codepoints in `data` up to `length`.\n *\n * Note: For several actions with high data load the parsing is optimized\n * by using local read ahead loops with hardcoded conditions to\n * avoid costly table lookups. Make sure that any change of table values\n * will be reflected in the loop conditions as well and vice versa.\n * Affected states/actions:\n * - GROUND:PRINT\n * - CSI_PARAM:PARAM\n * - DCS_PARAM:PARAM\n * - OSC_STRING:OSC_PUT\n * - DCS_PASSTHROUGH:DCS_PUT\n *\n * Additionally the following fast paths exist before the table lookup:\n * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)\n * - 7-bit CSI sequences without intermediates (ESC [ params final)\n *\n * Note on asynchronous handler support:\n * Any handler returning a promise will be treated as asynchronous.\n * To keep the in-band blocking working for async handlers, `parse` pauses execution,\n * creates a stack save and returns the promise to the caller.\n * For proper continuation of the paused state it is important\n * to await the promise resolving. On resolve the parse must be repeated\n * with the same chunk of data and the resolved value in `promiseResult`\n * until no promise is returned.\n *\n * Important: With only sync handlers defined, parsing is completely synchronous as well.\n * As soon as an async handler is involved, synchronous parsing is not possible anymore.\n *\n * Boilerplate for proper parsing of multiple chunks with async handlers:\n *\n * ```typescript\n * async function parseMultipleChunks(chunks: Uint32Array[]): Promise {\n * for (const chunk of chunks) {\n * let result: void | Promise;\n * let prev: boolean | undefined;\n * while (result = parser.parse(chunk, chunk.length, prev)) {\n * prev = await result;\n * }\n * }\n * // finished parsing all chunks...\n * }\n * ```\n */\n public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise {\n let code: number;\n let transition: number;\n let start = 0;\n let handlerResult: void | boolean | Promise;\n\n // resume from async handler\n if (this._parseStack.state) {\n // allow sync parser reset even in continuation mode\n // Note: can be used to recover parser from improper continuation error below\n if (this._parseStack.state === ParserStackType.RESET) {\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND\n } else {\n if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {\n /**\n * Reject further parsing on improper continuation after pausing. This is a really bad\n * condition with screwed up execution order and prolly messed up terminal state,\n * therefore we exit hard with an exception and reject any further parsing.\n *\n * Note: With `Terminal.write` usage this exception should never occur, as the top level\n * calls are guaranteed to handle async conditions properly. If you ever encounter this\n * exception in your terminal integration it indicates, that you injected data chunks to\n * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for\n * continuation of a running async handler.\n *\n * It is possible to get rid of this error by calling `reset`. But dont rely on that, as\n * the pending async handler still might mess up the terminal later. Instead fix the\n * faulty async handling, so this error will not be thrown anymore.\n */\n this._parseStack.state = ParserStackType.FAIL;\n throw new Error('improper continuation due to previous async handler, giving up parsing');\n }\n\n // we have to resume the old handler loop if:\n // - return value of the promise was `false`\n // - handlers are not exhausted yet\n const handlers = this._parseStack.handlers;\n let handlerPos = this._parseStack.handlerPos - 1;\n switch (this._parseStack.state) {\n case ParserStackType.CSI:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.ESC:\n if (promiseResult === false && handlerPos > -1) {\n for (; handlerPos >= 0; handlerPos--) {\n handlerResult = (handlers as EscHandlerType[])[handlerPos]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._parseStack.handlerPos = handlerPos;\n return handlerResult;\n }\n }\n }\n this._parseStack.handlers = [];\n break;\n case ParserStackType.DCS:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.OSC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserStackType.APC:\n code = data[this._parseStack.chunkPos];\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);\n if (handlerResult) {\n return handlerResult;\n }\n if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n break;\n }\n // cleanup before continuing with the main sync loop\n this._parseStack.state = ParserStackType.NONE;\n start = this._parseStack.chunkPos + 1;\n this.precedingJoinState = 0;\n this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n\n // continue with main sync loop\n\n // process input string\n for (let i = start; i < length; ++i) {\n code = data[i];\n\n // EXE fast-path: common control bytes (0x00-0x17) in non-payload states\n if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {\n (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);\n this.precedingJoinState = 0;\n continue;\n }\n\n // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop\n if (code === 0x1b\n && this.currentState < ParserState.OSC_STRING\n && i + 2 < length && data[i + 1] === 0x5b\n ) {\n this._params.resetZdm();\n this._collect = 0;\n let k = i + 2;\n let ch = data[k];\n if (ch >= 0x3c && ch <= 0x3f) {\n this._collect = ch;\n k++;\n }\n let csiDone = false;\n for (; k < length; k++) {\n ch = data[k];\n if (ch >= 0x30 && ch <= 0x39) {\n this._params.addDigit(ch - 48);\n } else if (ch === 0x3b) {\n this._params.addParam(0);\n } else if (ch === 0x3a) {\n this._params.addSubParam(-1);\n } else if (ch >= 0x40 && ch <= 0x7e) {\n const handlers = this._csiHandlers[this._collect << 8 | ch];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | ch, this._params);\n }\n this.precedingJoinState = 0;\n i = k;\n this.currentState = ParserState.GROUND;\n csiDone = true;\n break;\n } else {\n break;\n }\n }\n if (!csiDone) {\n i = k - 1;\n this.currentState = ParserState.CSI_PARAM;\n }\n continue;\n }\n\n // normal transition & action lookup\n transition = this._transitions.table[\n this.currentState << TableAccess.INDEX_STATE_SHIFT |\n (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)\n ];\n switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {\n case ParserAction.PRINT:\n // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded\n let c = i;\n const l4 = length - 4;\n while (c < l4\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)\n ) {}\n if (c >= l4) {\n while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {\n c++;\n }\n }\n this._printHandler(data, i, c);\n i = c - 1;\n break;\n case ParserAction.EXECUTE:\n if (this._executeHandlers[code]) this._executeHandlers[code]();\n else this._executeHandlerFb(code);\n this.precedingJoinState = 0;\n break;\n case ParserAction.IGNORE:\n break;\n case ParserAction.ERROR:\n const inject: IParsingState = this._errorHandler(\n {\n position: i,\n code,\n currentState: this.currentState,\n collect: this._collect,\n params: this._params,\n abort: false\n });\n if (inject.abort) return;\n // inject values: currently not implemented\n break;\n case ParserAction.CSI_DISPATCH:\n // Trigger CSI Handler\n const handlers = this._csiHandlers[this._collect << 8 | code];\n let j = handlers ? handlers.length - 1 : -1;\n for (; j >= 0; j--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlers[j](this._params);\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);\n return handlerResult;\n }\n }\n if (j < 0) {\n this._csiHandlerFb(this._collect << 8 | code, this._params);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.PARAM:\n // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)\n do {\n switch (code) {\n case 0x3b:\n this._params.addParam(0); // ZDM\n break;\n case 0x3a:\n this._params.addSubParam(-1);\n break;\n default: // 0x30 - 0x39\n this._params.addDigit(code - 48);\n }\n } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);\n i--;\n break;\n case ParserAction.COLLECT:\n this._collect <<= 8;\n this._collect |= code;\n break;\n case ParserAction.ESC_DISPATCH:\n const handlersEsc = this._escHandlers[this._collect << 8 | code];\n let jj = handlersEsc ? handlersEsc.length - 1 : -1;\n for (; jj >= 0; jj--) {\n // true means success and to stop bubbling\n // a promise indicates an async handler that needs to finish before progressing\n handlerResult = handlersEsc[jj]();\n if (handlerResult === true) {\n break;\n } else if (handlerResult instanceof Promise) {\n this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);\n return handlerResult;\n }\n }\n if (jj < 0) {\n this._escHandlerFb(this._collect << 8 | code);\n }\n this.precedingJoinState = 0;\n break;\n case ParserAction.CLEAR:\n this._params.resetZdm();\n this._collect = 0;\n break;\n case ParserAction.DCS_HOOK:\n this._dcsParser.hook(this._collect << 8 | code, this._params);\n break;\n case ParserAction.DCS_PUT:\n // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f\n // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)\n for (let j = i + 1; ; ++j) {\n if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._dcsParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.DCS_UNHOOK:\n handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.DCS, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.OSC_START:\n this._oscParser.start();\n break;\n case ParserAction.OSC_PUT:\n // inner loop: 0x20 (SP) included, 0x7F (DEL) included\n for (let j = i + 1; ; j++) {\n if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {\n this._oscParser.put(data, i, j);\n i = j - 1;\n break;\n }\n }\n break;\n case ParserAction.OSC_END:\n handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.OSC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n case ParserAction.APC_START:\n this._apcParser.start(this._collect << 8 | code);\n break;\n case ParserAction.APC_PUT:\n // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c\n // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE\n for (let j = i + 1; ; ++j) {\n if (j < length && (\n (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE\n )) continue;\n this._apcParser.put(data, i, j);\n i = j - 1;\n break;\n }\n break;\n case ParserAction.APC_END:\n handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);\n if (handlerResult) {\n this._preserveStack(ParserStackType.APC, [], 0, transition, i);\n return handlerResult;\n }\n if (code === 0x1b) transition |= ParserState.ESCAPE;\n this._params.resetZdm();\n this._collect = 0;\n this.precedingJoinState = 0;\n break;\n }\n this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;\n }\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n\n// 'rgb:' rule - matching: r/g/b | rr/gg/bb | rrr/ggg/bbb | rrrr/gggg/bbbb (hex digits)\nconst RGB_REX = /^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/;\n// '#...' rule - matching any hex digits\nconst HASH_REX = /^[\\da-f]+$/;\n\n/**\n * Parse color spec to RGB values (8 bit per channel).\n * See `man xparsecolor` for details about certain format specifications.\n *\n * Supported formats:\n * - rgb:// with , , in h | hh | hhh | hhhh\n * - #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB\n *\n * All other formats like rgbi: or device-independent string specifications\n * with float numbering are not supported.\n */\nexport function parseColor(data: string): [number, number, number] | undefined {\n if (!data) return;\n // also handle uppercases\n let low = data.toLowerCase();\n if (low.startsWith('rgb:')) {\n // 'rgb:' specifier\n low = low.slice(4);\n const m = RGB_REX.exec(low);\n if (m) {\n const base = m[1] ? 15 : m[4] ? 255 : m[7] ? 4095 : 65535;\n return [\n Math.round(parseInt(m[1] || m[4] || m[7] || m[10], 16) / base * 255),\n Math.round(parseInt(m[2] || m[5] || m[8] || m[11], 16) / base * 255),\n Math.round(parseInt(m[3] || m[6] || m[9] || m[12], 16) / base * 255)\n ];\n }\n } else if (low.startsWith('#')) {\n // '#' specifier\n low = low.slice(1);\n if (HASH_REX.exec(low) && [3, 6, 9, 12].includes(low.length)) {\n const adv = low.length / 3;\n const result: [number, number, number] = [0, 0, 0];\n for (let i = 0; i < 3; ++i) {\n const c = parseInt(low.slice(adv * i, adv * i + adv), 16);\n result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;\n }\n return result;\n }\n }\n\n // Named colors are currently not supported due to the large addition to the xterm.js bundle size\n // they would add. In order to support named colors, we would need some way of optionally loading\n // additional payloads so startup/download time is not bloated (see #3530).\n}\n\n// pad hex output to requested bit width\nfunction pad(n: number, bits: number): string {\n const s = n.toString(16);\n const s2 = s.length < 2 ? '0' + s : s;\n switch (bits) {\n case 4:\n return s[0];\n case 8:\n return s2;\n case 12:\n return (s2 + s2).slice(0, 3);\n default:\n return s2 + s2;\n }\n}\n\n/**\n * Convert a given color to rgb:../../.. string of `bits` depth.\n */\nexport function toRgbString(color: [number, number, number], bits: number = 16): string {\n const [r, g, b] = color;\n return `rgb:${pad(r, bits)}/${pad(g, bits)}/${pad(b, bits)}`;\n}\n", "/**\n * Copyright (c) 2025 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * The xterm.js version. This is updated by the publish script from package.json.\n */\nexport const XTERM_VERSION = '6.1.0-beta.287';\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';\nimport { IAttributeData, IBuffer } from './buffer/Types';\nimport { C0, C1 } from './data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';\nimport { EscapeSequenceParser } from './parser/EscapeSequenceParser';\nimport { Disposable } from './Lifecycle';\nimport { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';\nimport { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';\nimport { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';\nimport { CellData } from './buffer/CellData';\nimport { AttributeData } from './buffer/AttributeData';\nimport { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { UnicodeService } from './services/UnicodeService';\nimport { OscHandler } from './parser/OscParser';\nimport { DcsHandler } from './parser/DcsParser';\nimport { ApcHandler } from './parser/ApcParser';\nimport { parseColor } from './input/XParseColor';\nimport { Emitter } from './Event';\nimport { XTERM_VERSION } from './Version';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };\n\n/**\n * Document xterm VT features here that are currently unsupported\n */\n// @vt: #N DCS DECUDK \"User Defined Keys\" \"DCS Ps ; Ps \\| Pt ST\" \"Definitions for user-defined keys.\"\n// @vt: #N DCS XTGETTCAP \"Request Terminfo String\" \"DCS + q Pt ST\" \"Request Terminfo String.\"\n// @vt: #N DCS XTSETTCAP \"Set Terminfo Data\" \"DCS + p Pt ST\" \"Set Terminfo Data.\"\n// @vt: #N OSC 1 \"Set Icon Name\" \"OSC 1 ; Pt BEL\" \"Set icon name.\"\n\n/**\n * Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.\n */\nconst enum Constants {\n MAX_PARSEBUFFER_LENGTH = 131072,\n /** Limit length of title and icon name stacks. */\n STACK_LIMIT = 10,\n // create a warning log if an async handler takes longer than the limit (in ms)\n SLOW_ASYNC_LIMIT = 5000\n}\n\n// map params to window option\nfunction paramToWindowOption(n: number, opts: IWindowOptions): boolean {\n if (n > 24) {\n return opts.setWinLines || false;\n }\n switch (n) {\n case 1: return !!opts.restoreWin;\n case 2: return !!opts.minimizeWin;\n case 3: return !!opts.setWinPosition;\n case 4: return !!opts.setWinSizePixels;\n case 5: return !!opts.raiseWin;\n case 6: return !!opts.lowerWin;\n case 7: return !!opts.refreshWin;\n case 8: return !!opts.setWinSizeChars;\n case 9: return !!opts.maximizeWin;\n case 10: return !!opts.fullscreenWin;\n case 11: return !!opts.getWinState;\n case 13: return !!opts.getWinPosition;\n case 14: return !!opts.getWinSizePixels;\n case 15: return !!opts.getScreenSizePixels;\n case 16: return !!opts.getCellSizePixels;\n case 18: return !!opts.getWinSizeChars;\n case 19: return !!opts.getScreenSizeChars;\n case 20: return !!opts.getIconTitle;\n case 21: return !!opts.getWinTitle;\n case 22: return !!opts.pushTitle;\n case 23: return !!opts.popTitle;\n case 24: return !!opts.setWinLines;\n }\n return false;\n}\n\nexport enum WindowsOptionsReportType {\n GET_WIN_SIZE_PIXELS = 0,\n GET_CELL_SIZE_PIXELS = 1\n}\n\n// Work variables to avoid garbage collection\nlet $temp = 0;\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n private _parseBuffer: Uint32Array = new Uint32Array(4096);\n private _stringDecoder: StringToUtf32 = new StringToUtf32();\n private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();\n private _windowTitle = '';\n private _iconName = '';\n private _dirtyRowTracker: IDirtyRowTracker;\n protected _windowTitleStack: string[] = [];\n protected _iconNameStack: string[] = [];\n\n private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();\n public getAttrData(): IAttributeData { return this._curAttrData; }\n private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();\n\n private _activeBuffer: IBuffer;\n\n private readonly _onRequestBell = this._register(new Emitter());\n public readonly onRequestBell = this._onRequestBell.event;\n private readonly _onRequestRefreshRows = this._register(new Emitter<{ start: number, end: number } | undefined>());\n public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;\n private readonly _onRequestReset = this._register(new Emitter());\n public readonly onRequestReset = this._onRequestReset.event;\n private readonly _onRequestSendFocus = this._register(new Emitter());\n public readonly onRequestSendFocus = this._onRequestSendFocus.event;\n private readonly _onRequestSyncScrollBar = this._register(new Emitter());\n public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;\n private readonly _onRequestWindowsOptionsReport = this._register(new Emitter());\n public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;\n\n private readonly _onA11yChar = this._register(new Emitter());\n public readonly onA11yChar = this._onA11yChar.event;\n private readonly _onA11yTab = this._register(new Emitter());\n public readonly onA11yTab = this._onA11yTab.event;\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n private readonly _onScroll = this._register(new Emitter());\n public readonly onScroll = this._onScroll.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onColor = this._register(new Emitter());\n public readonly onColor = this._onColor.event;\n private readonly _onRequestColorSchemeQuery = this._register(new Emitter());\n public readonly onRequestColorSchemeQuery = this._onRequestColorSchemeQuery.event;\n\n private _parseStack: IParseStack = {\n paused: false,\n cursorStartX: 0,\n cursorStartY: 0,\n decodedLength: 0,\n position: 0\n };\n\n constructor(\n private readonly _bufferService: IBufferService,\n private readonly _charsetService: ICharsetService,\n private readonly _coreService: ICoreService,\n private readonly _logService: ILogService,\n private readonly _optionsService: IOptionsService,\n private readonly _oscLinkService: IOscLinkService,\n private readonly _mouseStateService: IMouseStateService,\n private readonly _unicodeService: IUnicodeService,\n private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()\n ) {\n super();\n this._register(this._parser);\n this._dirtyRowTracker = new DirtyRowTracker(this._bufferService);\n\n // Track properties used in performance critical code manually to avoid using slow getters\n this._activeBuffer = this._bufferService.buffer;\n this._register(this._bufferService.buffers.onBufferActivate(e => this._activeBuffer = e.activeBuffer));\n\n /**\n * custom fallback handlers\n */\n this._parser.setCsiHandlerFallback((ident, params) => {\n this._logService.debug('Unknown CSI code: ', { identifier: this._parser.identToString(ident), params: params.toArray() });\n });\n this._parser.setEscHandlerFallback(ident => {\n this._logService.debug('Unknown ESC code: ', { identifier: this._parser.identToString(ident) });\n });\n this._parser.setExecuteHandlerFallback(code => {\n this._logService.debug('Unknown EXECUTE code: ', { code });\n });\n this._parser.setOscHandlerFallback((identifier, action, data) => {\n this._logService.debug('Unknown OSC code: ', { identifier, action, data });\n });\n this._parser.setDcsHandlerFallback((ident, action, payload) => {\n if (action === 'HOOK') {\n payload = payload.toArray();\n }\n this._logService.debug('Unknown DCS code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n this._parser.setApcHandlerFallback((ident, action, payload) => {\n this._logService.debug('Unknown APC code: ', { identifier: this._parser.identToString(ident), action, payload });\n });\n\n /**\n * print handler\n */\n this._parser.setPrintHandler((data, start, end) => this.print(data, start, end));\n\n /**\n * CSI handler\n */\n this._parser.registerCsiHandler({ final: '@' }, params => this.insertChars(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: '@' }, params => this.scrollLeft(params));\n this._parser.registerCsiHandler({ final: 'A' }, params => this.cursorUp(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'A' }, params => this.scrollRight(params));\n this._parser.registerCsiHandler({ final: 'B' }, params => this.cursorDown(params));\n this._parser.registerCsiHandler({ final: 'C' }, params => this.cursorForward(params));\n this._parser.registerCsiHandler({ final: 'D' }, params => this.cursorBackward(params));\n this._parser.registerCsiHandler({ final: 'E' }, params => this.cursorNextLine(params));\n this._parser.registerCsiHandler({ final: 'F' }, params => this.cursorPrecedingLine(params));\n this._parser.registerCsiHandler({ final: 'G' }, params => this.cursorCharAbsolute(params));\n this._parser.registerCsiHandler({ final: 'H' }, params => this.cursorPosition(params));\n this._parser.registerCsiHandler({ final: 'I' }, params => this.cursorForwardTab(params));\n this._parser.registerCsiHandler({ final: 'J' }, params => this.eraseInDisplay(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'J' }, params => this.eraseInDisplay(params, true));\n this._parser.registerCsiHandler({ final: 'K' }, params => this.eraseInLine(params, false));\n this._parser.registerCsiHandler({ prefix: '?', final: 'K' }, params => this.eraseInLine(params, true));\n this._parser.registerCsiHandler({ final: 'L' }, params => this.insertLines(params));\n this._parser.registerCsiHandler({ final: 'M' }, params => this.deleteLines(params));\n this._parser.registerCsiHandler({ final: 'P' }, params => this.deleteChars(params));\n this._parser.registerCsiHandler({ final: 'S' }, params => this.scrollUp(params));\n this._parser.registerCsiHandler({ final: 'T' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: 'X' }, params => this.eraseChars(params));\n this._parser.registerCsiHandler({ final: 'Z' }, params => this.cursorBackwardTab(params));\n this._parser.registerCsiHandler({ final: '^' }, params => this.scrollDown(params));\n this._parser.registerCsiHandler({ final: '`' }, params => this.charPosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'a' }, params => this.hPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'b' }, params => this.repeatPrecedingCharacter(params));\n this._parser.registerCsiHandler({ final: 'c' }, params => this.sendDeviceAttributesPrimary(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'c' }, params => this.sendDeviceAttributesSecondary(params));\n this._parser.registerCsiHandler({ final: 'd' }, params => this.linePosAbsolute(params));\n this._parser.registerCsiHandler({ final: 'e' }, params => this.vPositionRelative(params));\n this._parser.registerCsiHandler({ final: 'f' }, params => this.hVPosition(params));\n this._parser.registerCsiHandler({ final: 'g' }, params => this.tabClear(params));\n this._parser.registerCsiHandler({ final: 'h' }, params => this.setMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'h' }, params => this.setModePrivate(params));\n this._parser.registerCsiHandler({ final: 'l' }, params => this.resetMode(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'l' }, params => this.resetModePrivate(params));\n this._parser.registerCsiHandler({ final: 'm' }, params => this.charAttributes(params));\n this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));\n this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));\n this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));\n this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));\n this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));\n this._parser.registerCsiHandler({ final: 't' }, params => this.windowOptions(params));\n this._parser.registerCsiHandler({ final: 'u' }, params => this.restoreCursor(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '}' }, params => this.insertColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\\'', final: '~' }, params => this.deleteColumns(params));\n this._parser.registerCsiHandler({ intermediates: '\"', final: 'q' }, params => this.selectProtected(params));\n this._parser.registerCsiHandler({ intermediates: '$', final: 'p' }, params => this.requestMode(params, true));\n this._parser.registerCsiHandler({ prefix: '?', intermediates: '$', final: 'p' }, params => this.requestMode(params, false));\n\n // Kitty keyboard protocol handlers\n this._parser.registerCsiHandler({ prefix: '=', final: 'u' }, params => this.kittyKeyboardSet(params));\n this._parser.registerCsiHandler({ prefix: '?', final: 'u' }, params => this.kittyKeyboardQuery(params));\n this._parser.registerCsiHandler({ prefix: '>', final: 'u' }, params => this.kittyKeyboardPush(params));\n this._parser.registerCsiHandler({ prefix: '<', final: 'u' }, params => this.kittyKeyboardPop(params));\n\n /**\n * execute handler\n */\n this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n this._parser.setExecuteHandler(C0.HT, () => this.tab());\n this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n // FIXME: What do to with missing? Old code just added those to print.\n\n this._parser.setExecuteHandler(C1.IND, () => this.index());\n this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n /**\n * OSC handler\n */\n // 0 - icon name + title\n this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));\n // 1 - icon name\n this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));\n // 2 - title\n this._parser.registerOscHandler(2, new OscHandler(data => this.setTitle(data)));\n // 3 - set property X in the form \"prop=value\"\n // 4 - Change Color Number\n this._parser.registerOscHandler(4, new OscHandler(data => this.setOrReportIndexedColor(data)));\n // 5 - Change Special Color Number\n // 6 - Enable/disable Special Color Number c\n // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n // 8 - create hyperlink (not in xterm spec, see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)\n this._parser.registerOscHandler(8, new OscHandler(data => this.setHyperlink(data)));\n // 10 - Change VT100 text foreground color to Pt.\n this._parser.registerOscHandler(10, new OscHandler(data => this.setOrReportFgColor(data)));\n // 11 - Change VT100 text background color to Pt.\n this._parser.registerOscHandler(11, new OscHandler(data => this.setOrReportBgColor(data)));\n // 12 - Change text cursor color to Pt.\n this._parser.registerOscHandler(12, new OscHandler(data => this.setOrReportCursorColor(data)));\n // 13 - Change mouse foreground color to Pt.\n // 14 - Change mouse background color to Pt.\n // 15 - Change Tektronix foreground color to Pt.\n // 16 - Change Tektronix background color to Pt.\n // 17 - Change highlight background color to Pt.\n // 18 - Change Tektronix cursor color to Pt.\n // 19 - Change highlight foreground color to Pt.\n // 46 - Change Log File to Pt.\n // 50 - Set Font to Pt.\n // 51 - reserved for Emacs shell.\n // 52 - Manipulate Selection Data.\n // 104 ; c - Reset Color Number c.\n this._parser.registerOscHandler(104, new OscHandler(data => this.restoreIndexedColor(data)));\n // 105 ; c - Reset Special Color Number c.\n // 106 ; c; f - Enable/disable Special Color Number c.\n // 110 - Reset VT100 text foreground color.\n this._parser.registerOscHandler(110, new OscHandler(data => this.restoreFgColor(data)));\n // 111 - Reset VT100 text background color.\n this._parser.registerOscHandler(111, new OscHandler(data => this.restoreBgColor(data)));\n // 112 - Reset text cursor color.\n this._parser.registerOscHandler(112, new OscHandler(data => this.restoreCursorColor(data)));\n // 113 - Reset mouse foreground color.\n // 114 - Reset mouse background color.\n // 115 - Reset Tektronix foreground color.\n // 116 - Reset Tektronix background color.\n // 117 - Reset highlight color.\n // 118 - Reset Tektronix cursor color.\n // 119 - Reset highlight foreground color.\n\n /**\n * ESC handlers\n */\n this._parser.registerEscHandler({ final: '7' }, () => this.saveCursor());\n this._parser.registerEscHandler({ final: '8' }, () => this.restoreCursor());\n this._parser.registerEscHandler({ final: 'D' }, () => this.index());\n this._parser.registerEscHandler({ final: 'E' }, () => this.nextLine());\n this._parser.registerEscHandler({ final: 'H' }, () => this.tabSet());\n this._parser.registerEscHandler({ final: 'M' }, () => this.reverseIndex());\n this._parser.registerEscHandler({ final: '=' }, () => this.keypadApplicationMode());\n this._parser.registerEscHandler({ final: '>' }, () => this.keypadNumericMode());\n this._parser.registerEscHandler({ final: 'c' }, () => this.fullReset());\n this._parser.registerEscHandler({ final: 'n' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: 'o' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '|' }, () => this.setgLevel(3));\n this._parser.registerEscHandler({ final: '}' }, () => this.setgLevel(2));\n this._parser.registerEscHandler({ final: '~' }, () => this.setgLevel(1));\n this._parser.registerEscHandler({ intermediates: '%', final: '@' }, () => this.selectDefaultCharset());\n this._parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => this.selectDefaultCharset());\n for (const flag in CHARSETS) {\n this._parser.registerEscHandler({ intermediates: '(', final: flag }, () => this.selectCharset('(' + flag));\n this._parser.registerEscHandler({ intermediates: ')', final: flag }, () => this.selectCharset(')' + flag));\n this._parser.registerEscHandler({ intermediates: '*', final: flag }, () => this.selectCharset('*' + flag));\n this._parser.registerEscHandler({ intermediates: '+', final: flag }, () => this.selectCharset('+' + flag));\n this._parser.registerEscHandler({ intermediates: '-', final: flag }, () => this.selectCharset('-' + flag));\n this._parser.registerEscHandler({ intermediates: '.', final: flag }, () => this.selectCharset('.' + flag));\n this._parser.registerEscHandler({ intermediates: '/', final: flag }, () => this.selectCharset('/' + flag)); // TODO: supported?\n }\n this._parser.registerEscHandler({ intermediates: '#', final: '8' }, () => this.screenAlignmentPattern());\n\n /**\n * error handler\n */\n this._parser.setErrorHandler((state: IParsingState) => {\n this._logService.error('Parsing error: ', state);\n return state;\n });\n\n /**\n * DCS handler\n */\n this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DcsHandler((data, params) => this.requestStatusString(data, params)));\n }\n\n /**\n * Async parse support.\n */\n private _preserveStack(cursorStartX: number, cursorStartY: number, decodedLength: number, position: number): void {\n this._parseStack.paused = true;\n this._parseStack.cursorStartX = cursorStartX;\n this._parseStack.cursorStartY = cursorStartY;\n this._parseStack.decodedLength = decodedLength;\n this._parseStack.position = position;\n }\n\n private _logSlowResolvingAsync(p: Promise): void {\n // log a limited warning about an async handler taking too long\n if (this._logService.logLevel <= LogLevelEnum.WARN) {\n let slowTimeout: ReturnType | undefined;\n const slowPromise = new Promise((_res, rej) => {\n slowTimeout = setTimeout(() => rej('#SLOW_TIMEOUT'), Constants.SLOW_ASYNC_LIMIT);\n });\n Promise.race([p, slowPromise])\n .then(() => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n }, err => {\n if (slowTimeout !== undefined) {\n clearTimeout(slowTimeout);\n }\n if (err !== '#SLOW_TIMEOUT') {\n throw err;\n }\n console.warn(`async parser handler taking longer than ${Constants.SLOW_ASYNC_LIMIT} ms`);\n });\n }\n }\n\n private _getCurrentLinkId(): number {\n return this._curAttrData.extended.urlId;\n }\n\n /**\n * Parse call with async handler support.\n *\n * Whether the stack state got preserved for the next call, is indicated by the return value:\n * - undefined (void):\n * all handlers were sync, no stack save, continue normally with next chunk\n * - Promise\\:\n * execution stopped at async handler, stack saved, continue with same chunk and the promise\n * resolve value as `promiseResult` until the method returns `undefined`\n *\n * Note: This method should only be called by `Terminal.write` to ensure correct execution order\n * and proper continuation of async parser handlers.\n */\n public parse(data: string | Uint8Array, promiseResult?: boolean): void | Promise {\n let result: void | Promise;\n let cursorStartX = this._activeBuffer.x;\n let cursorStartY = this._activeBuffer.y;\n let start = 0;\n const wasPaused = this._parseStack.paused;\n\n if (wasPaused) {\n // assumption: _parseBuffer never mutates between async calls\n if (result = this._parser.parse(this._parseBuffer, this._parseStack.decodedLength, promiseResult)) {\n this._logSlowResolvingAsync(result);\n return result;\n }\n cursorStartX = this._parseStack.cursorStartX;\n cursorStartY = this._parseStack.cursorStartY;\n this._parseStack.paused = false;\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n start = this._parseStack.position + Constants.MAX_PARSEBUFFER_LENGTH;\n }\n }\n\n // Log debug data, the log level gate is to prevent extra work in this hot path\n if (this._logService.logLevel <= LogLevelEnum.DEBUG) {\n this._logService.debug(`parsing data ${typeof data === 'string' ? ` \"${data}\"` : ` \"${Array.prototype.map.call(data, e => String.fromCharCode(e)).join('')}\"`}`);\n }\n if (this._logService.logLevel === LogLevelEnum.TRACE) {\n this._logService.trace(`parsing data (codes)`, typeof data === 'string'\n ? data.split('').map(e => e.charCodeAt(0))\n : data\n );\n }\n\n // resize input buffer if needed\n if (this._parseBuffer.length < data.length) {\n if (this._parseBuffer.length < Constants.MAX_PARSEBUFFER_LENGTH) {\n this._parseBuffer = new Uint32Array(Math.min(data.length, Constants.MAX_PARSEBUFFER_LENGTH));\n }\n }\n\n // Clear the dirty row service so we know which lines changed as a result of parsing\n // Important: do not clear between async calls, otherwise we lost pending update information.\n if (!wasPaused) {\n this._dirtyRowTracker.clearRange();\n }\n\n // process big data in smaller chunks\n if (data.length > Constants.MAX_PARSEBUFFER_LENGTH) {\n for (let i = start; i < data.length; i += Constants.MAX_PARSEBUFFER_LENGTH) {\n const end = i + Constants.MAX_PARSEBUFFER_LENGTH < data.length ? i + Constants.MAX_PARSEBUFFER_LENGTH : data.length;\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data.substring(i, end), this._parseBuffer)\n : this._utf8Decoder.decode(data.subarray(i, end), this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, i);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n } else {\n if (!wasPaused) {\n const len = (typeof data === 'string')\n ? this._stringDecoder.decode(data, this._parseBuffer)\n : this._utf8Decoder.decode(data, this._parseBuffer);\n if (result = this._parser.parse(this._parseBuffer, len)) {\n this._preserveStack(cursorStartX, cursorStartY, len, 0);\n this._logSlowResolvingAsync(result);\n return result;\n }\n }\n }\n\n if (this._activeBuffer.x !== cursorStartX || this._activeBuffer.y !== cursorStartY) {\n this._onCursorMove.fire();\n }\n\n // Refresh any dirty rows accumulated as part of parsing, fire only for rows within the\n // _viewport_ which is relative to ydisp, not relative to ybase.\n const viewportEnd = this._dirtyRowTracker.end + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n const viewportStart = this._dirtyRowTracker.start + (this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n if (viewportStart < this._bufferService.rows) {\n this._onRequestRefreshRows.fire({\n start: Math.min(viewportStart, this._bufferService.rows - 1),\n end: Math.min(viewportEnd, this._bufferService.rows - 1)\n });\n }\n }\n\n public print(data: Uint32Array, start: number, end: number): void {\n let code: number;\n let chWidth: number;\n const charset = this._charsetService.charset;\n const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;\n const cols = this._bufferService.cols;\n const wraparoundMode = this._coreService.decPrivateModes.wraparound;\n const insertMode = this._coreService.modes.insertMode;\n const curAttr = this._curAttrData;\n let bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n\n // Defensive check: bufferRow can be undefined if a resize occurred mid-write due to async\n // scheduling gaps in WriteBuffer. See https://github.com/xtermjs/xterm.js/issues/5597\n if (!bufferRow) {\n return;\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char\n if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr);\n }\n\n let precedingJoinState = this._parser.precedingJoinState;\n for (let pos = start; pos < end; ++pos) {\n code = data[pos];\n\n // Soft hyphen's (U+00AD) behavior is ambiguous and differs across terminals. We opt to treat\n // it as a zero-width hint to text layout engines and simply ignore it.\n if (code === 0xAD) {\n continue;\n }\n\n // get charset replacement character\n // charset is only defined for ASCII, therefore we only\n // search for an replacement char if code < 127\n if (code < 127 && charset) {\n const ch = charset[String.fromCharCode(code)];\n if (ch) {\n code = ch.charCodeAt(0);\n }\n }\n\n const currentInfo = this._unicodeService.charProperties(code, precedingJoinState);\n chWidth = UnicodeService.extractWidth(currentInfo);\n const shouldJoin = UnicodeService.extractShouldJoin(currentInfo);\n const oldWidth = shouldJoin ? UnicodeService.extractWidth(precedingJoinState) : 0;\n precedingJoinState = currentInfo;\n\n if (screenReaderMode) {\n this._onA11yChar.fire(stringFromCodePoint(code));\n }\n const linkId = this._getCurrentLinkId();\n if (linkId) {\n this._oscLinkService.addLineToLink(linkId, this._activeBuffer.ybase + this._activeBuffer.y);\n }\n\n // goto next line if ch would overflow\n // NOTE: To avoid costly width checks here,\n // the terminal does not allow a cols < 2.\n if (this._activeBuffer.x + chWidth - oldWidth > cols) {\n // autowrap - DECAWM\n // automatically wraps to the beginning of the next line\n if (wraparoundMode) {\n const oldRow = bufferRow;\n let oldCol = this._activeBuffer.x - oldWidth;\n this._activeBuffer.x = oldWidth;\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData(), true);\n } else {\n if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = true;\n }\n // row changed, get it again\n bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (!bufferRow) {\n return;\n }\n if (oldWidth > 0 && bufferRow instanceof BufferLine) {\n // Combining character widens 1 column to 2.\n // Move old character to next line.\n bufferRow.copyCellsFrom(oldRow as BufferLine,\n oldCol, 0, oldWidth, false);\n }\n // clear left over cells to the right\n while (oldCol < cols) {\n oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr);\n }\n } else {\n this._activeBuffer.x = cols - 1;\n if (chWidth === 2) {\n // FIXME: check for xterm behavior\n // What to do here? We got a wide char that does not fit into last cell\n continue;\n }\n }\n }\n\n // insert combining char at last cursor position\n // this._activeBuffer.x should never be 0 for a combining char\n // since they always follow a cell consuming char\n // therefore we can test for this._activeBuffer.x to avoid overflow left\n if (shouldJoin && this._activeBuffer.x) {\n const offset = bufferRow.getWidth(this._activeBuffer.x - 1) ? 1 : 2;\n // if empty cell after fullwidth, need to go 2 cells back\n // it is save to step 2 cells back here\n // since an empty cell is only set by fullwidth chars\n bufferRow.addCodepointToCell(this._activeBuffer.x - offset,\n code, chWidth);\n for (let delta = chWidth - oldWidth; --delta >= 0;) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n continue;\n }\n\n // insert mode: move characters to right\n if (insertMode) {\n // right shift cells according to the width\n bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr));\n // test last cell - since the last cell has only room for\n // a halfwidth char any fullwidth shifted there is lost\n // and will be set to empty cell\n if (bufferRow.getWidth(cols - 1) === 2) {\n bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr);\n }\n }\n\n // write current char to buffer and advance cursor\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr);\n\n // fullwidth char - also set next cell to placeholder stub and advance cursor\n // for graphemes bigger than fullwidth we can simply loop to zero\n // we already made sure above, that this._activeBuffer.x + chWidth will not overflow right\n if (chWidth > 0) {\n while (--chWidth) {\n // other than a regular empty cell a cell following a wide char has no width\n bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr);\n }\n }\n }\n\n this._parser.precedingJoinState = precedingJoinState;\n\n // handle wide chars: reset cell to the right if it is second cell of a wide char\n if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) {\n bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr);\n }\n\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Forward registerCsiHandler from parser.\n */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n if (id.final === 't' && !id.prefix && !id.intermediates) {\n // security: always check whether window option is allowed\n return this._parser.registerCsiHandler(id, params => {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n return callback(params);\n });\n }\n return this._parser.registerCsiHandler(id, callback);\n }\n\n /**\n * Forward registerDcsHandler from parser.\n */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._parser.registerDcsHandler(id, new DcsHandler(callback));\n }\n\n /**\n * Forward registerEscHandler from parser.\n */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._parser.registerEscHandler(id, callback);\n }\n\n /**\n * Forward registerOscHandler from parser.\n */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerOscHandler(ident, new OscHandler(callback));\n }\n\n /**\n * Forward registerApcHandler from parser.\n */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._parser.registerApcHandler(id, new ApcHandler(callback));\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n *\n * @vt: #Y C0 BEL \"Bell\" \"\\a, \\x07\" \"Ring the bell.\"\n * The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`\n * and `ITerminalOptions.bellSound`.\n */\n public bell(): boolean {\n this._onRequestBell.fire();\n return true;\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n *\n * @vt: #Y C0 LF \"Line Feed\" \"\\n, \\x0A\" \"Move the cursor one row down, scrolling if needed.\"\n * Scrolling is restricted to scroll margins and will only happen on the bottom line.\n *\n * @vt: #Y C0 VT \"Vertical Tabulation\" \"\\v, \\x0B\" \"Treated as LF.\"\n * @vt: #Y C0 FF \"Form Feed\" \"\\f, \\x0C\" \"Treated as LF.\"\n */\n public lineFeed(): boolean {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._optionsService.rawOptions.convertEol) {\n this._activeBuffer.x = 0;\n }\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n } else {\n // There was an explicit line feed (not just a carriage return), so clear the wrapped state of\n // the line. This is particularly important on conpty/Windows where revisiting lines to\n // reprint is common, especially on resize. Note that the windowsMode wrapped line heuristics\n // can mess with this so windowsMode should be disabled, which is recommended on Windows build\n // 21376 and above.\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._activeBuffer.x >= this._bufferService.cols) {\n this._activeBuffer.x--;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n\n this._onLineFeed.fire();\n return true;\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n *\n * @vt: #Y C0 CR \"Carriage Return\" \"\\r, \\x0D\" \"Move the cursor to the beginning of the row.\"\n */\n public carriageReturn(): boolean {\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n *\n * @vt: #Y C0 BS \"Backspace\" \"\\b, \\x08\" \"Move the cursor one position to the left.\"\n * By default it is not possible to move the cursor past the leftmost position.\n * If `reverse wrap-around` (`CSI ? 45 h`) is set, a previous soft line wrap (DECAWM)\n * can be undone with BS within the scroll margins. In that case the cursor will wrap back\n * to the end of the previous row. Note that it is not possible to peek back into the scrollbuffer\n * with the cursor, thus at the home position (top-leftmost cell) this has no effect.\n */\n public backspace(): boolean {\n // reverse wrap-around is disabled\n if (!this._coreService.decPrivateModes.reverseWraparound) {\n this._restrictCursor();\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n }\n return true;\n }\n\n // reverse wrap-around is enabled\n // other than for normal operation mode, reverse wrap-around allows the cursor\n // to be at x=cols to be able to address the last cell of a row by BS\n this._restrictCursor(this._bufferService.cols);\n\n if (this._activeBuffer.x > 0) {\n this._activeBuffer.x--;\n } else {\n /**\n * reverse wrap-around handling:\n * Our implementation deviates from xterm on purpose. Details:\n * - only previous soft NLs can be reversed (isWrapped=true)\n * - only works within scrollborders (top/bottom, left/right not yet supported)\n * - cannot peek into scrollbuffer\n * - any cursor movement sequence keeps working as expected\n */\n if (this._activeBuffer.x === 0\n && this._activeBuffer.y > this._activeBuffer.scrollTop\n && this._activeBuffer.y <= this._activeBuffer.scrollBottom\n && this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {\n this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;\n this._activeBuffer.y--;\n this._activeBuffer.x = this._bufferService.cols - 1;\n // find last taken cell - last cell can have 3 different states:\n // - hasContent(true) + hasWidth(1): narrow char - we are done\n // - hasWidth(0): second part of wide char - we are done\n // - hasContent(false) + hasWidth(1): empty cell due to early wrapping wide char, go one\n // cell further back\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n if (line.hasWidth(this._activeBuffer.x) && !line.hasContent(this._activeBuffer.x)) {\n this._activeBuffer.x--;\n // We do this only once, since width=1 + hasContent=false currently happens only once\n // before early wrapping of a wide char.\n // This needs to be fixed once we support graphemes taking more than 2 cells.\n }\n }\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n *\n * @vt: #Y C0 HT \"Horizontal Tabulation\" \"\\t, \\x09\" \"Move the cursor to the next character tab stop.\"\n */\n public tab(): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n const originalX = this._activeBuffer.x;\n this._activeBuffer.x = this._activeBuffer.nextStop();\n if (this._optionsService.rawOptions.screenReaderMode) {\n this._onA11yTab.fire(this._activeBuffer.x - originalX);\n }\n return true;\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n *\n * @vt: #P[Only limited ISO-2022 charset support.] C0 SO \"Shift Out\" \"\\x0E\" \"Switch to an alternative character set.\"\n */\n public shiftOut(): boolean {\n this._charsetService.setgLevel(1);\n return true;\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n *\n * @vt: #Y C0 SI \"Shift In\" \"\\x0F\" \"Return to regular character set after Shift Out.\"\n */\n public shiftIn(): boolean {\n this._charsetService.setgLevel(0);\n return true;\n }\n\n /**\n * Restrict cursor to viewport size / scroll margin (origin mode).\n */\n private _restrictCursor(maxCol: number = this._bufferService.cols - 1): void {\n this._activeBuffer.x = Math.min(maxCol, Math.max(0, this._activeBuffer.x));\n this._activeBuffer.y = this._coreService.decPrivateModes.origin\n ? Math.min(this._activeBuffer.scrollBottom, Math.max(this._activeBuffer.scrollTop, this._activeBuffer.y))\n : Math.min(this._bufferService.rows - 1, Math.max(0, this._activeBuffer.y));\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set absolute cursor position.\n */\n private _setCursor(x: number, y: number): void {\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n if (this._coreService.decPrivateModes.origin) {\n this._activeBuffer.x = x;\n this._activeBuffer.y = this._activeBuffer.scrollTop + y;\n } else {\n this._activeBuffer.x = x;\n this._activeBuffer.y = y;\n }\n this._restrictCursor();\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n\n /**\n * Set relative cursor position.\n */\n private _moveCursor(x: number, y: number): void {\n // for relative changes we have to make sure we are within 0 .. cols/rows - 1\n // before calculating the new position\n this._restrictCursor();\n this._setCursor(this._activeBuffer.x + x, this._activeBuffer.y + y);\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n *\n * @vt: #Y CSI CUU \"Cursor Up\" \"CSI Ps A\" \"Move cursor `Ps` times up (default=1).\"\n * If the cursor would pass the top scroll margin, it will stop there.\n */\n public cursorUp(params: IParams): boolean {\n // stop at scrollTop\n const diffToTop = this._activeBuffer.y - this._activeBuffer.scrollTop;\n if (diffToTop >= 0) {\n this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));\n } else {\n this._moveCursor(0, -(params.params[0] || 1));\n }\n return true;\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n *\n * @vt: #Y CSI CUD \"Cursor Down\" \"CSI Ps B\" \"Move cursor `Ps` times down (default=1).\"\n * If the cursor would pass the bottom scroll margin, it will stop there.\n */\n public cursorDown(params: IParams): boolean {\n // stop at scrollBottom\n const diffToBottom = this._activeBuffer.scrollBottom - this._activeBuffer.y;\n if (diffToBottom >= 0) {\n this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));\n } else {\n this._moveCursor(0, params.params[0] || 1);\n }\n return true;\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n *\n * @vt: #Y CSI CUF \"Cursor Forward\" \"CSI Ps C\" \"Move cursor `Ps` times forward (default=1).\"\n */\n public cursorForward(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n *\n * @vt: #Y CSI CUB \"Cursor Backward\" \"CSI Ps D\" \"Move cursor `Ps` times backward (default=1).\"\n */\n public cursorBackward(params: IParams): boolean {\n this._moveCursor(-(params.params[0] || 1), 0);\n return true;\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * Other than cursorDown (CUD) also set the cursor to first column.\n *\n * @vt: #Y CSI CNL \"Cursor Next Line\" \"CSI Ps E\" \"Move cursor `Ps` times down (default=1) and to the first column.\"\n * Same as CUD, additionally places the cursor at the first column.\n */\n public cursorNextLine(params: IParams): boolean {\n this.cursorDown(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps F\n * Cursor Previous Line Ps Times (default = 1) (CPL).\n * Other than cursorUp (CUU) also set the cursor to first column.\n *\n * @vt: #Y CSI CPL \"Cursor Backward\" \"CSI Ps F\" \"Move cursor `Ps` times up (default=1) and to the first column.\"\n * Same as CUU, additionally places the cursor at the first column.\n */\n public cursorPrecedingLine(params: IParams): boolean {\n this.cursorUp(params);\n this._activeBuffer.x = 0;\n return true;\n }\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n *\n * @vt: #Y CSI CHA \"Cursor Horizontal Absolute\" \"CSI Ps G\" \"Move cursor to `Ps`-th column of the active row (default=1).\"\n */\n public cursorCharAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n *\n * @vt: #Y CSI CUP \"Cursor Position\" \"CSI Ps ; Ps H\" \"Set cursor to position [`Ps`, `Ps`] (default = [1, 1]).\"\n * If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.\n * If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.\n * Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.\n */\n public cursorPosition(params: IParams): boolean {\n this._setCursor(\n // col\n (params.length >= 2) ? (params.params[1] || 1) - 1 : 0,\n // row\n (params.params[0] || 1) - 1\n );\n return true;\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n * Currently same functionality as CHA.\n *\n * @vt: #Y CSI HPA \"Horizontal Position Absolute\" \"CSI Ps ` \" \"Same as CHA.\"\n */\n public charPosAbsolute(params: IParams): boolean {\n this._setCursor((params.params[0] || 1) - 1, this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n *\n * @vt: #Y CSI HPR \"Horizontal Position Relative\" \"CSI Ps a\" \"Same as CUF.\"\n */\n public hPositionRelative(params: IParams): boolean {\n this._moveCursor(params.params[0] || 1, 0);\n return true;\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n *\n * @vt: #Y CSI VPA \"Vertical Position Absolute\" \"CSI Ps d\" \"Move cursor to `Ps`-th row (default=1).\"\n */\n public linePosAbsolute(params: IParams): boolean {\n this._setCursor(this._activeBuffer.x, (params.params[0] || 1) - 1);\n return true;\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n *\n * @vt: #Y CSI VPR \"Vertical Position Relative\" \"CSI Ps e\" \"Move cursor `Ps` times down (default=1).\"\n */\n public vPositionRelative(params: IParams): boolean {\n this._moveCursor(0, params.params[0] || 1);\n return true;\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n * Same as CUP.\n *\n * @vt: #Y CSI HVP \"Horizontal and Vertical Position\" \"CSI Ps ; Ps f\" \"Same as CUP.\"\n */\n public hVPosition(params: IParams): boolean {\n this.cursorPosition(params);\n return true;\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n *\n * @vt: #Y CSI TBC \"Tab Clear\" \"CSI Ps g\" \"Clear tab stops at current position (0) or all (3) (default=0).\"\n * Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.\n */\n public tabClear(params: IParams): boolean {\n const param = params.params[0];\n if (param === 0) {\n delete this._activeBuffer.tabs[this._activeBuffer.x];\n } else if (param === 3) {\n this._activeBuffer.tabs = {};\n }\n return true;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n *\n * @vt: #Y CSI CHT \"Cursor Horizontal Tabulation\" \"CSI Ps I\" \"Move cursor `Ps` times tabs forward (default=1).\"\n */\n public cursorForwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.nextStop();\n }\n return true;\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n *\n * @vt: #Y CSI CBT \"Cursor Backward Tabulation\" \"CSI Ps Z\" \"Move cursor `Ps` tabs backward (default=1).\"\n */\n public cursorBackwardTab(params: IParams): boolean {\n if (this._activeBuffer.x >= this._bufferService.cols) {\n return true;\n }\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.x = this._activeBuffer.prevStop();\n }\n return true;\n }\n\n /**\n * CSI Ps \" q Select Character Protection Attribute (DECSCA).\n *\n * @vt: #Y CSI DECSCA \"Select Character Protection Attribute\" \"CSI Ps \" q\" \"Whether DECSED and DECSEL can erase (0=default, 2) or not (1).\"\n */\n public selectProtected(params: IParams): boolean {\n const p = params.params[0];\n if (p === 1) this._curAttrData.bg |= BgFlags.PROTECTED;\n if (p === 2 || p === 0) this._curAttrData.bg &= ~BgFlags.PROTECTED;\n return true;\n }\n\n\n /**\n * Helper method to erase cells in a terminal row.\n * The cell gets replaced with the eraseChar of the terminal.\n * @param y The row index relative to the viewport.\n * @param start The start x index of the range to be erased.\n * @param end The end x index of the range to be erased (exclusive).\n * @param clearWrap clear the isWrapped flag\n * @param respectProtect Whether to respect the protection attribute (DECSCA).\n */\n private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (!line) {\n return;\n }\n line.replaceCells(\n start,\n end,\n this._activeBuffer.getNullCell(this._eraseAttrData()),\n respectProtect\n );\n if (clearWrap) {\n line.isWrapped = false;\n }\n }\n\n /**\n * Helper method to reset cells in a terminal row. The cell gets replaced with the eraseChar of\n * the terminal and the isWrapped property is set to false.\n * @param y row index\n */\n private _resetBufferLine(y: number, respectProtect: boolean = false): void {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y);\n if (line) {\n line.fill(this._activeBuffer.getNullCell(this._eraseAttrData()), respectProtect);\n this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase + y);\n line.isWrapped = false;\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI ED \"Erase In Display\" \"CSI Ps J\" \"Erase various parts of the viewport.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | ------------------------------------------------------------ |\n * | 0 | Erase from the cursor through the end of the viewport. |\n * | 1 | Erase from the beginning of the viewport through the cursor. |\n * | 2 | Erase complete viewport. |\n * | 3 | Erase scrollback. |\n *\n * @vt: #Y CSI DECSED \"Selective Erase In Display\" \"CSI ? Ps J\" \"Same as ED with respecting protection flag.\"\n */\n public eraseInDisplay(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n let j;\n switch (params.params[0]) {\n case 0:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n this._eraseInBufferLine(j++, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n for (; j < this._bufferService.rows; j++) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(j);\n break;\n case 1:\n j = this._activeBuffer.y;\n this._dirtyRowTracker.markDirty(j);\n // Deleted front part of line and everything before. This line will no longer be wrapped.\n this._eraseInBufferLine(j, 0, this._activeBuffer.x + 1, true, respectProtect);\n if (this._activeBuffer.x + 1 >= this._bufferService.cols) {\n // Deleted entire previous line. This next line can no longer be wrapped.\n const nextLine = this._activeBuffer.lines.get(j + 1);\n if (nextLine) {\n nextLine.isWrapped = false;\n }\n }\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n break;\n case 2:\n if (this._optionsService.rawOptions.scrollOnEraseInDisplay) {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markRangeDirty(0, j - 1);\n while (j--) {\n const currentLine = this._activeBuffer.lines.get(this._activeBuffer.ybase + j);\n if (currentLine?.getTrimmedLength()) {\n break;\n }\n }\n for (; j >= 0; j--) {\n this._bufferService.scroll(this._eraseAttrData());\n }\n }\n else {\n j = this._bufferService.rows;\n this._dirtyRowTracker.markDirty(j - 1);\n while (j--) {\n this._resetBufferLine(j, respectProtect);\n }\n this._dirtyRowTracker.markDirty(0);\n }\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._activeBuffer.lines.length - this._bufferService.rows;\n if (scrollBackSize > 0) {\n this._activeBuffer.lines.trimStart(scrollBackSize);\n this._activeBuffer.ybase = Math.max(this._activeBuffer.ybase - scrollBackSize, 0);\n this._activeBuffer.ydisp = Math.max(this._activeBuffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._onScroll.fire(0);\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n *\n * @vt: #Y CSI EL \"Erase In Line\" \"CSI Ps K\" \"Erase various parts of the active row.\"\n * Supported param values:\n *\n * | Ps | Effect |\n * | -- | -------------------------------------------------------- |\n * | 0 | Erase from the cursor through the end of the row. |\n * | 1 | Erase from the beginning of the line through the cursor. |\n * | 2 | Erase complete line. |\n *\n * @vt: #Y CSI DECSEL \"Selective Erase In Line\" \"CSI ? Ps K\" \"Same as EL with respecting protecting flag.\"\n */\n public eraseInLine(params: IParams, respectProtect: boolean = false): boolean {\n this._restrictCursor(this._bufferService.cols);\n switch (params.params[0]) {\n case 0:\n this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0, respectProtect);\n break;\n case 1:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false, respectProtect);\n break;\n case 2:\n this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true, respectProtect);\n break;\n }\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n return true;\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n *\n * @vt: #Y CSI IL \"Insert Line\" \"CSI Ps L\" \"Insert `Ps` blank lines at active row (default=1).\"\n * For every inserted line at the scroll top one line at the scroll bottom gets removed.\n * The cursor is set to the first column.\n * IL has no effect if the cursor is outside the scroll margins.\n */\n public insertLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n const scrollBottomRowsOffset = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n const scrollBottomAbsolute = this._bufferService.rows - 1 + this._activeBuffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._activeBuffer.lines.splice(row, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n *\n * @vt: #Y CSI DL \"Delete Line\" \"CSI Ps M\" \"Delete `Ps` lines at active row (default=1).\"\n * For every deleted line at the scroll top one blank line at the scroll bottom gets appended.\n * The cursor is set to the first column.\n * DL has no effect if the cursor is outside the scroll margins.\n */\n public deleteLines(params: IParams): boolean {\n this._restrictCursor();\n let param = params.params[0] || 1;\n\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n\n const row: number = this._activeBuffer.ybase + this._activeBuffer.y;\n\n let j: number;\n j = this._bufferService.rows - 1 - this._activeBuffer.scrollBottom;\n j = this._bufferService.rows - 1 + this._activeBuffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._activeBuffer.lines.splice(row, 1);\n this._activeBuffer.lines.splice(j, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.y, this._activeBuffer.scrollBottom);\n this._activeBuffer.x = 0; // see https://vt100.net/docs/vt220-rm/chapter4.html - vt220 only?\n return true;\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n *\n * @vt: #Y CSI ICH \"Insert Characters\" \"CSI Ps @\" \"Insert `Ps` (blank) characters (default = 1).\"\n * The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the\n * blank characters. Text between the cursor and right margin moves to the right. Characters moved\n * past the right margin are lost.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public insertChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.insertCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n *\n * @vt: #Y CSI DCH \"Delete Character\" \"CSI Ps P\" \"Delete `Ps` characters (default=1).\"\n * As characters are deleted, the remaining characters between the cursor and right margin move to\n * the left. Character attributes move with the characters. The terminal adds blank characters at\n * the right margin.\n *\n *\n * FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)\n */\n public deleteChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.deleteCells(\n this._activeBuffer.x,\n params.params[0] || 1,\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n *\n * @vt: #Y CSI SU \"Scroll Up\" \"CSI Ps S\" \"Scroll `Ps` lines up (default=1).\"\n *\n *\n * FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)\n */\n public scrollUp(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 0, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n *\n * @vt: #Y CSI SD \"Scroll Down\" \"CSI Ps T\" \"Scroll `Ps` lines down (default=1).\"\n */\n public scrollDown(params: IParams): boolean {\n let param = params.params[0] || 1;\n\n while (param--) {\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollBottom, 1);\n this._activeBuffer.lines.splice(this._activeBuffer.ybase + this._activeBuffer.scrollTop, 0, this._activeBuffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP @ Scroll left Ps columns (default = 1) (SL) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/00\n * Parameter default value: Pn = 1\n * SL causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the left; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always left shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SL \"Scroll Left\" \"CSI Ps SP @\" \"Scroll viewport `Ps` times to the left.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the left.\n * SL has no effect outside of the scroll margins.\n */\n public scrollLeft(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps SP A Scroll right Ps columns (default = 1) (SR) ECMA-48\n *\n * Notation: (Pn)\n * Representation: CSI Pn 02/00 04/01\n * Parameter default value: Pn = 1\n * SR causes the data in the presentation component to be moved by n character positions\n * if the line orientation is horizontal, or by n line positions if the line orientation\n * is vertical, such that the data appear to move to the right; where n equals the value of Pn.\n * The active presentation position is not affected by this control function.\n *\n * Supported:\n * - always right shift (no line orientation setting respected)\n *\n * @vt: #Y CSI SR \"Scroll Right\" \"CSI Ps SP A\" \"Scroll viewport `Ps` times to the right.\"\n * SL moves the content of all lines within the scroll margins `Ps` times to the right.\n * Content at the right margin is lost.\n * SL has no effect outside of the scroll margins.\n */\n public scrollRight(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' }\n * Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.\n *\n * @vt: #Y CSI DECIC \"Insert Columns\" \"CSI Ps ' }\" \"Insert `Ps` columns at cursor position.\"\n * DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll\n * margins, moving content to the right. Content at the right margin is lost. DECIC has no effect\n * outside the scrolling margins.\n */\n public insertColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Pm ' ~\n * Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.\n *\n * @vt: #Y CSI DECDC \"Delete Columns\" \"CSI Ps ' ~\" \"Delete `Ps` columns at cursor position.\"\n * DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,\n * moving content to the left. Blank columns are added at the right margin.\n * DECDC has no effect outside the scrolling margins.\n */\n public deleteColumns(params: IParams): boolean {\n if (this._activeBuffer.y > this._activeBuffer.scrollBottom || this._activeBuffer.y < this._activeBuffer.scrollTop) {\n return true;\n }\n const param = params.params[0] || 1;\n for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) {\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;\n line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()));\n line.isWrapped = false;\n }\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n return true;\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n *\n * @vt: #Y CSI ECH \"Erase Character\" \"CSI Ps X\" \"Erase `Ps` characters from current cursor position to the right (default=1).\"\n * ED erases `Ps` characters from current cursor position to the right.\n * ED works inside or outside the scrolling margins.\n */\n public eraseChars(params: IParams): boolean {\n this._restrictCursor();\n const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y);\n if (line) {\n line.replaceCells(\n this._activeBuffer.x,\n this._activeBuffer.x + (params.params[0] || 1),\n this._activeBuffer.getNullCell(this._eraseAttrData())\n );\n this._dirtyRowTracker.markDirty(this._activeBuffer.y);\n }\n return true;\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n * From ECMA 48 (@see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf)\n * Notation: (Pn)\n * Representation: CSI Pn 06/02\n * Parameter default value: Pn = 1\n * REP is used to indicate that the preceding character in the data stream,\n * if it is a graphic character (represented by one or more bit combinations) including SPACE,\n * is to be repeated n times, where n equals the value of Pn.\n * If the character preceding REP is a control function or part of a control function,\n * the effect of REP is not defined by this Standard.\n *\n * We extend xterm's behavior to allow repeating entire grapheme clusters.\n * This isn't 100% xterm-compatible, but it seems saner and more useful.\n * - text attrs are applied normally\n * - wrap around is respected\n * - any valid sequence resets the carried forward char\n *\n * Note: To get reset on a valid sequence working correctly without much runtime penalty, the\n * preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.\n *\n * @vt: #Y CSI REP \"Repeat Preceding Character\" \"CSI Ps b\" \"Repeat preceding character `Ps` times (default=1).\"\n * REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is\n * set. REP has no effect if the sequence does not follow a printable ASCII character\n * (NOOP for any other sequence in between or NON ASCII characters).\n */\n public repeatPrecedingCharacter(params: IParams): boolean {\n const joinState = this._parser.precedingJoinState;\n if (!joinState) {\n return true;\n }\n // call print to insert the chars and handle correct wrapping\n const length = params.params[0] || 1;\n const chWidth = UnicodeService.extractWidth(joinState);\n const x = this._activeBuffer.x - chWidth;\n const bufferRow = this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!;\n const text = bufferRow.getString(x);\n const data = new Uint32Array(text.length * length);\n let idata = 0;\n for (let itext = 0; itext < text.length;) {\n const ch = text.codePointAt(itext) || 0;\n data[idata++] = ch;\n itext += ch > 0xffff ? 2 : 1;\n }\n let tlength = idata;\n for (let i = 1; i < length; ++i) {\n data.copyWithin(tlength, 0, idata);\n tlength += idata;\n }\n this.print(data, 0, tlength);\n return true;\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n *\n * @vt: #Y CSI DA1 \"Primary Device Attributes\" \"CSI c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesPrimary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');\n } else if (this._is('linux')) {\n this._coreService.triggerDataEvent(C0.ESC + '[?6c');\n }\n return true;\n }\n\n /**\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n *\n * @vt: #Y CSI DA2 \"Secondary Device Attributes\" \"CSI > c\" \"Send primary device attributes.\"\n *\n *\n * TODO: fix and cleanup response\n */\n public sendDeviceAttributesSecondary(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._is('xterm')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');\n } else if (this._is('rxvt-unicode')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');\n } else if (this._is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._coreService.triggerDataEvent(params.params[0] + 'c');\n } else if (this._is('screen')) {\n this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');\n }\n return true;\n }\n\n /**\n * CSI > Ps q\n * Ps = 0 => Report xterm name and version (XTVERSION).\n *\n * The response is a DCS sequence identifying the version: DCS > | text ST\n *\n * @vt: #Y CSI XTVERSION \"Report Xterm Version\" \"CSI > q\" \"Report the terminal name and version.\"\n */\n public sendXtVersion(params: IParams): boolean {\n if (params.params[0] > 0) {\n return true;\n }\n this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\\\`);\n return true;\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n private _is(term: string): boolean {\n return (this._optionsService.rawOptions.termName + '').startsWith(term);\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI SM \"Set Mode\" \"CSI Pm h\" \"Set various terminal modes.\"\n * Supported param values by SM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Insert Mode (IRM). | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Automatic Newline (LNM). | #Y |\n */\n public setMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = true;\n break;\n case 20:\n this._optionsService.options.convertEol = true;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n *\n * @vt: #P[See below for supported modes.] CSI DECSET \"DEC Private Set Mode\" \"CSI ? Pm h\" \"Set various terminal attributes.\"\n * Supported param values by DECSET:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | --------|\n * | 1 | Application Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |\n * | 3 | 132 Column Mode (DECCOLM). | #Y |\n * | 6 | Origin Mode (DECOM). | #Y |\n * | 7 | Auto-wrap Mode (DECAWM). | #Y |\n * | 8 | Auto-repeat Keys (DECARM). Always on. | #N |\n * | 9 | X10 xterm mouse protocol. | #Y |\n * | 12 | Start Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Show Cursor (DECTCEM). | #Y |\n * | 45 | Reverse wrap-around. | #Y |\n * | 47 | Use Alternate Screen Buffer. | #Y |\n * | 66 | Application keypad (DECNKM). | #Y |\n * | 1000 | X11 xterm mouse protocol. | #Y |\n * | 1002 | Use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Use All Motion Mouse Tracking. | #Y |\n * | 1004 | Send FocusIn/FocusOut events | #Y |\n * | 1005 | Enable UTF-8 Mouse Mode. | #N |\n * | 1006 | Enable SGR Mouse Mode. | #Y |\n * | 1015 | Enable urxvt Mouse Mode. | #N |\n * | 1016 | Enable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Alternate Screen Buffer. | #Y |\n * | 1048 | Save cursor as in DECSC. | #Y |\n * | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |\n * | 2004 | Set bracketed paste mode. | #Y |\n *\n *\n * FIXME: implement DECSCNM, 1049 should clear altbuffer\n */\n public setModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = true;\n break;\n case 2:\n this._charsetService.setgCharset(0, DEFAULT_CHARSET);\n this._charsetService.setgCharset(1, DEFAULT_CHARSET);\n this._charsetService.setgCharset(2, DEFAULT_CHARSET);\n this._charsetService.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3:\n /**\n * DECCOLM - 132 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(132, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = true;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = true;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = true;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = true;\n break;\n case 66:\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n this._mouseStateService.activeProtocol = 'X10';\n break;\n case 1000: // vt200 mouse\n // no motion.\n this._mouseStateService.activeProtocol = 'VT200';\n break;\n case 1002: // button event mouse\n this._mouseStateService.activeProtocol = 'DRAG';\n break;\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n this._mouseStateService.activeProtocol = 'ANY';\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._coreService.decPrivateModes.sendFocus = true;\n this._onRequestSendFocus.fire();\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'SGR';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECSET 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'SGR_PIXELS';\n break;\n case 25: // show cursor\n this._coreService.isCursorHidden = false;\n break;\n case 1048: // alt screen cursor\n this.saveCursor();\n break;\n case 1049: // alt screen buffer cursor\n this.saveCursor();\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n // Swap kitty keyboard flags: save main, restore alt\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.mainFlags = state.flags;\n state.flags = state.altFlags;\n }\n this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = true;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = true;\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = true;\n }\n break;\n case 9001: // win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md)\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = true;\n }\n break;\n }\n }\n return true;\n }\n\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n *\n * @vt: #P[Only IRM is supported.] CSI RM \"Reset Mode\" \"CSI Pm l\" \"Set various terminal attributes.\"\n * Supported param values by RM:\n *\n * | Param | Action | Support |\n * | ----- | -------------------------------------- | ------- |\n * | 2 | Keyboard Action Mode (KAM). Always on. | #N |\n * | 4 | Replace Mode (IRM). (default) | #Y |\n * | 12 | Send/receive (SRM). Always off. | #N |\n * | 20 | Normal Linefeed (LNM). | #Y |\n *\n *\n * FIXME: why is LNM commented out?\n */\n public resetMode(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 4:\n this._coreService.modes.insertMode = false;\n break;\n case 20:\n this._optionsService.options.convertEol = false;\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n *\n * @vt: #P[See below for supported modes.] CSI DECRST \"DEC Private Reset Mode\" \"CSI ? Pm l\" \"Reset various terminal attributes.\"\n * Supported param values by DECRST:\n *\n * | param | Action | Support |\n * | ----- | ------------------------------------------------------- | ------- |\n * | 1 | Normal Cursor Keys (DECCKM). | #Y |\n * | 2 | Designate VT52 mode (DECANM). | #N |\n * | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |\n * | 6 | Normal Cursor Mode (DECOM). | #Y |\n * | 7 | No Wraparound Mode (DECAWM). | #Y |\n * | 8 | No Auto-repeat Keys (DECARM). | #N |\n * | 9 | Don't send Mouse X & Y on button press. | #Y |\n * | 12 | Stop Blinking Cursor. | #P[Requires the allowSetCursorBlink quirk option enabled.] |\n * | 25 | Hide Cursor (DECTCEM). | #Y |\n * | 45 | No reverse wrap-around. | #Y |\n * | 47 | Use Normal Screen Buffer. | #Y |\n * | 66 | Numeric keypad (DECNKM). | #Y |\n * | 1000 | Don't send Mouse reports. | #Y |\n * | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |\n * | 1003 | Don't use All Motion Mouse Tracking. | #Y |\n * | 1004 | Don't send FocusIn/FocusOut events. | #Y |\n * | 1005 | Disable UTF-8 Mouse Mode. | #N |\n * | 1006 | Disable SGR Mouse Mode. | #Y |\n * | 1015 | Disable urxvt Mouse Mode. | #N |\n * | 1016 | Disable SGR-Pixels Mouse Mode. | #Y |\n * | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |\n * | 1048 | Restore cursor as in DECRC. | #Y |\n * | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |\n * | 2004 | Reset bracketed paste mode. | #Y |\n *\n *\n * FIXME: DECCOLM is currently broken (already fixed in window options PR)\n */\n public resetModePrivate(params: IParams): boolean {\n for (let i = 0; i < params.length; i++) {\n switch (params.params[i]) {\n case 1:\n this._coreService.decPrivateModes.applicationCursorKeys = false;\n break;\n case 3:\n /**\n * DECCOLM - 80 column mode.\n * This is only active if 'SetWinLines' (24) is enabled\n * through `options.windowsOptions`.\n */\n if (this._optionsService.rawOptions.windowOptions.setWinLines) {\n this._bufferService.resize(80, this._bufferService.rows);\n this._onRequestReset.fire();\n }\n break;\n case 6:\n this._coreService.decPrivateModes.origin = false;\n this._setCursor(0, 0);\n break;\n case 7:\n this._coreService.decPrivateModes.wraparound = false;\n break;\n case 12:\n if (this._optionsService.rawOptions.quirks?.allowSetCursorBlink) {\n this._optionsService.options.cursorBlink = false;\n }\n break;\n case 45:\n this._coreService.decPrivateModes.reverseWraparound = false;\n break;\n case 66:\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._mouseStateService.activeProtocol = 'NONE';\n break;\n case 1004: // send focusin/focusout events\n this._coreService.decPrivateModes.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1005 not supported (see #2507)');\n break;\n case 1006: // sgr ext mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 1015: // urxvt ext mode mouse - removed in #2507\n this._logService.debug('DECRST 1015 not supported (see #2507)');\n break;\n case 1016: // sgr pixels mode mouse\n this._mouseStateService.activeEncoding = 'DEFAULT';\n break;\n case 25: // hide cursor\n this._coreService.isCursorHidden = true;\n break;\n case 1048: // alt screen cursor\n this.restoreCursor();\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Swap kitty keyboard flags: save alt, restore main\n if (this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n const state = this._coreService.kittyKeyboard;\n state.altFlags = state.flags;\n state.flags = state.mainFlags;\n }\n // Ensure the selection manager has the correct buffer\n this._bufferService.buffers.activateNormalBuffer();\n if (params.params[i] === 1049) {\n this.restoreCursor();\n }\n this._coreService.isCursorInitialized = true;\n this._onRequestRefreshRows.fire(undefined);\n this._onRequestSyncScrollBar.fire();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._coreService.decPrivateModes.bracketedPasteMode = false;\n break;\n case 2026: // synchronized output (https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md)\n this._coreService.decPrivateModes.synchronizedOutput = false;\n this._onRequestRefreshRows.fire(undefined);\n break;\n case 2031: // color scheme updates (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._coreService.decPrivateModes.colorSchemeUpdates = false;\n }\n break;\n case 9001: // win32-input-mode\n if (this._optionsService.rawOptions.vtExtensions?.win32InputMode) {\n this._coreService.decPrivateModes.win32InputMode = false;\n }\n break;\n }\n }\n return true;\n }\n\n /**\n * CSI Ps $ p Request ANSI Mode (DECRQM).\n *\n * Reports CSI Ps; Pm $ y (DECRPM), where Ps is the mode number as in SM/RM,\n * and Pm is the mode value:\n * 0 - not recognized\n * 1 - set\n * 2 - reset\n * 3 - permanently set\n * 4 - permanently reset\n *\n * @vt: #Y CSI DECRQM \"Request Mode\" \"CSI Ps $p\" \"Request mode state.\"\n * Returns a report as `CSI Ps; Pm $ y` (DECRPM), where `Ps` is the mode number as in SM/RM\n * or DECSET/DECRST, and `Pm` is the mode value:\n * - 0: not recognized\n * - 1: set\n * - 2: reset\n * - 3: permanently set\n * - 4: permanently reset\n *\n * For modes not understood xterm.js always returns `notRecognized`. In general this means,\n * that a certain operation mode is not implemented and cannot be used.\n *\n * Modes changing the active terminal buffer (47, 1047, 1049) are not subqueried\n * and only report, whether the alternate buffer is set.\n *\n * Mouse encodings and mouse protocols are handled mutual exclusive,\n * thus only one of each of those can be set at a given time.\n *\n * There is a chance, that some mode reports are not fully in line with xterm.js' behavior,\n * e.g. if the default implementation already exposes a certain behavior. If you find\n * discrepancies in the mode reports, please file a bug.\n */\n public requestMode(params: IParams, ansi: boolean): boolean {\n // return value as in DECRPM\n const enum V {\n NOT_RECOGNIZED = 0,\n SET = 1,\n RESET = 2,\n PERMANENTLY_SET = 3,\n PERMANENTLY_RESET = 4\n }\n\n // access helpers\n const dm = this._coreService.decPrivateModes;\n const { activeProtocol: mouseProtocol, activeEncoding: mouseEncoding } = this._mouseStateService;\n const cs = this._coreService;\n const { buffers, cols } = this._bufferService;\n const { active, alt } = buffers;\n const opts = this._optionsService.rawOptions;\n\n const f = (m: number, v: V): boolean => {\n cs.triggerDataEvent(`${C0.ESC}[${ansi ? '' : '?'}${m};${v}$y`);\n return true;\n };\n const b2v = (value: boolean): V => value ? V.SET : V.RESET;\n\n const p = params.params[0];\n\n if (ansi) {\n if (p === 2) return f(p, V.PERMANENTLY_RESET);\n if (p === 4) return f(p, b2v(cs.modes.insertMode));\n if (p === 12) return f(p, V.PERMANENTLY_SET);\n if (p === 20) return f(p, b2v(opts.convertEol));\n return f(p, V.NOT_RECOGNIZED);\n }\n\n if (p === 1) return f(p, b2v(dm.applicationCursorKeys));\n if (p === 3) return f(p, opts.windowOptions.setWinLines ? (cols === 80 ? V.RESET : cols === 132 ? V.SET : V.NOT_RECOGNIZED) : V.NOT_RECOGNIZED);\n if (p === 6) return f(p, b2v(dm.origin));\n if (p === 7) return f(p, b2v(dm.wraparound));\n if (p === 8) return f(p, V.PERMANENTLY_SET);\n if (p === 9) return f(p, b2v(mouseProtocol === 'X10'));\n if (p === 12) return f(p, b2v(opts.cursorBlink));\n if (p === 25) return f(p, b2v(!cs.isCursorHidden));\n if (p === 45) return f(p, b2v(dm.reverseWraparound));\n if (p === 66) return f(p, b2v(dm.applicationKeypad));\n if (p === 67) return f(p, V.PERMANENTLY_RESET);\n if (p === 1000) return f(p, b2v(mouseProtocol === 'VT200'));\n if (p === 1002) return f(p, b2v(mouseProtocol === 'DRAG'));\n if (p === 1003) return f(p, b2v(mouseProtocol === 'ANY'));\n if (p === 1004) return f(p, b2v(dm.sendFocus));\n if (p === 1005) return f(p, V.PERMANENTLY_RESET);\n if (p === 1006) return f(p, b2v(mouseEncoding === 'SGR'));\n if (p === 1015) return f(p, V.PERMANENTLY_RESET);\n if (p === 1016) return f(p, b2v(mouseEncoding === 'SGR_PIXELS'));\n if (p === 1048) return f(p, V.SET); // xterm always returns SET here\n if (p === 47 || p === 1047 || p === 1049) return f(p, b2v(active === alt));\n if (p === 2004) return f(p, b2v(dm.bracketedPasteMode));\n if (p === 2026) return f(p, b2v(dm.synchronizedOutput));\n if (p === 9001) return this._optionsService.rawOptions.vtExtensions?.win32InputMode ? f(p, b2v(dm.win32InputMode)) : f(p, V.NOT_RECOGNIZED);\n return f(p, V.NOT_RECOGNIZED);\n }\n\n /**\n * Helper to write color information packed with color mode.\n */\n private _updateAttrColor(color: number, mode: number, c1: number, c2: number, c3: number): number {\n if (mode === 2) {\n color |= Attributes.CM_RGB;\n color &= ~Attributes.RGB_MASK;\n color |= AttributeData.fromColorRGB([c1, c2, c3]);\n } else if (mode === 5) {\n color &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n color |= Attributes.CM_P256 | (c1 & 0xff);\n }\n return color;\n }\n\n /**\n * Helper to extract and apply color params/subparams.\n * Returns advance for params index.\n */\n private _extractColor(params: IParams, pos: number, attr: IAttributeData): number {\n // normalize params\n // meaning: [target, CM, ign, val, val, val]\n // RGB : [ 38/48, 2, ign, r, g, b]\n // P256 : [ 38/48, 5, ign, v, ign, ign]\n const accu = [0, 0, -1, 0, 0, 0];\n\n // alignment placeholder for non color space sequences\n let cSpace = 0;\n\n // return advance we took in params\n let advance = 0;\n\n do {\n accu[advance + cSpace] = params.params[pos + advance];\n if (params.hasSubParams(pos + advance)) {\n const subparams = params.getSubParams(pos + advance)!;\n let i = 0;\n do {\n if (accu[1] === 5) {\n cSpace = 1;\n }\n accu[advance + i + 1 + cSpace] = subparams[i];\n } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length);\n break;\n }\n // exit early if can decide color mode with semicolons\n if ((accu[1] === 5 && advance + cSpace >= 2)\n || (accu[1] === 2 && advance + cSpace >= 5)) {\n break;\n }\n // offset colorSpace slot for semicolon mode\n if (accu[1]) {\n cSpace = 1;\n }\n } while (++advance + pos < params.length && advance + cSpace < accu.length);\n\n // set default values to 0\n for (let i = 2; i < accu.length; ++i) {\n if (accu[i] === -1) {\n accu[i] = 0;\n }\n }\n\n // apply colors\n switch (accu[0]) {\n case 38:\n attr.fg = this._updateAttrColor(attr.fg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 48:\n attr.bg = this._updateAttrColor(attr.bg, accu[1], accu[3], accu[4], accu[5]);\n break;\n case 58:\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = this._updateAttrColor(attr.extended.underlineColor, accu[1], accu[3], accu[4], accu[5]);\n }\n\n return advance;\n }\n\n /**\n * SGR 4 subparams:\n * 4:0 - equal to SGR 24 (turn off all underline)\n * 4:1 - equal to SGR 4 (single underline)\n * 4:2 - equal to SGR 21 (double underline)\n * 4:3 - curly underline\n * 4:4 - dotted underline\n * 4:5 - dashed underline\n */\n private _processUnderline(style: number, attr: IAttributeData): void {\n // treat extended attrs as immutable, thus always clone from old one\n // this is needed since the buffer only holds references to it\n attr.extended = attr.extended.clone();\n\n // default to 1 == single underline\n if (!~style || style > 5) {\n style = 1;\n }\n attr.extended.underlineStyle = style;\n attr.fg |= FgFlags.UNDERLINE;\n\n // 0 deactivates underline\n if (style === 0) {\n attr.fg &= ~FgFlags.UNDERLINE;\n }\n\n // update HAS_EXTENDED in BG\n attr.updateExtended();\n }\n\n private _processSGR0(attr: IAttributeData): void {\n attr.fg = DEFAULT_ATTR_DATA.fg;\n attr.bg = DEFAULT_ATTR_DATA.bg;\n attr.extended = attr.extended.clone();\n // Reset underline style and color. Note that we don't want to reset other\n // fields such as the url id.\n attr.extended.underlineStyle = UnderlineStyle.NONE;\n attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.updateExtended();\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n *\n * @vt: #P[See below for supported attributes.] CSI SGR \"Select Graphic Rendition\" \"CSI Pm m\" \"Set/Reset various text attributes.\"\n * SGR selects one or more character attributes at the same time. Multiple params (up to 32)\n * are applied in order from left to right. The changed attributes are applied to all new\n * characters received. If you move characters in the viewport by scrolling or any other means,\n * then the attributes move with the characters.\n *\n * Supported param values by SGR:\n *\n * | Param | Meaning | Support |\n * | --------- | -------------------------------------------------------- | ------- |\n * | 0 | Normal (default). Resets any other preceding SGR. | #Y |\n * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |\n * | 2 | Faint, decreased intensity. | #Y |\n * | 3 | Italic. | #Y |\n * | 4 | Underlined (see below for style support). | #Y |\n * | 5 | Slowly blinking. | #N |\n * | 6 | Rapidly blinking. | #N |\n * | 7 | Inverse. Flips foreground and background color. | #Y |\n * | 8 | Invisible (hidden). | #Y |\n * | 9 | Crossed-out characters (strikethrough). | #Y |\n * | 21 | Doubly underlined. | #Y |\n * | 22 | Normal (neither bold nor faint). | #Y |\n * | 23 | No italic. | #Y |\n * | 24 | Not underlined. | #Y |\n * | 25 | Steady (not blinking). | #Y |\n * | 27 | Positive (not inverse). | #Y |\n * | 28 | Visible (not hidden). | #Y |\n * | 29 | Not Crossed-out (strikethrough). | #Y |\n * | 30 | Foreground color: Black. | #Y |\n * | 31 | Foreground color: Red. | #Y |\n * | 32 | Foreground color: Green. | #Y |\n * | 33 | Foreground color: Yellow. | #Y |\n * | 34 | Foreground color: Blue. | #Y |\n * | 35 | Foreground color: Magenta. | #Y |\n * | 36 | Foreground color: Cyan. | #Y |\n * | 37 | Foreground color: White. | #Y |\n * | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 39 | Foreground color: Default (original). | #Y |\n * | 40 | Background color: Black. | #Y |\n * | 41 | Background color: Red. | #Y |\n * | 42 | Background color: Green. | #Y |\n * | 43 | Background color: Yellow. | #Y |\n * | 44 | Background color: Blue. | #Y |\n * | 45 | Background color: Magenta. | #Y |\n * | 46 | Background color: Cyan. | #Y |\n * | 47 | Background color: White. | #Y |\n * | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 49 | Background color: Default (original). | #Y |\n * | 53 | Overlined. | #Y |\n * | 55 | Not Overlined. | #Y |\n * | 58 | Underline color: Extended color. | #P[Support for RGB and indexed colors, see below.] |\n * | 221 | Not bold (kitty extension). | #Y |\n * | 222 | Not faint (kitty extension). | #Y |\n * | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |\n * | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |\n *\n * Underline supports subparams to denote the style in the form `4 : x`:\n *\n * | x | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | No underline. Same as `SGR 24 m`. | #Y |\n * | 1 | Single underline. Same as `SGR 4 m`. | #Y |\n * | 2 | Double underline. | #Y |\n * | 3 | Curly underline. | #Y |\n * | 4 | Dotted underline. | #Y |\n * | 5 | Dashed underline. | #Y |\n * | other | Single underline. Same as `SGR 4 m`. | #Y |\n *\n * Extended colors are supported for foreground (Ps=38), background (Ps=48) and underline (Ps=58)\n * as follows:\n *\n * | Ps + 1 | Meaning | Support |\n * | ------ | ------------------------------------------------------------- | ------- |\n * | 0 | Implementation defined. | #N |\n * | 1 | Transparent. | #N |\n * | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |\n * | 3 | CMY color. | #N |\n * | 4 | CMYK color. | #N |\n * | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |\n */\n public charAttributes(params: IParams): boolean {\n // Optimize a single SGR0.\n if (params.length === 1 && params.params[0] === 0) {\n this._processSGR0(this._curAttrData);\n return true;\n }\n\n const l = params.length;\n let p;\n const attr = this._curAttrData;\n\n for (let i = 0; i < l; i++) {\n p = params.params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 30);\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 40);\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n } else if (p === 0) {\n // default\n this._processSGR0(attr);\n } else if (p === 1) {\n // bold text\n attr.fg |= FgFlags.BOLD;\n } else if (p === 3) {\n // italic text\n attr.bg |= BgFlags.ITALIC;\n } else if (p === 4) {\n // underlined text\n attr.fg |= FgFlags.UNDERLINE;\n this._processUnderline(params.hasSubParams(i) ? params.getSubParams(i)![0] : UnderlineStyle.SINGLE, attr);\n } else if (p === 5) {\n // blink\n attr.fg |= FgFlags.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n attr.fg |= FgFlags.INVERSE;\n } else if (p === 8) {\n // invisible\n attr.fg |= FgFlags.INVISIBLE;\n } else if (p === 9) {\n // strikethrough\n attr.fg |= FgFlags.STRIKETHROUGH;\n } else if (p === 2) {\n // dimmed text\n attr.bg |= BgFlags.DIM;\n } else if (p === 21) {\n // double underline\n this._processUnderline(UnderlineStyle.DOUBLE, attr);\n } else if (p === 22) {\n // not bold nor faint\n attr.fg &= ~FgFlags.BOLD;\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 23) {\n // not italic\n attr.bg &= ~BgFlags.ITALIC;\n } else if (p === 24) {\n // not underlined\n attr.fg &= ~FgFlags.UNDERLINE;\n this._processUnderline(UnderlineStyle.NONE, attr);\n } else if (p === 25) {\n // not blink\n attr.fg &= ~FgFlags.BLINK;\n } else if (p === 27) {\n // not inverse\n attr.fg &= ~FgFlags.INVERSE;\n } else if (p === 28) {\n // not invisible\n attr.fg &= ~FgFlags.INVISIBLE;\n } else if (p === 29) {\n // not strikethrough\n attr.fg &= ~FgFlags.STRIKETHROUGH;\n } else if (p === 39) {\n // reset fg\n attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.fg |= DEFAULT_ATTR_DATA.fg & Attributes.RGB_MASK;\n } else if (p === 49) {\n // reset bg\n attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n attr.bg |= DEFAULT_ATTR_DATA.bg & Attributes.RGB_MASK;\n } else if (p === 38 || p === 48 || p === 58) {\n // fg color 256 and RGB\n i += this._extractColor(params, i, attr);\n } else if (p === 53) {\n // overline\n attr.bg |= BgFlags.OVERLINE;\n } else if (p === 55) {\n // not overline\n attr.bg &= ~BgFlags.OVERLINE;\n } else if (p === 221 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not bold (kitty extension)\n attr.fg &= ~FgFlags.BOLD;\n } else if (p === 222 && (this._optionsService.rawOptions.vtExtensions?.kittySgrBoldFaintControl ?? true)) {\n // not faint (kitty extension)\n attr.bg &= ~BgFlags.DIM;\n } else if (p === 59) {\n attr.extended = attr.extended.clone();\n attr.extended.underlineColor = -1;\n attr.updateExtended();\n } else {\n this._logService.debug('Unknown SGR attribute: %d.', p);\n }\n }\n return true;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n *\n * @vt: #Y CSI DSR \"Device Status Report\" \"CSI Ps n\" \"Request cursor position (CPR) with `Ps` = 6.\"\n */\n public deviceStatus(params: IParams): boolean {\n switch (params.params[0]) {\n case 5:\n // status report\n this._coreService.triggerDataEvent(`${C0.ESC}[0n`);\n break;\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[${y};${x}R`);\n break;\n }\n return true;\n }\n\n // @vt: #P[Only CPR is supported.] CSI DECDSR \"DEC Device Status Report\" \"CSI ? Ps n\" \"Only CPR is supported (same as DSR).\"\n public deviceStatusPrivate(params: IParams): boolean {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params.params[0]) {\n case 6:\n // cursor position\n const y = this._activeBuffer.y + 1;\n const x = this._activeBuffer.x + 1;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${y};${x}R`);\n break;\n case 15:\n // no printer\n // this.handler(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.handler(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.handler(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.handler(C0.ESC + '[?50n');\n break;\n case 996:\n // color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n if (this._optionsService.rawOptions.vtExtensions?.colorSchemeQuery ?? true) {\n this._onRequestColorSchemeQuery.fire();\n }\n break;\n }\n return true;\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n *\n * @vt: #Y CSI DECSTR \"Soft Terminal Reset\" \"CSI ! p\" \"Reset several terminal attributes to initial state.\"\n * There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full\n * terminal bootstrap, DECSTR only resets certain attributes. For most needs DECSTR should be\n * sufficient.\n *\n * The following terminal attributes are reset to default values:\n * - IRM is reset (dafault = false)\n * - scroll margins are reset (default = viewport size)\n * - erase attributes are reset to default\n * - charsets are reset\n * - DECSC data is reset to initial values\n * - DECOM is reset to absolute mode\n *\n *\n * FIXME: there are several more attributes missing (see VT520 manual)\n */\n public softReset(params: IParams): boolean {\n this._coreService.isCursorHidden = false;\n this._onRequestSyncScrollBar.fire();\n this._activeBuffer.scrollTop = 0;\n this._activeBuffer.scrollBottom = this._bufferService.rows - 1;\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._coreService.reset();\n this._charsetService.reset();\n\n // reset DECSC data\n this._activeBuffer.savedX = 0;\n this._activeBuffer.savedY = this._activeBuffer.ybase;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n\n // reset DECOM\n this._coreService.decPrivateModes.origin = false;\n return true;\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> reset to option.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n *\n * @vt: #Y CSI DECSCUSR \"Set Cursor Style\" \"CSI Ps SP q\" \"Set cursor style.\"\n * Supported cursor styles:\n * - 0: reset to option\n * - empty, 1: blinking block\n * - 2: steady block\n * - 3: blinking underline\n * - 4: steady underline\n * - 5: blinking bar\n * - 6: steady bar\n */\n public setCursorStyle(params: IParams): boolean {\n const param = params.length === 0 ? 1 : params.params[0];\n if (param === 0) {\n this._coreService.decPrivateModes.cursorStyle = undefined;\n this._coreService.decPrivateModes.cursorBlink = undefined;\n } else {\n switch (param) {\n case 1:\n case 2:\n this._coreService.decPrivateModes.cursorStyle = 'block';\n break;\n case 3:\n case 4:\n this._coreService.decPrivateModes.cursorStyle = 'underline';\n break;\n case 5:\n case 6:\n this._coreService.decPrivateModes.cursorStyle = 'bar';\n break;\n }\n const isBlinking = param % 2 === 1;\n this._coreService.decPrivateModes.cursorBlink = isBlinking;\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n *\n * @vt: #Y CSI DECSTBM \"Set Top and Bottom Margin\" \"CSI Ps ; Ps r\" \"Set top and bottom margins of the viewport [top;bottom] (default = viewport size).\"\n */\n public setScrollRegion(params: IParams): boolean {\n const top = params.params[0] || 1;\n let bottom: number;\n\n if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {\n bottom = this._bufferService.rows;\n }\n\n if (bottom > top) {\n this._activeBuffer.scrollTop = top - 1;\n this._activeBuffer.scrollBottom = bottom - 1;\n this._setCursor(0, 0);\n }\n return true;\n }\n\n /**\n * CSI Ps ; Ps ; Ps t - Various window manipulations and reports (xterm)\n *\n * Note: Only those listed below are supported. All others are left to integrators and\n * need special treatment based on the embedding environment.\n *\n * Ps = 1 4 supported\n * Report xterm text area size in pixels.\n * Result is CSI 4 ; height ; width t\n * Ps = 14 ; 2 not implemented\n * Ps = 16 supported\n * Report xterm character cell size in pixels.\n * Result is CSI 6 ; height ; width t\n * Ps = 18 supported\n * Report the size of the text area in characters.\n * Result is CSI 8 ; height ; width t\n * Ps = 20 supported\n * Report xterm window's icon label.\n * Result is OSC L label ST\n * Ps = 21 supported\n * Report xterm window's title.\n * Result is OSC l label ST\n * Ps = 22 ; 0 -> Save xterm icon and window title on stack. supported\n * Ps = 22 ; 1 -> Save xterm icon title on stack. supported\n * Ps = 22 ; 2 -> Save xterm window title on stack. supported\n * Ps = 23 ; 0 -> Restore xterm icon and window title from stack. supported\n * Ps = 23 ; 1 -> Restore xterm icon title from stack. supported\n * Ps = 23 ; 2 -> Restore xterm window title from stack. supported\n * Ps >= 24 not implemented\n */\n public windowOptions(params: IParams): boolean {\n if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {\n return true;\n }\n const second = (params.length > 1) ? params.params[1] : 0;\n switch (params.params[0]) {\n case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t\n if (second !== 2) {\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);\n }\n break;\n case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t\n this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);\n break;\n case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t\n if (this._bufferService) {\n this._coreService.triggerDataEvent(`${C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);\n }\n break;\n case 22: // PushTitle\n if (second === 0 || second === 2) {\n this._windowTitleStack.push(this._windowTitle);\n if (this._windowTitleStack.length > Constants.STACK_LIMIT) {\n this._windowTitleStack.shift();\n }\n }\n if (second === 0 || second === 1) {\n this._iconNameStack.push(this._iconName);\n if (this._iconNameStack.length > Constants.STACK_LIMIT) {\n this._iconNameStack.shift();\n }\n }\n break;\n case 23: // PopTitle\n if (second === 0 || second === 2) {\n if (this._windowTitleStack.length) {\n this.setTitle(this._windowTitleStack.pop()!);\n }\n }\n if (second === 0 || second === 1) {\n if (this._iconNameStack.length) {\n this.setIconName(this._iconNameStack.pop()!);\n }\n }\n break;\n }\n return true;\n }\n\n\n /**\n * CSI s\n * ESC 7\n * Save cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCOSC \"Save Cursor\" \"CSI s\" \"Save cursor position, charmap and text attributes.\"\n * @vt: #Y ESC SC \"Save Cursor\" \"ESC 7\" \"Save cursor position, charmap and text attributes.\"\n */\n public saveCursor(params?: IParams): boolean {\n this._activeBuffer.savedX = this._activeBuffer.x;\n this._activeBuffer.savedY = this._activeBuffer.ybase + this._activeBuffer.y;\n this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg;\n this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg;\n this._activeBuffer.savedCharset = this._charsetService.charset;\n this._activeBuffer.savedCharsets = this._charsetService.charsets.slice();\n this._activeBuffer.savedGlevel = this._charsetService.glevel;\n this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin;\n this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound;\n return true;\n }\n\n\n /**\n * CSI u\n * ESC 8\n * Restore cursor (ANSI.SYS).\n *\n * @vt: #P[TODO...] CSI SCORC \"Restore Cursor\" \"CSI u\" \"Restore cursor position, charmap and text attributes.\"\n * @vt: #Y ESC RC \"Restore Cursor\" \"ESC 8\" \"Restore cursor position, charmap and text attributes.\"\n */\n public restoreCursor(params?: IParams): boolean {\n this._activeBuffer.x = this._activeBuffer.savedX || 0;\n this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0);\n this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg;\n this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg;\n for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) {\n this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]);\n }\n this._charsetService.setgLevel(this._activeBuffer.savedGlevel);\n this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode;\n this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode;\n this._restrictCursor();\n return true;\n }\n\n /**\n * OSC 2; ST (set window title)\n * Proxy to set window title.\n *\n * @vt: #P[Icon name is not exposed.] OSC 0 \"Set Windows Title and Icon Name\" \"OSC 0 ; Pt BEL\" \"Set window title and icon name.\"\n * Icon name is not supported. For Window Title see below.\n *\n * @vt: #Y OSC 2 \"Set Windows Title\" \"OSC 2 ; Pt BEL\" \"Set window title.\"\n * xterm.js does not manipulate the title directly, instead exposes changes via the event\n * `Terminal.onTitleChange`.\n */\n public setTitle(data: string): boolean {\n this._windowTitle = data;\n this._onTitleChange.fire(data);\n return true;\n }\n\n /**\n * OSC 1; ST\n * Note: Icon name is not exposed.\n */\n public setIconName(data: string): boolean {\n this._iconName = data;\n return true;\n }\n\n /**\n * OSC 4; ; ST (set ANSI color to )\n *\n * @vt: #Y OSC 4 \"Set ANSI color\" \"OSC 4 ; c ; spec BEL\" \"Change color number `c` to the color specified by `spec`.\"\n * `c` is the color index between 0 and 255. The color format of `spec` is derived from\n * `XParseColor` (see OSC 10 for supported formats). There may be multipe `c ; spec` pairs present\n * in the same instruction. If `spec` contains `?` the terminal returns a sequence with the\n * currently set color.\n */\n public setOrReportIndexedColor(data: string): boolean {\n const event: IColorEvent = [];\n const slots = data.split(';');\n while (slots.length > 1) {\n const idx = slots.shift() as string;\n const spec = slots.shift() as string;\n if (/^\\d+$/.exec(idx)) {\n const index = parseInt(idx, 10);\n if (isValidColorIndex(index)) {\n if (spec === '?') {\n event.push({ type: ColorRequestType.REPORT, index });\n } else {\n const color = parseColor(spec);\n if (color) {\n event.push({ type: ColorRequestType.SET, index, color });\n }\n }\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 8 ; ; ST - create hyperlink\n * OSC 8 ; ; ST - finish hyperlink\n *\n * Test case:\n *\n * ```sh\n * printf '\\e]8;;http://example.com\\e\\\\This is a link\\e]8;;\\e\\\\\\n'\n * ```\n *\n * @vt: #Y OSC 8 \"Create hyperlink\" \"OSC 8 ; params ; uri BEL\" \"Create a hyperlink to `uri` using `params`.\"\n * `uri` is a hyperlink starting with `http://`, `https://`, `ftp://`, `file://` or `mailto://`. `params` is an\n * optional list of key=value assignments, separated by the : character.\n * Example: `id=xyz123:foo=bar:baz=quux`.\n * Currently only the id key is defined. Cells that share the same ID and URI share hover\n * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink.\n */\n public setHyperlink(data: string): boolean {\n // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944)\n const idx = data.indexOf(';');\n if (idx === -1) {\n // malformed sequence, just return as handled\n return true;\n }\n const id = data.slice(0, idx).trim();\n const uri = data.slice(idx + 1);\n if (uri) {\n return this._createHyperlink(id, uri);\n }\n if (id.trim()) {\n return false;\n }\n return this._finishHyperlink();\n }\n\n private _createHyperlink(params: string, uri: string): boolean {\n // It's legal to open a new hyperlink without explicitly finishing the previous one\n if (this._getCurrentLinkId()) {\n this._finishHyperlink();\n }\n const parsedParams = params.split(':');\n let id: string | undefined;\n const idParamIndex = parsedParams.findIndex(e => e.startsWith('id='));\n if (idParamIndex !== -1) {\n id = parsedParams[idParamIndex].slice(3) || undefined;\n }\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });\n this._curAttrData.updateExtended();\n return true;\n }\n\n private _finishHyperlink(): boolean {\n this._curAttrData.extended = this._curAttrData.extended.clone();\n this._curAttrData.extended.urlId = 0;\n this._curAttrData.updateExtended();\n return true;\n }\n\n // special colors - OSC 10 | 11 | 12\n private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR];\n\n /**\n * Apply colors requests for special colors in OSC 10 | 11 | 12.\n * Since these commands are stacking from multiple parameters,\n * we handle them in a loop with an entry offset to `_specialColors`.\n */\n private _setOrReportSpecialColor(data: string, offset: number): boolean {\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i, ++offset) {\n if (offset >= this._specialColors.length) break;\n if (slots[i] === '?') {\n this._onColor.fire([{ type: ColorRequestType.REPORT, index: this._specialColors[offset] }]);\n } else {\n const color = parseColor(slots[i]);\n if (color) {\n this._onColor.fire([{ type: ColorRequestType.SET, index: this._specialColors[offset], color }]);\n }\n }\n }\n return true;\n }\n\n /**\n * OSC 10 ; | ST - set or query default foreground color\n *\n * @vt: #Y OSC 10 \"Set or query default foreground color\" \"OSC 10 ; Pt BEL\" \"Set or query default foreground color.\"\n * To set the color, the following color specification formats are supported:\n * - `rgb://` for `, , ` in `h | hh | hhh | hhhh`, where\n * `h` is a single hexadecimal digit (case insignificant). The different widths scale\n * from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).\n * - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`\n * - `#RRGGBB` - 8 bits per channel\n * - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`\n * - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`\n *\n * **Note:** X11 named colors are currently unsupported.\n *\n * If `Pt` contains `?` instead of a color specification, the terminal\n * returns a sequence with the current default foreground color\n * (use that sequence to restore the color after changes).\n *\n * **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.\n * Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.\n */\n public setOrReportFgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 0);\n }\n\n /**\n * OSC 11 ; | ST - set or query default background color\n *\n * @vt: #Y OSC 11 \"Set or query default background color\" \"OSC 11 ; Pt BEL\" \"Same as OSC 10, but for default background.\"\n */\n public setOrReportBgColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 1);\n }\n\n /**\n * OSC 12 ; | ST - set or query default cursor color\n *\n * @vt: #Y OSC 12 \"Set or query default cursor color\" \"OSC 12 ; Pt BEL\" \"Same as OSC 10, but for default cursor color.\"\n */\n public setOrReportCursorColor(data: string): boolean {\n return this._setOrReportSpecialColor(data, 2);\n }\n\n /**\n * OSC 104 ; ST - restore ANSI color \n *\n * @vt: #Y OSC 104 \"Reset ANSI color\" \"OSC 104 ; c BEL\" \"Reset color number `c` to themed color.\"\n * `c` is the color index between 0 and 255. This function restores the default color for `c` as\n * specified by the loaded theme. Any number of `c` parameters may be given.\n * If no parameters are given, the entire indexed color table will be reset.\n */\n public restoreIndexedColor(data: string): boolean {\n if (!data) {\n this._onColor.fire([{ type: ColorRequestType.RESTORE }]);\n return true;\n }\n const event: IColorEvent = [];\n const slots = data.split(';');\n for (let i = 0; i < slots.length; ++i) {\n if (/^\\d+$/.exec(slots[i])) {\n const index = parseInt(slots[i], 10);\n if (isValidColorIndex(index)) {\n event.push({ type: ColorRequestType.RESTORE, index });\n }\n }\n }\n if (event.length) {\n this._onColor.fire(event);\n }\n return true;\n }\n\n /**\n * OSC 110 ST - restore default foreground color\n *\n * @vt: #Y OSC 110 \"Restore default foreground color\" \"OSC 110 BEL\" \"Restore default foreground to themed color.\"\n */\n public restoreFgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]);\n return true;\n }\n\n /**\n * OSC 111 ST - restore default background color\n *\n * @vt: #Y OSC 111 \"Restore default background color\" \"OSC 111 BEL\" \"Restore default background to themed color.\"\n */\n public restoreBgColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]);\n return true;\n }\n\n /**\n * OSC 112 ST - restore default cursor color\n *\n * @vt: #Y OSC 112 \"Restore default cursor color\" \"OSC 112 BEL\" \"Restore default cursor to themed color.\"\n */\n public restoreCursorColor(data: string): boolean {\n this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]);\n return true;\n }\n\n /**\n * ESC E\n * C1.NEL\n * DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n * Moves cursor to first position on next line.\n *\n * @vt: #Y C1 NEL \"Next Line\" \"\\x85\" \"Move the cursor to the beginning of the next row.\"\n * @vt: #Y ESC NEL \"Next Line\" \"ESC E\" \"Move the cursor to the beginning of the next row.\"\n */\n public nextLine(): boolean {\n this._activeBuffer.x = 0;\n this.index();\n return true;\n }\n\n /**\n * ESC =\n * DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n * Enables the numeric keypad to send application sequences to the host.\n */\n public keypadApplicationMode(): boolean {\n this._logService.debug('Serial port requested application keypad.');\n this._coreService.decPrivateModes.applicationKeypad = true;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC >\n * DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n * Enables the keypad to send numeric characters to the host.\n */\n public keypadNumericMode(): boolean {\n this._logService.debug('Switching back to normal keypad.');\n this._coreService.decPrivateModes.applicationKeypad = false;\n this._onRequestSyncScrollBar.fire();\n return true;\n }\n\n /**\n * ESC % @\n * ESC % G\n * Select default character set. UTF-8 is not supported (string are unicode anyways)\n * therefore ESC % G does the same.\n */\n public selectDefaultCharset(): boolean {\n this._charsetService.setgLevel(0);\n this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)\n return true;\n }\n\n /**\n * ESC ( C\n * Designate G0 Character Set, VT100, ISO 2022.\n * ESC ) C\n * Designate G1 Character Set (ISO 2022, VT100).\n * ESC * C\n * Designate G2 Character Set (ISO 2022, VT220).\n * ESC + C\n * Designate G3 Character Set (ISO 2022, VT220).\n * ESC - C\n * Designate G1 Character Set (VT300).\n * ESC . C\n * Designate G2 Character Set (VT300).\n * ESC / C\n * Designate G3 Character Set (VT300). C = A -> ISO Latin-1 Supplemental. - Supported?\n */\n public selectCharset(collectAndFlag: string): boolean {\n if (collectAndFlag.length !== 2) {\n this.selectDefaultCharset();\n return true;\n }\n if (collectAndFlag[0] === '/') {\n return true; // TODO: Is this supported?\n }\n this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] ?? DEFAULT_CHARSET);\n return true;\n }\n\n /**\n * ESC D\n * C1.IND\n * DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n * Moves the cursor down one line in the same column.\n *\n * @vt: #Y C1 IND \"Index\" \"\\x84\" \"Move the cursor one line down scrolling if needed.\"\n * @vt: #Y ESC IND \"Index\" \"ESC D\" \"Move the cursor one line down scrolling if needed.\"\n */\n public index(): boolean {\n this._restrictCursor();\n this._activeBuffer.y++;\n if (this._activeBuffer.y === this._activeBuffer.scrollBottom + 1) {\n this._activeBuffer.y--;\n this._bufferService.scroll(this._eraseAttrData());\n } else if (this._activeBuffer.y >= this._bufferService.rows) {\n this._activeBuffer.y = this._bufferService.rows - 1;\n }\n this._restrictCursor();\n return true;\n }\n\n /**\n * ESC H\n * C1.HTS\n * DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n * Sets a horizontal tab stop at the column position indicated by\n * the value of the active column when the terminal receives an HTS.\n *\n * @vt: #Y C1 HTS \"Horizontal Tabulation Set\" \"\\x88\" \"Places a tab stop at the current cursor position.\"\n * @vt: #Y ESC HTS \"Horizontal Tabulation Set\" \"ESC H\" \"Places a tab stop at the current cursor position.\"\n */\n public tabSet(): boolean {\n this._activeBuffer.tabs[this._activeBuffer.x] = true;\n return true;\n }\n\n /**\n * ESC M\n * C1.RI\n * DEC mnemonic: HTS\n * Moves the cursor up one line in the same column. If the cursor is at the top margin,\n * the page scrolls down.\n *\n * @vt: #Y ESC IR \"Reverse Index\" \"ESC M\" \"Move the cursor one line up scrolling if needed.\"\n */\n public reverseIndex(): boolean {\n this._restrictCursor();\n if (this._activeBuffer.y === this._activeBuffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this._activeBuffer.scrollBottom - this._activeBuffer.scrollTop;\n this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase + this._activeBuffer.y, scrollRegionHeight, 1);\n this._activeBuffer.lines.set(this._activeBuffer.ybase + this._activeBuffer.y, this._activeBuffer.getBlankLine(this._eraseAttrData()));\n this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom);\n } else {\n this._activeBuffer.y--;\n this._restrictCursor(); // quickfix to not run out of bounds\n }\n return true;\n }\n\n /**\n * ESC c\n * DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n * Reset to initial state.\n *\n * @vt: #Y ESC RIS \"Full Reset\" \"ESC c\" \"Reset to initial state.\"\n */\n public fullReset(): boolean {\n this._parser.reset();\n this._onRequestReset.fire();\n return true;\n }\n\n public reset(): void {\n this._curAttrData = DEFAULT_ATTR_DATA.clone();\n this._eraseAttrDataInternal = DEFAULT_ATTR_DATA.clone();\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n private _eraseAttrData(): IAttributeData {\n this._eraseAttrDataInternal.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n this._eraseAttrDataInternal.bg |= this._curAttrData.bg & ~0xFC000000;\n return this._eraseAttrDataInternal;\n }\n\n /**\n * ESC n\n * ESC o\n * ESC |\n * ESC }\n * ESC ~\n * DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n * When you use a locking shift, the character set remains in GL or GR until\n * you use another locking shift. (partly supported)\n */\n public setgLevel(level: number): boolean {\n this._charsetService.setgLevel(level);\n return true;\n }\n\n /**\n * ESC # 8\n * DEC mnemonic: DECALN (https://vt100.net/docs/vt510-rm/DECALN.html)\n * This control function fills the complete screen area with\n * a test pattern (E) used for adjusting screen alignment.\n *\n * @vt: #Y ESC DECALN \"Screen Alignment Pattern\" \"ESC # 8\" \"Fill viewport with a test pattern (E).\"\n */\n public screenAlignmentPattern(): boolean {\n // prepare cell data\n const cell = new CellData();\n cell.content = 1 << Content.WIDTH_SHIFT | 'E'.charCodeAt(0);\n cell.fg = this._curAttrData.fg;\n cell.bg = this._curAttrData.bg;\n\n\n this._setCursor(0, 0);\n for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {\n const row = this._activeBuffer.ybase + this._activeBuffer.y + yOffset;\n const line = this._activeBuffer.lines.get(row);\n if (line) {\n line.fill(cell);\n line.isWrapped = false;\n }\n }\n this._dirtyRowTracker.markAllDirty();\n this._setCursor(0, 0);\n return true;\n }\n\n\n /**\n * DCS $ q Pt ST\n * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n * Request Status String (DECRQSS), VT420 and up.\n * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n *\n * @vt: #P[Limited support, see below.] DCS DECRQSS \"Request Selection or Setting\" \"DCS $ q Pt ST\" \"Request several terminal settings.\"\n * Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the\n * corresponding CSI string, `ESC P 0 ST` for invalid requests.\n *\n * Supported requests and responses:\n *\n * | Type | Request | Response (`Pt`) |\n * | -------------------------------- | ----------------- | ----------------------------------------------------- |\n * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |\n * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |\n * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |\n * | Protection Attribute (DECSCA) | `DCS $ q \" q ST` | `Ps \" q` (DECSCA 2 is reported as Ps = 0) |\n * | Conformance Level (DECSCL) | `DCS $ q \" p ST` | always reporting `61 ; 1 \" p` (DECSCL is unsupported) |\n *\n *\n * TODO:\n * - fix SGR report\n * - either check which conformance is better suited or remove the report completely\n * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly\n */\n public requestStatusString(data: string, params: IParams): boolean {\n const f = (s: string): boolean => {\n this._coreService.triggerDataEvent(`${C0.ESC}${s}${C0.ESC}\\\\`);\n return true;\n };\n\n // access helpers\n const b = this._bufferService.buffer;\n const opts = this._optionsService.rawOptions;\n const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };\n\n if (data === '\"q') return f(`P1$r${this._curAttrData.isProtected() ? 1 : 0}\"q`);\n if (data === '\"p') return f(`P1$r61;1\"p`);\n if (data === 'r') return f(`P1$r${b.scrollTop + 1};${b.scrollBottom + 1}r`);\n // FIXME: report real SGR settings instead of 0m\n if (data === 'm') return f(`P1$r0m`);\n if (data === ' q') return f(`P1$r${STYLES[opts.cursorStyle] - (opts.cursorBlink ? 1 : 0)} q`);\n return f(`P0$r`);\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n this._dirtyRowTracker.markRangeDirty(y1, y2);\n }\n\n // #region Kitty keyboard\n\n /**\n * CSI = flags ; mode u\n * Set Kitty keyboard protocol flags.\n * mode: 1=set, 2=set-only-specified, 3=reset-only-specified\n *\n * @vt: #Y CSI KKBDSET \"Kitty Keyboard Set\" \"CSI = Ps ; Pm u\" \"Set Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardSet(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const mode = params.length > 1 ? (params.params[1] || 1) : 1;\n const state = this._coreService.kittyKeyboard;\n\n switch (mode) {\n case 1: // Set all flags\n state.flags = flags;\n break;\n case 2: // Set only specified flags (OR)\n state.flags |= flags;\n break;\n case 3: // Reset only specified flags (AND NOT)\n state.flags &= ~flags;\n break;\n }\n return true;\n }\n\n /**\n * CSI ? u\n * Query Kitty keyboard protocol flags.\n * Terminal responds with CSI ? flags u\n *\n * @vt: #Y CSI KKBDQUERY \"Kitty Keyboard Query\" \"CSI ? u\" \"Query Kitty keyboard protocol flags.\"\n */\n public kittyKeyboardQuery(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = this._coreService.kittyKeyboard.flags;\n this._coreService.triggerDataEvent(`${C0.ESC}[?${flags}u`);\n return true;\n }\n\n /**\n * CSI > flags u\n * Push Kitty keyboard flags onto stack and set new flags.\n *\n * @vt: #Y CSI KKBDPUSH \"Kitty Keyboard Push\" \"CSI > Ps u\" \"Push keyboard flags to stack and set new flags.\"\n */\n public kittyKeyboardPush(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const flags = params.params[0] || 0;\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Evict oldest entry if stack is full (DoS protection, limit of 16)\n if (stack.length >= 16) {\n stack.shift();\n }\n\n // Push current flags onto stack and set new flags\n stack.push(state.flags);\n state.flags = flags;\n return true;\n }\n\n /**\n * CSI < count u\n * Pop Kitty keyboard flags from stack.\n *\n * @vt: #Y CSI KKBDPOP \"Kitty Keyboard Pop\" \"CSI < Ps u\" \"Pop keyboard flags from stack.\"\n */\n public kittyKeyboardPop(params: IParams): boolean {\n if (!this._optionsService.rawOptions.vtExtensions?.kittyKeyboard) {\n return true;\n }\n const count = Math.max(1, params.params[0] || 1);\n const state = this._coreService.kittyKeyboard;\n const isAlt = this._bufferService.buffer === this._bufferService.buffers.alt;\n const stack = isAlt ? state.altStack : state.mainStack;\n\n // Pop specified number of entries from stack\n for (let i = 0; i < count && stack.length > 0; i++) {\n state.flags = stack.pop()!;\n }\n // If stack is empty after popping, reset to 0\n if (stack.length === 0 && count > 0) {\n state.flags = 0;\n }\n return true;\n }\n\n // #endregion\n}\n\nexport interface IDirtyRowTracker {\n readonly start: number;\n readonly end: number;\n\n clearRange(): void;\n markDirty(y: number): void;\n markRangeDirty(y1: number, y2: number): void;\n markAllDirty(): void;\n}\n\nclass DirtyRowTracker implements IDirtyRowTracker {\n public start!: number;\n public end!: number;\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n this.clearRange();\n }\n\n public clearRange(): void {\n this.start = this._bufferService.buffer.y;\n this.end = this._bufferService.buffer.y;\n }\n\n public markDirty(y: number): void {\n if (y < this.start) {\n this.start = y;\n } else if (y > this.end) {\n this.end = y;\n }\n }\n\n public markRangeDirty(y1: number, y2: number): void {\n if (y1 > y2) {\n $temp = y1;\n y1 = y2;\n y2 = $temp;\n }\n if (y1 < this.start) {\n this.start = y1;\n }\n if (y2 > this.end) {\n this.end = y2;\n }\n }\n\n public markAllDirty(): void {\n this.markRangeDirty(0, this._bufferService.rows - 1);\n }\n}\n\nexport function isValidColorIndex(value: number): value is ColorIndex {\n return 0 <= value && value < 256;\n}\n", "\n/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TimeoutTimer } from '../Async';\nimport { Disposable, toDisposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nconst enum Constants {\n /**\n * Safety watermark to avoid memory exhaustion and browser engine crash on fast data input.\n * Enable flow control to avoid this limit and make sure that your backend correctly\n * propagates this to the underlying pty. (see docs for further instructions)\n * Since this limit is meant as a safety parachute to prevent browser crashs,\n * it is set to a very high number. Typically xterm.js gets unresponsive with\n * a 100 times lower number (>500 kB).\n */\n DISCARD_WATERMARK = 50000000, // ~50 MB\n /**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\n WRITE_TIMEOUT_MS = 12,\n /**\n * Threshold of max held chunks in the write buffer, that were already processed.\n * This is a tradeoff between extensive write buffer shifts (bad runtime) and high\n * memory consumption by data thats not used anymore.\n */\n WRITE_BUFFER_LENGTH_THRESHOLD = 50\n}\n\nexport class WriteBuffer extends Disposable {\n private _writeBuffer: (string | Uint8Array)[] = [];\n private _callbacks: ((() => void) | undefined)[] = [];\n private _pendingData = 0;\n private _bufferOffset = 0;\n private _isSyncWriting = false;\n private _syncCalls = 0;\n private _didUserInput = false;\n\n private readonly _innerWriteTimer = this._register(new TimeoutTimer());\n private readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise) {\n super();\n this._register(toDisposable(() => {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }));\n }\n\n public handleUserInput(): void {\n this._didUserInput = true;\n }\n\n /**\n * Flushes all pending writes synchronously. This is useful when you need to\n * ensure all queued data is processed before performing an operation that\n * depends upon everything being parsed like resize.\n *\n * Note: This is unreliable with async parser handlers as it does not wait for\n * promises to resolve.\n */\n public flushSync(): void {\n if (this._store.isDisposed) {\n return;\n }\n // exit early if another sync write loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // Process all pending chunks synchronously\n let chunk: string | Uint8Array | undefined;\n let didProcess = false;\n while (chunk = this._writeBuffer.shift()) {\n didProcess = true;\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n\n // Reset buffer state\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n\n this._isSyncWriting = false;\n if (didProcess) {\n this._onWriteParsed.fire();\n }\n }\n\n /**\n * @deprecated Unreliable, to be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._store.isDisposed) {\n return;\n }\n // stop writeSync recursions with maxSubsequentCalls argument\n // This is dangerous to use as it will lose the current data chunk\n // and return immediately.\n if (maxSubsequentCalls !== undefined && this._syncCalls > maxSubsequentCalls) {\n // comment next line if a whole loop block should only contain x `writeSync` calls\n // (total flat vs. deep nested limit)\n this._syncCalls = 0;\n return;\n }\n // append chunk to buffer\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(undefined);\n\n // increase recursion counter\n this._syncCalls++;\n // exit early if another writeSync loop is active\n if (this._isSyncWriting) {\n return;\n }\n this._isSyncWriting = true;\n\n // force sync processing on pending data chunks to avoid in-band data scrambling\n // does the same as innerWrite but without event loop\n // we have to do it here as single loop steps to not corrupt loop subject\n // by another writeSync call triggered from _action\n let chunk: string | Uint8Array | undefined;\n while (chunk = this._writeBuffer.shift()) {\n this._action(chunk);\n const cb = this._callbacks.shift();\n if (cb) cb();\n }\n // reset to avoid reprocessing of chunks with scheduled innerWrite call\n // stopping scheduled innerWrite by offset > length condition\n this._pendingData = 0;\n this._bufferOffset = 0x7FFFFFFF;\n\n // allow another writeSync to loop\n this._isSyncWriting = false;\n this._syncCalls = 0;\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n if (this._store.isDisposed) {\n return;\n }\n if (this._pendingData > Constants.DISCARD_WATERMARK) {\n throw new Error('write data discarded, use flow control to avoid losing data');\n }\n\n // schedule chunk processing for next event loop run\n if (!this._writeBuffer.length) {\n this._bufferOffset = 0;\n\n // If this is the first write call after the user has done some input,\n // parse it immediately to minimize input latency,\n // otherwise schedule for the next event\n if (this._didUserInput) {\n this._didUserInput = false;\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n this._innerWrite();\n return;\n }\n\n this._scheduleInnerWrite();\n }\n\n this._pendingData += data.length;\n this._writeBuffer.push(data);\n this._callbacks.push(callback);\n }\n\n /**\n * Inner write call, that enters the sliced chunk processing by timing.\n *\n * `lastTime` indicates, when the last _innerWrite call had started.\n * It is used to aggregate async handler execution under a timeout constraint\n * effectively lowering the redrawing needs, schematically:\n *\n * macroTask _innerWrite:\n * if (performance.now() - (lastTime | 0) < Constants.WRITE_TIMEOUT_MS):\n * schedule microTask _innerWrite(lastTime)\n * else:\n * schedule macroTask _innerWrite(0)\n *\n * overall execution order on task queues:\n *\n * macrotasks: [...] --> _innerWrite(0) --> [...] --> screenUpdate --> [...]\n * m t: |\n * i a: [...]\n * c s: |\n * r k: while < timeout:\n * o s: _innerWrite(timeout)\n *\n * `promiseResult` depicts the promise resolve value of an async handler.\n * This value gets carried forward through all saved stack states of the\n * paused parser for proper continuation.\n *\n * Note, for pure sync code `lastTime` and `promiseResult` have no meaning.\n */\n private _scheduleInnerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n this._innerWriteTimer.cancelAndSet(() => this._innerWrite(lastTime, promiseResult), 0);\n }\n\n protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void {\n if (this._store.isDisposed) {\n return;\n }\n const startTime = lastTime || performance.now();\n while (this._writeBuffer.length > this._bufferOffset) {\n const data = this._writeBuffer[this._bufferOffset];\n const result = this._action(data, promiseResult);\n if (result) {\n /**\n * If we get a promise as return value, we re-schedule the continuation\n * as thenable on the promise and exit right away.\n *\n * The exit here means, that we block input processing at the current active chunk,\n * the exact execution position within the chunk is preserved by the saved\n * stack content in InputHandler and EscapeSequenceParser.\n *\n * Resuming happens automatically from that saved stack state.\n * Also the resolved promise value is passed along the callstack to\n * `EscapeSequenceParser.parse` to correctly resume the stopped handler loop.\n *\n * Exceptions on async handlers will be logged to console async, but do not interrupt\n * the input processing (continues with next handler at the current input position).\n */\n\n /**\n * If a promise takes long to resolve, we should schedule continuation behind setTimeout.\n * This might already be too late, if our .then enters really late (executor + prev thens\n * took very long). This cannot be solved here for the handler itself (it is the handlers\n * responsibility to slice hard work), but we can at least schedule a screen update as we\n * gain control.\n */\n const continuation: (r: boolean) => void = (r: boolean) => {\n if (this._store.isDisposed) {\n return;\n }\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n this._scheduleInnerWrite(0, r);\n } else {\n this._innerWrite(startTime, r);\n }\n };\n\n /**\n * Optimization considerations:\n * The continuation above favors FPS over throughput by eval'ing `startTime` on resolve.\n * This might schedule too many screen updates with bad throughput drops (in case a slow\n * resolving handler sliced its work properly behind setTimeout calls). We cannot spot\n * this condition here, also the renderer has no way to spot nonsense updates either.\n * FIXME: A proper fix for this would track the FPS at the renderer entry level separately.\n *\n * If favoring of FPS shows bad throughput impact, use the following instead. It favors\n * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the\n * current microtask queue (executed before setTimeout).\n */\n // const continuation: (r: boolean) => void = performance.now() - startTime >=\n // Constants.WRITE_TIMEOUT_MS\n // ? r => setTimeout(() => this._innerWrite(0, r))\n // : r => this._innerWrite(startTime, r);\n\n // Handle exceptions synchronously to current band position, idea:\n // 1. spawn a single microtask which we allow to throw hard\n // 2. spawn a promise immediately resolving to `true`\n // (executed on the same queue, thus properly aligned before continuation happens)\n result.catch(err => {\n queueMicrotask(() => {throw err;});\n return Promise.resolve(false);\n }).then(continuation);\n return;\n }\n\n const cb = this._callbacks[this._bufferOffset];\n if (cb) cb();\n this._bufferOffset++;\n this._pendingData -= data.length;\n\n if (performance.now() - startTime >= Constants.WRITE_TIMEOUT_MS) {\n break;\n }\n }\n if (this._writeBuffer.length > this._bufferOffset) {\n // Allow renderer to catch up before processing the next batch\n // trim already processed chunks if we are above threshold\n if (this._bufferOffset > Constants.WRITE_BUFFER_LENGTH_THRESHOLD) {\n this._writeBuffer = this._writeBuffer.slice(this._bufferOffset);\n this._callbacks = this._callbacks.slice(this._bufferOffset);\n this._bufferOffset = 0;\n }\n this._scheduleInnerWrite();\n } else {\n this._writeBuffer.length = 0;\n this._callbacks.length = 0;\n this._pendingData = 0;\n this._bufferOffset = 0;\n }\n this._onWriteParsed.fire();\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { IBufferService, IOscLinkService } from './Services';\nimport { IOscLinkData } from '../Types';\nimport { IMarker } from '../buffer/Types';\n\nexport class OscLinkService implements IOscLinkService {\n public serviceBrand: any;\n\n private _nextId = 1;\n\n /**\n * A map of the link key to link entry. This is used to add additional lines to links with ids.\n */\n private _entriesWithId: Map = new Map();\n\n /**\n * A map of the link id to the link entry. The \"link id\" (number) which is the numberic\n * representation of a unique link should not be confused with \"id\" (string) which comes in with\n * `id=` in the OSC link's properties.\n */\n private _dataByLinkId: Map = new Map();\n\n constructor(\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n }\n\n public registerLink(data: IOscLinkData): number {\n const buffer = this._bufferService.buffer;\n\n // Links with no id will only ever be registered a single time\n if (data.id === undefined) {\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryNoId = {\n data,\n id: this._nextId++,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n // Add the line to the link if it already exists\n const castData = data as Required;\n const key = this._getEntryIdKey(castData);\n const match = this._entriesWithId.get(key);\n if (match) {\n this.addLineToLink(match.id, buffer.ybase + buffer.y);\n return match.id;\n }\n\n // Create the link\n const marker = buffer.addMarker(buffer.ybase + buffer.y);\n const entry: IOscLinkEntryWithId = {\n id: this._nextId++,\n key: this._getEntryIdKey(castData),\n data: castData,\n lines: [marker]\n };\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n this._entriesWithId.set(entry.key, entry);\n this._dataByLinkId.set(entry.id, entry);\n return entry.id;\n }\n\n public addLineToLink(linkId: number, y: number): void {\n const entry = this._dataByLinkId.get(linkId);\n if (!entry) {\n return;\n }\n if (entry.lines.every(e => e.line !== y)) {\n const marker = this._bufferService.buffer.addMarker(y);\n entry.lines.push(marker);\n marker.onDispose(() => this._removeMarkerFromLink(entry, marker));\n }\n }\n\n public getLinkData(linkId: number): IOscLinkData | undefined {\n return this._dataByLinkId.get(linkId)?.data;\n }\n\n private _getEntryIdKey(linkData: Required): string {\n return `${linkData.id};;${linkData.uri}`;\n }\n\n private _removeMarkerFromLink(entry: IOscLinkEntryNoId | IOscLinkEntryWithId, marker: IMarker): void {\n const index = entry.lines.indexOf(marker);\n if (index === -1) {\n return;\n }\n entry.lines.splice(index, 1);\n if (entry.lines.length === 0) {\n if (entry.data.id !== undefined) {\n this._entriesWithId.delete((entry as IOscLinkEntryWithId).key);\n }\n this._dataByLinkId.delete(entry.id);\n }\n }\n}\n\ninterface IOscLinkEntry {\n data: T;\n id: number;\n lines: IMarker[];\n}\n\ninterface IOscLinkEntryNoId extends IOscLinkEntry {\n}\n\ninterface IOscLinkEntryWithId extends IOscLinkEntry> {\n key: string;\n}\n", "/**\n * Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';\nimport { InstantiationService } from './services/InstantiationService';\nimport { LogService } from './services/LogService';\nimport { BufferService, BufferServiceConstants } from './services/BufferService';\nimport { OptionsService } from './services/OptionsService';\nimport { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';\nimport { IAttributeData, IBufferSet } from './buffer/Types';\nimport { CoreService } from './services/CoreService';\nimport { MouseStateService } from './services/MouseStateService';\nimport { UnicodeV6 } from './input/UnicodeV6';\nimport { UnicodeService } from './services/UnicodeService';\nimport { CharsetService } from './services/CharsetService';\nimport { updateWindowsModeWrappedState } from './WindowsMode';\nimport { IFunctionIdentifier } from './parser/Types';\nimport { InputHandler } from './InputHandler';\nimport { WriteBuffer } from './input/WriteBuffer';\nimport { OscLinkService } from './services/OscLinkService';\nimport { Emitter, EventUtils, type IEvent } from './Event';\nimport { Disposable, MutableDisposable, toDisposable } from './Lifecycle';\n\n// Only trigger this warning a single time per session\nlet hasWriteSyncWarnHappened = false;\n\nexport interface ICoreTerminal {\n mouseStateService: IMouseStateService;\n coreService: ICoreService;\n optionsService: IOptionsService;\n unicodeService: IUnicodeService;\n buffers: IBufferSet;\n options: Required;\n registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable;\n registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable;\n registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable;\n registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable;\n registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable;\n}\n\nexport abstract class CoreTerminal extends Disposable implements ICoreTerminal {\n protected readonly _instantiationService: IInstantiationService;\n protected readonly _bufferService: IBufferService;\n protected readonly _logService: ILogService;\n protected readonly _charsetService: ICharsetService;\n protected readonly _oscLinkService: IOscLinkService;\n\n public readonly mouseStateService: IMouseStateService;\n public readonly coreService: ICoreService;\n public readonly unicodeService: IUnicodeService;\n public readonly optionsService: IOptionsService;\n\n protected _inputHandler: InputHandler;\n private _writeBuffer: WriteBuffer;\n private _windowsWrappingHeuristics = this._register(new MutableDisposable());\n\n private readonly _onBinary = this._register(new Emitter());\n public readonly onBinary = this._onBinary.event;\n private readonly _onData = this._register(new Emitter());\n public readonly onData = this._onData.event;\n protected _onLineFeed = this._register(new Emitter());\n public readonly onLineFeed = this._onLineFeed.event;\n protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());\n public readonly onRender = this._onRender.event;\n private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());\n public readonly onResize = this._onResize.event;\n protected readonly _onWriteParsed = this._register(new Emitter());\n public readonly onWriteParsed = this._onWriteParsed.event;\n\n /**\n * Internally we track the source of the scroll but this is meaningless outside the library so\n * it's filtered out.\n */\n protected _onScrollApi?: Emitter;\n protected _onScroll = this._register(new Emitter());\n public get onScroll(): IEvent {\n if (!this._onScrollApi) {\n this._onScrollApi = this._register(new Emitter());\n this._onScroll.event(ev => {\n this._onScrollApi?.fire(ev.position);\n });\n }\n return this._onScrollApi.event;\n }\n\n public get cols(): number { return this._bufferService.cols; }\n public get rows(): number { return this._bufferService.rows; }\n public get buffers(): IBufferSet { return this._bufferService.buffers; }\n public get options(): Required { return this.optionsService.options; }\n public set options(options: ITerminalOptions) {\n for (const key in options) {\n this.optionsService.options[key] = options[key];\n }\n }\n\n constructor(\n options: Partial\n ) {\n super();\n\n // Setup and initialize services\n this._instantiationService = new InstantiationService();\n this.optionsService = this._register(new OptionsService(options));\n this._instantiationService.setService(IOptionsService, this.optionsService);\n this._logService = this._register(this._instantiationService.createInstance(LogService));\n this._instantiationService.setService(ILogService, this._logService);\n this._bufferService = this._register(this._instantiationService.createInstance(BufferService));\n this._instantiationService.setService(IBufferService, this._bufferService);\n this.coreService = this._register(this._instantiationService.createInstance(CoreService));\n this._instantiationService.setService(ICoreService, this.coreService);\n this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));\n this._instantiationService.setService(IMouseStateService, this.mouseStateService);\n this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));\n this.unicodeService.register(new UnicodeV6());\n this._instantiationService.setService(IUnicodeService, this.unicodeService);\n this._charsetService = this._instantiationService.createInstance(CharsetService);\n this._instantiationService.setService(ICharsetService, this._charsetService);\n this._oscLinkService = this._instantiationService.createInstance(OscLinkService);\n this._instantiationService.setService(IOscLinkService, this._oscLinkService);\n\n\n // Register input handler and handle/forward events\n this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));\n this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));\n\n // Setup listeners\n this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));\n this._register(EventUtils.forward(this.coreService.onData, this._onData));\n this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));\n this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));\n this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));\n this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));\n this._register(this._bufferService.onScroll(() => {\n this._onScroll.fire({ position: this._bufferService.buffer.ydisp });\n this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop, this._bufferService.buffer.scrollBottom);\n }));\n // Setup WriteBuffer\n this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));\n this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));\n }\n\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._writeBuffer.write(data, callback);\n }\n\n /**\n * Write data to terminal synchonously.\n *\n * This method is unreliable with async parser handlers, thus should not\n * be used anymore. If you need blocking semantics on data input consider\n * `write` with a callback instead.\n *\n * @deprecated Unreliable, will be removed soon.\n */\n public writeSync(data: string | Uint8Array, maxSubsequentCalls?: number): void {\n if (this._logService.logLevel <= LogLevelEnum.WARN && !hasWriteSyncWarnHappened) {\n this._logService.warn('writeSync is unreliable and will be removed soon.');\n hasWriteSyncWarnHappened = true;\n }\n this._writeBuffer.writeSync(data, maxSubsequentCalls);\n }\n\n public input(data: string, wasUserInput: boolean = true): void {\n this.coreService.triggerDataEvent(data, wasUserInput);\n }\n\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n x = Math.max(x, BufferServiceConstants.MINIMUM_COLS);\n y = Math.max(y, BufferServiceConstants.MINIMUM_ROWS);\n\n // Flush pending writes before resize to avoid race conditions where async\n // writes are processed with incorrect dimensions\n this._writeBuffer.flushSync();\n\n this._bufferService.resize(x, y);\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param eraseAttr The attribute data to use the for blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {\n this._bufferService.scroll(eraseAttr, isWrapped);\n }\n\n /**\n * Scroll the display of the terminal\n * @param disp The number of lines to scroll down (negative scroll up).\n * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used to avoid\n * unwanted events being handled by the viewport when the event was triggered from the viewport\n * originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n this._bufferService.scrollLines(disp, suppressScrollEvent);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n /** Add handler for ESC escape sequence. See xterm.d.ts for details. */\n public registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable {\n return this._inputHandler.registerEscHandler(id, callback);\n }\n\n /** Add handler for DCS escape sequence. See xterm.d.ts for details. */\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerDcsHandler(id, callback);\n }\n\n /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean | Promise): IDisposable {\n return this._inputHandler.registerCsiHandler(id, callback);\n }\n\n /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerOscHandler(ident, callback);\n }\n\n /** Add handler for APC escape sequence. See xterm.d.ts for details. */\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._inputHandler.registerApcHandler(id, callback);\n }\n\n protected _setup(): void {\n this._handleWindowsPtyOptionChange();\n }\n\n public reset(): void {\n this._inputHandler.reset();\n this._bufferService.reset();\n this._charsetService.reset();\n this.coreService.reset();\n this.mouseStateService.reset();\n }\n\n\n private _handleWindowsPtyOptionChange(): void {\n let value = false;\n const windowsPty = this.optionsService.rawOptions.windowsPty;\n if (windowsPty && windowsPty.backend !== undefined && windowsPty.buildNumber !== undefined) {\n value = !!(windowsPty.backend === 'conpty' && windowsPty.buildNumber < 21376);\n }\n if (value) {\n this._enableWindowsWrappingHeuristics();\n } else {\n this._windowsWrappingHeuristics.clear();\n }\n }\n\n protected _enableWindowsWrappingHeuristics(): void {\n if (!this._windowsWrappingHeuristics.value) {\n const disposables: IDisposable[] = [];\n disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));\n disposables.push(this.registerCsiHandler({ final: 'H' }, () => {\n updateWindowsModeWrappedState(this._bufferService);\n return false;\n }));\n this._windowsWrappingHeuristics.value = toDisposable(() => {\n for (const d of disposables) {\n d.dispose();\n }\n });\n }\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IdleTaskQueue } from './TaskQueue';\nimport type { ILogService } from './services/Services';\n\n// Work variables to avoid garbage collection.\nlet i = 0;\n\n/**\n * A generic list that is maintained in sorted order and allows values with duplicate keys. Deferred\n * batch insertion and deletion is used to significantly reduce the time it takes to insert and\n * delete a large amount of items in succession. This list is based on binary search and as such\n * locating a key will take O(log n) amortized, this includes the by key iterator.\n */\nexport class SortedList {\n private _array: T[] = [];\n\n private readonly _insertedValues: T[] = [];\n private readonly _flushInsertedTask: InstanceType;\n private _isFlushingInserted = false;\n\n private readonly _deletedIndices: number[] = [];\n private readonly _flushDeletedTask: InstanceType;\n private _isFlushingDeleted = false;\n\n constructor(\n private readonly _getKey: (value: T) => number,\n logService: ILogService\n ) {\n this._flushInsertedTask = new IdleTaskQueue(logService);\n this._flushDeletedTask = new IdleTaskQueue(logService);\n }\n\n public clear(): void {\n this._array.length = 0;\n this._insertedValues.length = 0;\n this._flushInsertedTask.clear();\n this._isFlushingInserted = false;\n this._deletedIndices.length = 0;\n this._flushDeletedTask.clear();\n this._isFlushingDeleted = false;\n }\n\n public insert(value: T): void {\n this._flushCleanupDeleted();\n if (this._insertedValues.length === 0) {\n this._flushInsertedTask.enqueue(() => this._flushInserted());\n }\n this._insertedValues.push(value);\n }\n\n private _flushInserted(): void {\n const sortedAddedValues = this._insertedValues.sort((a, b) => this._getKey(a) - this._getKey(b));\n let sortedAddedValuesIndex = 0;\n let arrayIndex = 0;\n\n const newArray = new Array(this._array.length + this._insertedValues.length);\n\n for (let newArrayIndex = 0; newArrayIndex < newArray.length; newArrayIndex++) {\n if (arrayIndex >= this._array.length || this._getKey(sortedAddedValues[sortedAddedValuesIndex]) <= this._getKey(this._array[arrayIndex])) {\n newArray[newArrayIndex] = sortedAddedValues[sortedAddedValuesIndex];\n sortedAddedValuesIndex++;\n } else {\n newArray[newArrayIndex] = this._array[arrayIndex++];\n }\n }\n\n this._array = newArray;\n this._insertedValues.length = 0;\n }\n\n private _flushCleanupInserted(): void {\n if (!this._isFlushingInserted && this._insertedValues.length > 0) {\n this._flushInsertedTask.flush();\n }\n }\n\n public delete(value: T): boolean {\n this._flushCleanupInserted();\n if (this._array.length === 0) {\n return false;\n }\n const key = this._getKey(value);\n if (key === undefined) {\n return false;\n }\n if (this._deleteAtKey(value, key)) {\n return true;\n }\n // A pending deletion whose key mutated after `delete()` (disposing a marker\n // resets `line` to -1, and `line` is the sort key) leaves `_array` out of\n // order, so the binary search above can miss a value that is present.\n // Compacting those entries out restores the order; retry before reporting\n // the value absent, else its `onDecorationRemoved` never fires and the\n // decoration paints forever. Miss path only, so the common bulk delete\n // keeps its O(log n) search and deferred-compaction batching.\n if (this._deletedIndices.length === 0) {\n return false;\n }\n this._flushCleanupDeleted();\n return this._deleteAtKey(value, key);\n }\n\n private _deleteAtKey(value: T, key: number): boolean {\n i = this._search(key);\n if (i === -1) {\n return false;\n }\n if (this._getKey(this._array[i]) !== key) {\n return false;\n }\n do {\n if (this._array[i] === value) {\n if (this._deletedIndices.length === 0) {\n this._flushDeletedTask.enqueue(() => this._flushDeleted());\n }\n this._deletedIndices.push(i);\n return true;\n }\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n return false;\n }\n\n private _flushDeleted(): void {\n this._isFlushingDeleted = true;\n const sortedDeletedIndices = this._deletedIndices.sort((a, b) => a - b);\n let sortedDeletedIndicesIndex = 0;\n const newArray = new Array(this._array.length - sortedDeletedIndices.length);\n let newArrayIndex = 0;\n for (let i = 0; i < this._array.length; i++) {\n if (sortedDeletedIndices[sortedDeletedIndicesIndex] === i) {\n sortedDeletedIndicesIndex++;\n } else {\n newArray[newArrayIndex++] = this._array[i];\n }\n }\n this._array = newArray;\n this._deletedIndices.length = 0;\n this._isFlushingDeleted = false;\n }\n\n private _flushCleanupDeleted(): void {\n if (!this._isFlushingDeleted && this._deletedIndices.length > 0) {\n this._flushDeletedTask.flush();\n }\n }\n\n public *getKeyIterator(key: number): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n yield this._array[i];\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public forEachByKey(key: number, callback: (value: T) => void): void {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n if (this._array.length === 0) {\n return;\n }\n i = this._search(key);\n if (i < 0 || i >= this._array.length) {\n return;\n }\n if (this._getKey(this._array[i]) !== key) {\n return;\n }\n do {\n callback(this._array[i]);\n } while (++i < this._array.length && this._getKey(this._array[i]) === key);\n }\n\n public values(): IterableIterator {\n this._flushCleanupInserted();\n this._flushCleanupDeleted();\n // Duplicate the array to avoid issues when _array changes while iterating\n return [...this._array].values();\n }\n\n private _search(key: number): number {\n let min = 0;\n let max = this._array.length - 1;\n while (max >= min) {\n let mid = (min + max) >> 1;\n const midKey = this._getKey(this._array[mid]);\n if (midKey > key) {\n max = mid - 1;\n } else if (midKey < key) {\n min = mid + 1;\n } else {\n // key in list, walk to lowest duplicate\n while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {\n mid--;\n }\n return mid;\n }\n }\n // key not in list\n // still return closest min (also used as insert position)\n return min;\n }\n}\n", "/**\n * Copyright (c) 2022 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ICircularList, IDeleteEvent, IInsertEvent } from '../CircularList';\nimport { MicrotaskTimer } from '../Async';\nimport { css } from '../Color';\nimport { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../Lifecycle';\nimport { IBufferService, IDecorationService, IInternalDecoration, ILogService } from './Services';\nimport { SortedList } from '../SortedList';\nimport { IColor } from '../Types';\nimport { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm';\nimport { Emitter } from '../Event';\n\n// Work variables to avoid garbage collection\nlet $xmin = 0;\nlet $xmax = 0;\n\nexport class DecorationService extends Disposable implements IDecorationService {\n public serviceBrand: any;\n\n /**\n * A list of all decorations, sorted by the marker's line value. This relies on the fact that\n * while marker line values do change, they should all change by the same amount so this should\n * never become out of order.\n */\n private readonly _decorations: SortedList;\n\n private readonly _lineCache = this._register(new DecorationLineCache());\n\n private readonly _onDecorationRegistered = this._register(new Emitter());\n public readonly onDecorationRegistered = this._onDecorationRegistered.event;\n private readonly _onDecorationRemoved = this._register(new Emitter());\n public readonly onDecorationRemoved = this._onDecorationRemoved.event;\n\n public get decorations(): IterableIterator { return this._decorations.values(); }\n\n constructor(\n @ILogService private readonly _logService: ILogService,\n @IBufferService private readonly _bufferService: IBufferService\n ) {\n super();\n\n this._decorations = new SortedList(e => e?.marker.line, this._logService);\n\n this._register(toDisposable(() => this.reset()));\n this._register(this._bufferService.buffers.onBufferActivate(() => {\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }));\n this._lineCache.attachToBufferLines(this._bufferService.buffer.lines);\n }\n\n public registerDecoration(options: IDecorationOptions): IDecoration | undefined {\n if (options.marker.isDisposed) {\n return undefined;\n }\n const decoration = new Decoration(options);\n if (decoration) {\n const markerDispose = decoration.marker.onDispose(() => decoration.dispose());\n const listener = decoration.onDispose(() => {\n listener.dispose();\n if (decoration) {\n if (this._decorations.delete(decoration)) {\n this._lineCache.remove(decoration);\n this._onDecorationRemoved.fire(decoration);\n }\n markerDispose.dispose();\n }\n });\n this._decorations.insert(decoration);\n this._lineCache.add(decoration);\n this._onDecorationRegistered.fire(decoration);\n }\n return decoration;\n }\n\n public reset(): void {\n for (const d of this._decorations.values()) {\n d.dispose();\n }\n this._decorations.clear();\n this._lineCache.clear();\n }\n\n public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n yield d;\n }\n }\n }\n\n public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void {\n const bucket = this._lineCache.getDecorationsOnLine(line);\n if (!bucket) {\n return;\n }\n for (const d of bucket) {\n $xmin = d.options.x ?? 0;\n $xmax = $xmin + (d.options.width ?? 1);\n if (x >= $xmin && x < $xmax && (!layer || (d.options.layer ?? 'bottom') === layer)) {\n callback(d);\n }\n }\n }\n}\n\n/**\n * Per-logical-line index of decorations for fast cell lookup.\n *\n * Keys are marker.line coordinates (logical buffer lines), not CircularList ring slots.\n * Multi-line decorations appear in every line bucket they span. The index is kept aligned\n * with marker.line updates via buffer line trim/insert/delete events.\n */\nexport class DecorationLineCache extends Disposable {\n private readonly _decorationsByLine: Map = new Map();\n private readonly _decorations = new Set();\n private readonly _bufferLineListeners = this._register(new MutableDisposable());\n private readonly _lineIndexSyncTimer = this._register(new MicrotaskTimer());\n private _lineIndexSyncCallbacks: (() => void)[] = [];\n\n public clear(): void {\n this._lineIndexSyncCallbacks.length = 0;\n this._lineIndexSyncTimer.cancel();\n this._decorationsByLine.clear();\n this._decorations.clear();\n }\n\n public add(decoration: IInternalDecoration): void {\n this._decorations.add(decoration);\n this._addToLineBuckets(decoration);\n }\n\n public remove(decoration: IInternalDecoration): void {\n this._decorations.delete(decoration);\n this._removeFromLineBuckets(decoration);\n }\n\n public getDecorationsOnLine(line: number): ReadonlyArray | undefined {\n return this._decorationsByLine.get(line);\n }\n\n public attachToBufferLines(lines: ICircularList): void {\n const store = new DisposableStore();\n this._bufferLineListeners.value = store;\n store.add(lines.onTrim(amount => this._handleBufferLinesTrim(amount)));\n store.add(lines.onInsert(event => this._handleBufferLinesInsert(event)));\n store.add(lines.onDelete(event => this._handleBufferLinesDelete(event)));\n }\n\n private _getDecorationHeight(decoration: IInternalDecoration): number {\n return decoration.options.height ?? 1;\n }\n\n private _addToLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration.marker.line;\n if (start < 0) {\n return;\n }\n decoration._indexedStartLine = start;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n let bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n bucket = [];\n this._decorationsByLine.set(line, bucket);\n }\n bucket.push(decoration);\n }\n }\n\n private _removeFromLineBuckets(decoration: IInternalDecoration): void {\n const start = decoration._indexedStartLine;\n const height = this._getDecorationHeight(decoration);\n for (let line = start; line < start + height; line++) {\n const bucket = this._decorationsByLine.get(line);\n if (!bucket) {\n continue;\n }\n const index = bucket.indexOf(decoration);\n if (index !== -1) {\n bucket.splice(index, 1);\n }\n if (bucket.length === 0) {\n this._decorationsByLine.delete(line);\n }\n }\n }\n\n private _reindexDecoration(decoration: IInternalDecoration): void {\n this._removeFromLineBuckets(decoration);\n if (!decoration.marker.isDisposed && decoration.marker.line >= 0) {\n this._addToLineBuckets(decoration);\n }\n }\n\n /** Re-index after marker line updates (buffer listeners may run before markers). */\n private _scheduleLineIndexSync(callback: () => void): void {\n this._lineIndexSyncCallbacks.push(callback);\n this._lineIndexSyncTimer.set(() => {\n const callbacks = this._lineIndexSyncCallbacks;\n this._lineIndexSyncCallbacks = [];\n for (const cb of callbacks) {\n cb();\n }\n });\n }\n\n private _handleBufferLinesTrim(amount: number): void {\n if (amount <= 0) {\n return;\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line - amount;\n if (newLine < 0) {\n continue;\n }\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (!d.marker.isDisposed) {\n d._indexedStartLine -= amount;\n }\n }\n }\n\n private _handleBufferLinesInsert(event: IInsertEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesInsert(event));\n }\n\n private _handleBufferLinesDelete(event: IDeleteEvent): void {\n this._scheduleLineIndexSync(() => this._applyBufferLinesDelete(event));\n }\n\n private _mergeLineBucket(newMap: Map, line: number, bucket: IInternalDecoration[]): void {\n const existing = newMap.get(line);\n if (existing) {\n for (let i = 0, len = bucket.length; i < len; i++) {\n existing.push(bucket[i]);\n }\n } else {\n newMap.set(line, bucket.slice());\n }\n }\n\n /**\n * Shift indexed line keys and sync start lines. O(unique indexed lines), not O(decoration count).\n * Decorations that span the insert point are re-indexed individually (rare vs single-line hits).\n */\n private _applyBufferLinesInsert(event: IInsertEvent): void {\n const { index, amount } = event;\n const spanCrossers: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n if (start < index && start + this._getDecorationHeight(d) > index) {\n spanCrossers.push(d);\n this._removeFromLineBuckets(d);\n }\n }\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n const newLine = line >= index ? line + amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n if (d._indexedStartLine >= index) {\n d._indexedStartLine = d.marker.line;\n }\n }\n for (const d of spanCrossers) {\n this._addToLineBuckets(d);\n }\n }\n\n /**\n * Drop deleted line keys, shift keys below, sync start lines. Full re-index only when a\n * multi-line decoration spans across the deleted range but survives.\n */\n private _applyBufferLinesDelete(event: IDeleteEvent): void {\n const deleteEnd = event.index + event.amount;\n const newMap = new Map();\n for (const [line, bucket] of this._decorationsByLine) {\n if (line >= event.index && line < deleteEnd) {\n continue;\n }\n const newLine = line >= deleteEnd ? line - event.amount : line;\n this._mergeLineBucket(newMap, newLine, bucket);\n }\n this._decorationsByLine.clear();\n for (const [line, bucket] of newMap) {\n this._decorationsByLine.set(line, bucket);\n }\n const toReindex: IInternalDecoration[] = [];\n for (const d of this._decorations) {\n if (d.marker.isDisposed) {\n continue;\n }\n const start = d._indexedStartLine;\n const height = this._getDecorationHeight(d);\n if (start >= deleteEnd) {\n d._indexedStartLine = d.marker.line;\n } else if (start < event.index && start + height > deleteEnd) {\n toReindex.push(d);\n }\n }\n for (const d of toReindex) {\n this._reindexDecoration(d);\n }\n }\n}\n\nclass Decoration extends DisposableStore implements IInternalDecoration {\n public readonly marker: IMarker;\n public element: HTMLElement | undefined;\n\n /** Start line used for line-index removal when marker.line is cleared on dispose. */\n public _indexedStartLine: number;\n\n public readonly onRenderEmitter = this.add(new Emitter());\n public readonly onRender = this.onRenderEmitter.event;\n private readonly _onDispose = this.add(new Emitter());\n public readonly onDispose = this._onDispose.event;\n\n private _cachedBg: IColor | undefined | null = null;\n public get backgroundColorRGB(): IColor | undefined {\n if (this._cachedBg === null) {\n if (this.options.backgroundColor) {\n this._cachedBg = css.toColor(this.options.backgroundColor);\n } else {\n this._cachedBg = undefined;\n }\n }\n return this._cachedBg;\n }\n\n private _cachedFg: IColor | undefined | null = null;\n public get foregroundColorRGB(): IColor | undefined {\n if (this._cachedFg === null) {\n if (this.options.foregroundColor) {\n this._cachedFg = css.toColor(this.options.foregroundColor);\n } else {\n this._cachedFg = undefined;\n }\n }\n return this._cachedFg;\n }\n\n constructor(\n public readonly options: IDecorationOptions\n ) {\n super();\n this.marker = options.marker;\n this._indexedStartLine = options.marker.line;\n if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {\n this.options.overviewRulerOptions.position = 'full';\n }\n }\n\n public override dispose(): void {\n this._onDispose.fire();\n super.dispose();\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderDebouncer } from './Types';\n\nconst RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second\n\n/**\n * Debounces calls to update screen readers to update at most once configurable interval of time.\n */\nexport class TimeBasedDebouncer implements IRenderDebouncer {\n private _rowStart: number | undefined;\n private _rowEnd: number | undefined;\n private _rowCount: number | undefined;\n\n // The last moment that the Terminal was refreshed at\n private _lastRefreshMs = 0;\n // Whether a trailing refresh should be triggered due to a refresh request that was throttled\n private _additionalRefreshRequested = false;\n\n private _refreshTimeoutID: number | undefined;\n\n constructor(\n private _renderCallback: (start: number, end: number) => void,\n private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS\n ) {\n }\n\n public dispose(): void {\n if (this._refreshTimeoutID) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n }\n this._additionalRefreshRequested = false;\n }\n\n public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {\n this._rowCount = rowCount;\n // Get the min/max row start/end for the arg values\n rowStart = rowStart ?? 0;\n rowEnd = rowEnd ?? this._rowCount - 1;\n // Set the properties to the updated values\n this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n // Only refresh if the time since last refresh is above a threshold, otherwise wait for\n // enough time to pass before refreshing again.\n const refreshRequestTime: number = performance.now();\n if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {\n // Enough time has elapsed since the last refresh; refresh immediately\n if (this._refreshTimeoutID !== undefined) {\n clearTimeout(this._refreshTimeoutID);\n this._refreshTimeoutID = undefined;\n this._additionalRefreshRequested = false;\n }\n this._lastRefreshMs = refreshRequestTime;\n this._innerRefresh();\n } else if (!this._additionalRefreshRequested) {\n // This is the first additional request throttled; set up trailing refresh\n const elapsed = refreshRequestTime - this._lastRefreshMs;\n const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;\n this._additionalRefreshRequested = true;\n\n this._refreshTimeoutID = window.setTimeout(() => {\n this._lastRefreshMs = performance.now();\n this._innerRefresh();\n this._additionalRefreshRequested = false;\n this._refreshTimeoutID = undefined; // No longer need to clear the timeout\n }, waitPeriodBeforeTrailingRefresh);\n }\n }\n\n private _innerRefresh(): void {\n // Make sure values are set\n if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n return;\n }\n\n // Clamp values\n const start = Math.max(this._rowStart, 0);\n const end = Math.min(this._rowEnd, this._rowCount - 1);\n\n // Reset debouncer (this happens before render callback as the render could trigger it again)\n this._rowStart = undefined;\n this._rowEnd = undefined;\n\n // Run render callback\n this._renderCallback(start, end);\n }\n}\n\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './LocalizableStrings';\nimport { ITerminal, IRenderDebouncer } from './Types';\nimport { TimeBasedDebouncer } from './TimeBasedDebouncer';\nimport { Disposable, toDisposable } from '../common/Lifecycle';\nimport { ICoreBrowserService, IRenderService } from './services/Services';\nimport { IBuffer } from '../common/buffer/Types';\nimport { IInstantiationService } from '../common/services/Services';\nimport { addDisposableListener } from './Dom';\n\nconst enum Constants {\n MAX_ROWS_TO_READ = 20\n}\n\nconst enum BoundaryPosition {\n TOP,\n BOTTOM\n}\n\n// Turn this on to unhide the accessibility tree and display it under\n// (instead of overlapping with) the terminal.\nconst DEBUG = false;\n\nexport class AccessibilityManager extends Disposable {\n private _debugRootContainer: HTMLElement | undefined;\n private _accessibilityContainer: HTMLElement;\n\n private _rowContainer: HTMLElement;\n private _rowElements: HTMLElement[];\n private _rowColumns: WeakMap = new WeakMap();\n\n private _liveRegion: HTMLElement;\n private _liveRegionLineCount: number = 0;\n private _liveRegionDebouncer: IRenderDebouncer;\n\n private _topBoundaryFocusListener: (e: FocusEvent) => void;\n private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n /**\n * This queue has a character pushed to it for keys that are pressed, if the\n * next character added to the terminal is equal to the key char then it is\n * not announced (added to live region) because it has already been announced\n * by the textarea event (which cannot be canceled). There are some race\n * condition cases if there is typing while data is streaming, but this covers\n * the main case of typing into the prompt and inputting the answer to a\n * question (Y/N, etc.).\n */\n private _charsToConsume: string[] = [];\n\n private _charsToAnnounce: string = '';\n\n constructor(\n private readonly _terminal: ITerminal,\n @IInstantiationService instantiationService: IInstantiationService,\n @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,\n @IRenderService private readonly _renderService: IRenderService\n ) {\n super();\n const doc = this._coreBrowserService.mainDocument;\n this._accessibilityContainer = doc.createElement('div');\n this._accessibilityContainer.classList.add('xterm-accessibility');\n\n this._rowContainer = doc.createElement('div');\n this._rowContainer.setAttribute('role', 'list');\n this._rowContainer.classList.add('xterm-accessibility-tree');\n this._rowElements = [];\n for (let i = 0; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n\n this._topBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.TOP);\n this._bottomBoundaryFocusListener = e => this._handleBoundaryFocus(e, BoundaryPosition.BOTTOM);\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._accessibilityContainer.appendChild(this._rowContainer);\n\n this._liveRegion = doc.createElement('div');\n this._liveRegion.classList.add('live-region');\n this._liveRegion.setAttribute('aria-live', 'assertive');\n this._accessibilityContainer.appendChild(this._liveRegion);\n this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));\n\n if (!this._terminal.element) {\n throw new Error('Cannot enable accessibility before Terminal.open');\n }\n\n if (DEBUG) {\n this._accessibilityContainer.classList.add('debug');\n this._rowContainer.classList.add('debug');\n\n // Use a `
` container so that the css will still apply.\n this._debugRootContainer = doc.createElement('div');\n this._debugRootContainer.classList.add('xterm');\n\n this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));\n this._debugRootContainer.appendChild(this._accessibilityContainer);\n this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));\n\n this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);\n } else {\n this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);\n }\n\n this._register(this._terminal.onResize(e => this._handleResize(e.rows)));\n this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n this._register(this._terminal.onScroll(() => this._refreshRows()));\n // Line feed is an issue as the prompt won't be read out after a command is run\n this._register(this._terminal.onA11yChar(char => this._handleChar(char)));\n this._register(this._terminal.onLineFeed(() => this._handleChar('\\n')));\n this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));\n this._register(this._terminal.onKey(e => this._handleKey(e.key)));\n this._register(this._terminal.onBlur(() => this._clearLiveRegion()));\n this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));\n this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));\n this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));\n\n this._refreshRowsDimensions();\n this._refreshRows();\n this._register(toDisposable(() => {\n if (DEBUG) {\n this._debugRootContainer!.remove();\n } else {\n this._accessibilityContainer.remove();\n }\n this._rowElements.length = 0;\n }));\n }\n\n private _handleTab(spaceCount: number): void {\n for (let i = 0; i < spaceCount; i++) {\n this._handleChar(' ');\n }\n }\n\n private _handleChar(char: string): void {\n if (this._liveRegionLineCount < Constants.MAX_ROWS_TO_READ + 1) {\n if (this._charsToConsume.length > 0) {\n // Have the screen reader ignore the char if it was just input\n const shiftedChar = this._charsToConsume.shift();\n if (shiftedChar !== char) {\n this._charsToAnnounce += char;\n }\n } else {\n this._charsToAnnounce += char;\n }\n\n if (char === '\\n') {\n this._liveRegionLineCount++;\n if (this._liveRegionLineCount === Constants.MAX_ROWS_TO_READ + 1) {\n this._liveRegion.textContent = Strings.tooMuchOutput.get();\n }\n }\n }\n }\n\n private _clearLiveRegion(): void {\n this._liveRegion.textContent = '';\n this._liveRegionLineCount = 0;\n }\n\n private _handleKey(keyChar: string): void {\n this._clearLiveRegion();\n // Only add the char if there is no control character.\n if (!/\\p{Control}/u.test(keyChar)) {\n this._charsToConsume.push(keyChar);\n }\n }\n\n private _refreshRows(start?: number, end?: number): void {\n this._liveRegionDebouncer.refresh(start, end, this._terminal.rows);\n }\n\n private _renderRows(start: number, end: number): void {\n const buffer: IBuffer = this._terminal.buffer;\n const setSize = buffer.lines.length.toString();\n for (let i = start; i <= end; i++) {\n const line = buffer.lines.get(buffer.ydisp + i);\n const columns: number[] = [];\n const lineData = line?.translateToString(true, undefined, undefined, columns) || '';\n const posInSet = (buffer.ydisp + i + 1).toString();\n const element = this._rowElements[i];\n if (element) {\n if (lineData.length === 0) {\n element.textContent = '\\u00a0';\n this._rowColumns.set(element, [0, 1]);\n } else {\n element.textContent = lineData;\n this._rowColumns.set(element, columns);\n }\n element.setAttribute('aria-posinset', posInSet);\n element.setAttribute('aria-setsize', setSize);\n this._alignRowWidth(element);\n }\n }\n this._announceCharacters();\n }\n\n private _announceCharacters(): void {\n if (this._charsToAnnounce.length === 0) {\n return;\n }\n if (this._liveRegion.textContent === Strings.tooMuchOutput.get()) {\n this._clearLiveRegion();\n }\n this._liveRegion.textContent += this._charsToAnnounce;\n this._charsToAnnounce = '';\n }\n\n private _handleBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n const boundaryElement = e.target as HTMLElement;\n const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n // Don't scroll if the buffer top has reached the end in that direction\n const posInSet = boundaryElement.getAttribute('aria-posinset');\n const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n if (posInSet === lastRowPos) {\n return;\n }\n\n // Don't scroll when the last focused item was not the second row (focus is going the other\n // direction)\n if (e.relatedTarget !== beforeBoundaryElement) {\n return;\n }\n\n // Remove old boundary element from array\n let topBoundaryElement: HTMLElement;\n let bottomBoundaryElement: HTMLElement;\n if (position === BoundaryPosition.TOP) {\n topBoundaryElement = boundaryElement;\n bottomBoundaryElement = this._rowElements.pop()!;\n this._rowContainer.removeChild(bottomBoundaryElement);\n } else {\n topBoundaryElement = this._rowElements.shift()!;\n bottomBoundaryElement = boundaryElement;\n this._rowContainer.removeChild(topBoundaryElement);\n }\n\n // Remove listeners from old boundary elements\n topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Add new element to array/DOM\n if (position === BoundaryPosition.TOP) {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.unshift(newElement);\n this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n } else {\n const newElement = this._createAccessibilityTreeNode();\n this._rowElements.push(newElement);\n this._rowContainer.appendChild(newElement);\n }\n\n // Add listeners to new boundary elements\n this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Scroll up\n this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n // Focus new boundary before element\n this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n // Prevent the standard behavior\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n\n private _handleSelectionChange(): void {\n if (this._rowElements.length === 0) {\n return;\n }\n\n const selection = this._coreBrowserService.mainDocument.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.isCollapsed) {\n // Only do something when the anchorNode is inside the row container. This\n // behavior mirrors what we do with mouse --- if the mouse clicks\n // somewhere outside of the terminal, we don't clear the selection.\n if (this._rowContainer.contains(selection.anchorNode)) {\n this._terminal.clearSelection();\n }\n return;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n console.error('anchorNode and/or focusNode are null');\n return;\n }\n\n // Sort the two selection points in document order.\n let begin = { node: selection.anchorNode, offset: selection.anchorOffset };\n let end = { node: selection.focusNode, offset: selection.focusOffset };\n if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {\n [begin, end] = [end, begin];\n }\n\n // Clamp begin/end to the inside of the row container.\n if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {\n begin = { node: this._rowElements[0].childNodes[0], offset: 0 };\n }\n if (!this._rowContainer.contains(begin.node)) {\n // This happens when `begin` is below the last row.\n return;\n }\n const lastRowElement = this._rowElements.slice(-1)[0];\n if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {\n end = {\n node: lastRowElement,\n offset: lastRowElement.textContent?.length ?? 0\n };\n }\n if (!this._rowContainer.contains(end.node)) {\n // This happens when `end` is above the first row.\n return;\n }\n\n const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {\n // `node` is either the row element or the Text node inside it.\n const rowElement: any = node instanceof Text ? node.parentNode : node;\n let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;\n if (isNaN(row)) {\n console.warn('row is invalid. Race condition?');\n return null;\n }\n\n const columns = this._rowColumns.get(rowElement);\n if (!columns) {\n console.warn('columns is null. Race condition?');\n return null;\n }\n\n let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;\n if (column >= this._terminal.cols) {\n ++row;\n column = 0;\n }\n return {\n row,\n column\n };\n };\n\n const beginRowColumn = toRowColumn(begin);\n const endRowColumn = toRowColumn(end);\n\n if (!beginRowColumn || !endRowColumn) {\n return;\n }\n\n if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {\n // This should not happen unless we have some bugs.\n throw new Error('invalid range');\n }\n\n this._terminal.select(\n beginRowColumn.column,\n beginRowColumn.row,\n (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column\n );\n }\n\n private _handleResize(rows: number): void {\n // Remove bottom boundary listener\n this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n // Grow rows as required\n for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n this._rowElements[i] = this._createAccessibilityTreeNode();\n this._rowContainer.appendChild(this._rowElements[i]);\n }\n // Shrink rows as required\n while (this._rowElements.length > rows) {\n this._rowContainer.removeChild(this._rowElements.pop()!);\n }\n\n // Add bottom boundary listener\n this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n this._refreshRowsDimensions();\n }\n\n private _createAccessibilityTreeNode(): HTMLElement {\n const element = this._coreBrowserService.mainDocument.createElement('div');\n element.setAttribute('role', 'listitem');\n element.tabIndex = -1;\n this._refreshRowDimensions(element);\n return element;\n }\n\n private _refreshRowsDimensions(): void {\n if (!this._renderService.dimensions.css.cell.height) {\n return;\n }\n Object.assign(this._accessibilityContainer.style, {\n width: `${this._renderService.dimensions.css.canvas.width}px`,\n fontSize: `${this._terminal.options.fontSize}px`\n });\n if (this._rowElements.length !== this._terminal.rows) {\n this._handleResize(this._terminal.rows);\n }\n for (let i = 0; i < this._terminal.rows; i++) {\n this._refreshRowDimensions(this._rowElements[i]);\n this._alignRowWidth(this._rowElements[i]);\n }\n }\n\n private _refreshRowDimensions(element: HTMLElement): void {\n element.style.height = `${this._renderService.dimensions.css.cell.height}px`;\n }\n\n /**\n * Scale the width of a row so that each of the character is (mostly) aligned\n * with the actual rendering. This will allow the screen reader to draw\n * selection outline at the correct position.\n *\n * On top of using the \"monospace\" font and correct font size, the scaling\n * here is necessary to handle characters that are not covered by the font\n * (e.g. CJK).\n */\n private _alignRowWidth(element: HTMLElement): void {\n element.style.transform = '';\n const width = element.getBoundingClientRect().width;\n const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];\n if (!lastColumn) {\n return;\n }\n const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;\n element.style.transform = `scaleX(${targetWidth / width})`;\n }\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';\nimport { Disposable, dispose, toDisposable } from '../common/Lifecycle';\nimport { IDisposable } from '../common/Types';\nimport { IBufferService } from '../common/services/Services';\nimport { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';\nimport { Emitter } from '../common/Event';\nimport { addDisposableListener } from './Dom';\n\nexport class Linkifier extends Disposable implements ILinkifier2 {\n public get currentLink(): ILinkWithState | undefined { return this._currentLink; }\n protected _currentLink: ILinkWithState | undefined;\n private _mouseDownLink: ILinkWithState | undefined;\n private _lastMouseEvent: MouseEvent | undefined;\n private _linkCacheDisposables: IDisposable[] = [];\n private _lastBufferCell: IBufferCellPosition | undefined;\n private _isMouseOut: boolean = true;\n private _wasResized: boolean = false;\n private _activeProviderReplies: Map | undefined;\n private _activeLine: number = -1;\n\n private readonly _onShowLinkUnderline = this._register(new Emitter());\n public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;\n private readonly _onHideLinkUnderline = this._register(new Emitter());\n public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;\n\n constructor(\n private readonly _element: HTMLElement,\n @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,\n @IRenderService private readonly _renderService: IRenderService,\n @IBufferService private readonly _bufferService: IBufferService,\n @ILinkProviderService private readonly _linkProviderService: ILinkProviderService\n ) {\n super();\n this._register(toDisposable(() => {\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n this._lastMouseEvent = undefined;\n // Clear out link providers as they could easily cause an embedder memory leak\n this._activeProviderReplies?.clear();\n }));\n // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.\n this._register(this._bufferService.onResize(() => {\n this._clearCurrentLink();\n this._wasResized = true;\n }));\n this._register(addDisposableListener(this._element, 'mouseleave', () => {\n this._isMouseOut = true;\n this._clearCurrentLink();\n }));\n this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));\n this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));\n this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));\n }\n\n private _handleMouseMove(event: MouseEvent): void {\n this._lastMouseEvent = event;\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n this._isMouseOut = false;\n\n // Ignore the event if it's an embedder created hover widget\n const composedPath = event.composedPath() as HTMLElement[];\n for (let i = 0; i < composedPath.length; i++) {\n const target = composedPath[i];\n // Hit Terminal.element, break and continue\n if (target.classList.contains('xterm')) {\n break;\n }\n // It's a hover, don't respect hover event\n if (target.classList.contains('xterm-hover')) {\n return;\n }\n }\n\n if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) {\n this._handleHover(position);\n this._lastBufferCell = position;\n }\n }\n\n private _handleHover(position: IBufferCellPosition): void {\n // TODO: This currently does not cache link provider results across wrapped lines, activeLine\n // should be something like `activeRange: {startY, endY}`\n // Check if we need to clear the link\n if (this._activeLine !== position.y || this._wasResized) {\n this._clearCurrentLink();\n this._askForLink(position, false);\n this._wasResized = false;\n return;\n }\n\n // Check the if the link is in the mouse position\n const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position);\n if (!isCurrentLinkInPosition) {\n this._clearCurrentLink();\n this._askForLink(position, true);\n }\n }\n\n private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void {\n if (!this._activeProviderReplies || !useLineCache) {\n this._activeProviderReplies?.forEach(reply => {\n reply?.forEach(linkWithState => {\n if (linkWithState.link.dispose) {\n linkWithState.link.dispose();\n }\n });\n });\n this._activeProviderReplies = new Map();\n this._activeLine = position.y;\n }\n let linkProvided = false;\n\n // There is no link cached, so ask for one\n for (const [i, linkProvider] of this._linkProviderService.linkProviders.entries()) {\n if (useLineCache) {\n const existingReply = this._activeProviderReplies?.get(i);\n // If there isn't a reply, the provider hasn't responded yet.\n\n // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring\n // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably\n // needs promises to get fixed\n if (existingReply) {\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n }\n } else {\n linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => {\n if (this._isMouseOut) {\n return;\n }\n const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link }));\n this._activeProviderReplies?.set(i, linksWithState);\n linkProvided = this._checkLinkProviderResult(i, position, linkProvided);\n\n // If all providers have responded, remove lower priority links that intersect ranges of\n // higher priority links\n if (this._activeProviderReplies?.size === this._linkProviderService.linkProviders.length) {\n this._removeIntersectingLinks(position.y, this._activeProviderReplies);\n }\n });\n }\n }\n }\n\n private _removeIntersectingLinks(y: number, replies: Map): void {\n const occupiedCells = new Set();\n for (let i = 0; i < replies.size; i++) {\n const providerReply = replies.get(i);\n if (!providerReply) {\n continue;\n }\n for (let i = 0; i < providerReply.length; i++) {\n const linkWithState = providerReply[i];\n const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x;\n const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x;\n for (let x = startX; x <= endX; x++) {\n if (occupiedCells.has(x)) {\n providerReply.splice(i--, 1);\n break;\n }\n occupiedCells.add(x);\n }\n }\n }\n }\n\n private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean {\n if (!this._activeProviderReplies) {\n return linkProvided;\n }\n\n const links = this._activeProviderReplies.get(index);\n\n // Check if every provider before this one has come back undefined\n let hasLinkBefore = false;\n for (let j = 0; j < index; j++) {\n if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) {\n hasLinkBefore = true;\n }\n }\n\n // If all providers with higher priority came back undefined, then this provider's link for\n // the position should be used\n if (!hasLinkBefore && links) {\n const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position));\n if (linkAtPosition) {\n linkProvided = true;\n this._handleNewLink(linkAtPosition);\n }\n }\n\n // Check if all the providers have responded\n if (this._activeProviderReplies.size === this._linkProviderService.linkProviders.length && !linkProvided) {\n // Respect the order of the link providers\n for (let j = 0; j < this._activeProviderReplies.size; j++) {\n const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position));\n if (currentLink) {\n linkProvided = true;\n this._handleNewLink(currentLink);\n break;\n }\n }\n }\n\n return linkProvided;\n }\n\n private _handleMouseDown(): void {\n this._mouseDownLink = this._currentLink;\n }\n\n private _handleMouseUp(event: MouseEvent): void {\n if (!this._currentLink) {\n return;\n }\n\n const position = this._positionFromMouseEvent(event, this._element);\n if (!position) {\n return;\n }\n\n if (this._mouseDownLink && linkEquals(this._mouseDownLink.link, this._currentLink.link) && this._linkAtPosition(this._currentLink.link, position)) {\n this._currentLink.link.activate(event, this._currentLink.link.text);\n }\n }\n\n private _clearCurrentLink(startRow?: number, endRow?: number): void {\n if (!this._currentLink || !this._lastMouseEvent) {\n return;\n }\n\n // If we have a start and end row, check that the link is within it\n if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {\n this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);\n this._currentLink = undefined;\n dispose(this._linkCacheDisposables);\n this._linkCacheDisposables.length = 0;\n }\n }\n\n private _handleNewLink(linkWithState: ILinkWithState): void {\n if (!this._lastMouseEvent) {\n return;\n }\n\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n\n if (!position) {\n return;\n }\n\n // Trigger hover if the we have a link at the position\n if (this._linkAtPosition(linkWithState.link, position)) {\n this._currentLink = linkWithState;\n this._currentLink.state = {\n decorations: {\n underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline,\n pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor\n },\n isHovered: true\n };\n this._linkHover(this._element, linkWithState.link, this._lastMouseEvent);\n\n // Add listener for tracking decorations changes\n linkWithState.link.decorations = {} as ILinkDecorations;\n Object.defineProperties(linkWithState.link.decorations, {\n pointerCursor: {\n get: () => this._currentLink?.state?.decorations.pointerCursor,\n set: v => {\n if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) {\n this._currentLink.state.decorations.pointerCursor = v;\n if (this._currentLink.state.isHovered) {\n this._element.classList.toggle('xterm-cursor-pointer', v);\n }\n }\n }\n },\n underline: {\n get: () => this._currentLink?.state?.decorations.underline,\n set: v => {\n if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) {\n this._currentLink.state.decorations.underline = v;\n if (this._currentLink.state.isHovered) {\n this._fireUnderlineEvent(linkWithState.link, v);\n }\n }\n }\n }\n });\n\n // Listen to viewport changes to re-render the link under the cursor (only when the line the\n // link is on changes)\n this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => {\n // Sanity check, this shouldn't happen in practice as this listener would be disposed\n if (!this._currentLink) {\n return;\n }\n // When start is 0 a scroll most likely occurred, make sure links above the fold also get\n // cleared.\n const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp;\n const end = this._bufferService.buffer.ydisp + 1 + e.end;\n // Only clear the link if the viewport change happened on this line\n if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) {\n this._clearCurrentLink(start, end);\n if (this._lastMouseEvent) {\n // re-eval previously active link after changes\n const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element);\n if (position) {\n this._askForLink(position, false);\n }\n }\n }\n }));\n }\n }\n\n protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = true;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, true);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.add('xterm-cursor-pointer');\n }\n }\n\n if (link.hover) {\n link.hover(event, link.text);\n }\n }\n\n private _fireUnderlineEvent(link: ILink, showEvent: boolean): void {\n const range = link.range;\n const scrollOffset = this._bufferService.buffer.ydisp;\n const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined);\n const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline;\n emitter.fire(event);\n }\n\n protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {\n if (this._currentLink?.state) {\n this._currentLink.state.isHovered = false;\n if (this._currentLink.state.decorations.underline) {\n this._fireUnderlineEvent(link, false);\n }\n if (this._currentLink.state.decorations.pointerCursor) {\n element.classList.remove('xterm-cursor-pointer');\n }\n }\n\n if (link.leave) {\n link.leave(event, link.text);\n }\n }\n\n /**\n * Check if the buffer position is within the link\n * @param link\n * @param position\n */\n private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean {\n const lower = link.range.start.y * this._bufferService.cols + link.range.start.x;\n const upper = link.range.end.y * this._bufferService.cols + link.range.end.x;\n const current = position.y * this._bufferService.cols + position.x;\n return (lower <= current && current <= upper);\n }\n\n /**\n * Get the buffer position from a mouse event\n * @param event\n */\n private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement): IBufferCellPosition | undefined {\n const coords = this._mouseCoordsService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows);\n if (!coords) {\n return;\n }\n\n return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp };\n }\n\n private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent {\n return { x1, y1, x2, y2, cols: this._bufferService.cols, fg };\n }\n}\n\nfunction linkEquals(a: ILink, b: ILink): boolean {\n return (\n a.text === b.text &&\n a.range.start.x === b.range.start.x &&\n a.range.start.y === b.range.start.y &&\n a.range.end.x === b.range.end.x &&\n a.range.end.y === b.range.end.y\n );\n}\n", "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IRenderDimensions as IRenderDimensionsApi } from '@xterm/xterm';\nimport { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from './Clipboard';\nimport * as Strings from './LocalizableStrings';\nimport { OscLinkProvider } from './OscLinkProvider';\nimport { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from './Types';\nimport { Viewport } from './Viewport';\nimport { BufferDecorationRenderer } from './decorations/BufferDecorationRenderer';\nimport { OverviewRulerRenderer } from './decorations/OverviewRulerRenderer';\nimport { CompositionHelper } from './input/CompositionHelper';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IRenderer } from './renderer/shared/Types';\nimport { CharSizeService } from './services/CharSizeService';\nimport { CharacterJoinerService } from './services/CharacterJoinerService';\nimport { CoreBrowserService } from './services/CoreBrowserService';\nimport { LinkProviderService } from './services/LinkProviderService';\nimport { MouseCoordsService } from './services/MouseCoordsService';\nimport { MouseEventCssClasses, MouseService } from './services/MouseService';\nimport { RenderService } from './services/RenderService';\nimport { SelectionService } from './services/SelectionService';\nimport { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';\nimport { ThemeService } from './services/ThemeService';\nimport { KeyboardService } from './services/KeyboardService';\nimport { channels, color, rgb } from '../common/Color';\nimport { CoreTerminal } from '../common/CoreTerminal';\nimport * as Browser from '../common/Platform';\nimport { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';\nimport { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';\nimport { IBuffer } from '../common/buffer/Types';\nimport { C0, C1ESCAPED } from '../common/data/EscapeSequences';\nimport { toRgbString } from '../common/input/XParseColor';\nimport { DecorationService } from '../common/services/DecorationService';\nimport { IDecorationService } from '../common/services/Services';\nimport { WindowsOptionsReportType } from '../common/InputHandler';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { Linkifier } from './Linkifier';\nimport { Emitter, EventUtils, type IEvent } from '../common/Event';\nimport { addDisposableListener } from './Dom';\nimport { MutableDisposable, toDisposable } from '../common/Lifecycle';\n\nexport class CoreBrowserTerminal extends CoreTerminal implements ITerminal {\n public textarea: HTMLTextAreaElement | undefined;\n public element: HTMLElement | undefined;\n public screenElement: HTMLElement | undefined;\n\n private _document: Document | undefined;\n private _viewportElement: HTMLElement | undefined;\n private _helperContainer: HTMLElement | undefined;\n private _compositionView: HTMLElement | undefined;\n\n private readonly _linkifier: MutableDisposable = this._register(new MutableDisposable());\n public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }\n private _overviewRulerRenderer: OverviewRulerRenderer | undefined;\n private _viewport: Viewport | undefined;\n\n public browser: IBrowser = Browser as any;\n\n private _customKeyEventHandler: CustomKeyEventHandler | undefined;\n\n // Browser services\n private readonly _decorationService: DecorationService;\n private readonly _keyboardService: IKeyboardService;\n private readonly _linkProviderService: ILinkProviderService;\n\n // Optional browser services\n private _charSizeService: ICharSizeService | undefined;\n private _coreBrowserService: ICoreBrowserService | undefined;\n private _mouseCoordsService: IMouseCoordsService | undefined;\n private _mouseService: IMouseService | undefined;\n private _renderService: IRenderService | undefined;\n private _themeService: IThemeService | undefined;\n private _characterJoinerService: ICharacterJoinerService | undefined;\n private _selectionService: ISelectionService | undefined;\n\n /**\n * Records whether the keydown event has already been handled and triggered a data event, if so\n * the keypress event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyDownHandled: boolean = false;\n\n /**\n * Records whether a keydown event has occurred since the last keyup event, i.e. whether a key\n * is currently \"pressed\".\n */\n private _keyDownSeen: boolean = false;\n\n /**\n * Records whether the keypress event has already been handled and triggered a data event, if so\n * the input event should not trigger a data event but should still print to the textarea so\n * screen readers will announce it.\n */\n private _keyPressHandled: boolean = false;\n\n /**\n * Records whether there has been a keydown event for a dead key without a corresponding keydown\n * event for the composed/alternative character. If we cancel the keydown event for the dead key,\n * no events will be emitted for the final character.\n */\n private _unprocessedDeadKey: boolean = false;\n\n private _compositionHelper: ICompositionHelper | undefined;\n private _accessibilityManager: MutableDisposable = this._register(new MutableDisposable());\n\n private readonly _onCursorMove = this._register(new Emitter());\n public readonly onCursorMove = this._onCursorMove.event;\n private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());\n public readonly onKey = this._onKey.event;\n private readonly _onSelectionChange = this._register(new Emitter());\n public readonly onSelectionChange = this._onSelectionChange.event;\n private readonly _onTitleChange = this._register(new Emitter());\n public readonly onTitleChange = this._onTitleChange.event;\n private readonly _onBell = this._register(new Emitter());\n public readonly onBell = this._onBell.event;\n\n private _onFocus = this._register(new Emitter());\n public get onFocus(): IEvent { return this._onFocus.event; }\n private _onBlur = this._register(new Emitter());\n public get onBlur(): IEvent { return this._onBlur.event; }\n private _onA11yCharEmitter = this._register(new Emitter());\n public get onA11yChar(): IEvent { return this._onA11yCharEmitter.event; }\n private _onA11yTabEmitter = this._register(new Emitter());\n public get onA11yTab(): IEvent { return this._onA11yTabEmitter.event; }\n private _onWillOpen = this._register(new Emitter());\n public get onWillOpen(): IEvent { return this._onWillOpen.event; }\n private readonly _onDimensionsChange = this._register(new Emitter());\n public readonly onDimensionsChange = this._onDimensionsChange.event;\n\n public get dimensions(): IRenderDimensionsApi | undefined {\n if (!this._renderService) {\n return undefined;\n }\n const dimensions = this._renderService.dimensions;\n return {\n css: {\n canvas: { ...dimensions.css.canvas },\n cell: { ...dimensions.css.cell }\n },\n device: {\n canvas: { ...dimensions.device.canvas },\n cell: { ...dimensions.device.cell },\n char: { ...dimensions.device.char }\n }\n };\n }\n\n constructor(\n options: Partial = {}\n ) {\n super(options);\n\n this._setup();\n\n this._decorationService = this._instantiationService.createInstance(DecorationService);\n this._instantiationService.setService(IDecorationService, this._decorationService);\n this._keyboardService = this._instantiationService.createInstance(KeyboardService);\n this._instantiationService.setService(IKeyboardService, this._keyboardService);\n this._linkProviderService = this._instantiationService.createInstance(LinkProviderService);\n this._instantiationService.setService(ILinkProviderService, this._linkProviderService);\n this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));\n\n // Setup InputHandler listeners\n this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));\n this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));\n this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));\n this._register(this._inputHandler.onRequestReset(() => this.reset()));\n this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));\n this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));\n this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));\n this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));\n this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));\n this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));\n\n // Setup listeners\n this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));\n\n this._register(toDisposable(() => {\n this._customKeyEventHandler = undefined;\n this.element?.parentNode?.removeChild(this.element);\n }));\n }\n\n /**\n * Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.\n * An event from OSC 4|104 may contain multiple set or report requests, and multiple\n * or none restore requests (resetting all),\n * while an event from OSC 10|110 | 11|111 | 12|112 always contains a single request.\n */\n private _handleColorEvent(event: IColorEvent): void {\n if (!this._themeService) return;\n for (const req of event) {\n let acc: 'foreground' | 'background' | 'cursor' | 'ansi';\n let ident: string;\n switch (req.index) {\n case SpecialColorIndex.FOREGROUND: // OSC 10 | 110\n acc = 'foreground';\n ident = '10';\n break;\n case SpecialColorIndex.BACKGROUND: // OSC 11 | 111\n acc = 'background';\n ident = '11';\n break;\n case SpecialColorIndex.CURSOR: // OSC 12 | 112\n acc = 'cursor';\n ident = '12';\n break;\n default: // OSC 4 | 104\n // we can skip the [0..255] range check here (already done in inputhandler)\n acc = 'ansi';\n ident = '4;' + req.index;\n }\n switch (req.type) {\n case ColorRequestType.REPORT:\n const colorRgb = color.toColorRGB(acc === 'ansi'\n ? this._themeService.colors.ansi[req.index]\n : this._themeService.colors[acc]);\n this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);\n break;\n case ColorRequestType.SET:\n if (acc === 'ansi') {\n this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));\n } else {\n const narrowedAcc = acc;\n this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));\n }\n break;\n case ColorRequestType.RESTORE:\n this._themeService.restoreColor(req.index);\n break;\n }\n }\n }\n\n /**\n * Reports the current color scheme (dark or light) based on the relative luminance\n * of the background and foreground theme colors.\n * Sends CSI ? 997 ; 1 n for dark mode or CSI ? 997 ; 2 n for light mode.\n */\n private _reportColorScheme(): void {\n if (!this._themeService) return;\n const bgLuminance = rgb.relativeLuminance(this._themeService.colors.background.rgba >> 8);\n const fgLuminance = rgb.relativeLuminance(this._themeService.colors.foreground.rgba >> 8);\n // Dark mode = background is darker than foreground (lower luminance)\n const colorSchemeMode = bgLuminance < fgLuminance ? 1 : 2;\n this.coreService.triggerDataEvent(`${C0.ESC}[?997;${colorSchemeMode}n`);\n }\n\n protected _setup(): void {\n super._setup();\n\n this._customKeyEventHandler = undefined;\n }\n\n /**\n * Convenience property to active buffer.\n */\n public get buffer(): IBuffer {\n return this.buffers.active;\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus({ preventScroll: true });\n }\n }\n\n private _handleScreenReaderModeOptionChange(value: boolean): void {\n if (value) {\n if (!this._accessibilityManager.value && this._renderService) {\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n } else {\n this._accessibilityManager.clear();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _handleTextAreaFocus(ev: FocusEvent): void {\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n }\n this.element!.classList.add('focus');\n this._showCursor();\n this._onFocus.fire();\n }\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea?.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _handleTextAreaBlur(): void {\n // Text can safely be removed on blur. Doing it earlier could interfere with\n // screen readers reading it out.\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.blur();\n }\n this.textarea!.value = '';\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.coreService.decPrivateModes.sendFocus) {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n this.element!.classList.remove('focus');\n this._onBlur.fire();\n }\n\n private _syncTextArea(): void {\n if (!this.textarea || !this.buffer.isCursorInViewport || this._compositionHelper!.isComposing || !this._renderService) {\n return;\n }\n const cursorY = this.buffer.ybase + this.buffer.y;\n const bufferLine = this.buffer.lines.get(cursorY);\n if (!bufferLine) {\n return;\n }\n const cursorX = Math.min(this.buffer.x, this.cols - 1);\n const cellHeight = this._renderService.dimensions.css.cell.height;\n const width = bufferLine.getWidth(cursorX);\n const cellWidth = this._renderService.dimensions.css.cell.width * width;\n const cursorTop = this.buffer.y * this._renderService.dimensions.css.cell.height;\n const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;\n\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = cellWidth + 'px';\n this.textarea.style.height = cellHeight + 'px';\n this.textarea.style.lineHeight = cellHeight + 'px';\n this.textarea.style.zIndex = '-5';\n }\n\n /**\n * Initialize default behavior\n */\n private _initGlobal(): void {\n this._bindKeys();\n\n // Bind clipboard functionality\n this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this._selectionService!);\n }));\n const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);\n this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));\n this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }\n }));\n } else {\n this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);\n }));\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);\n }\n }));\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private _bindKeys(): void {\n this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n this._register(addDisposableListener(this.textarea!, 'compositionstart', () => {\n // Ensure the textarea is synced to the latest cursor location before composition begins. This\n // is to workaround a problem where highly dynamic TUIs like agentic CLIs reprint agressively\n // would cause the IME to appear in the wrong position. The theory is that when the IME is\n // triggered during a partial render the textarea position becomes locked and will not move\n // until it is hidden and a custom move occurs.\n this._syncTextArea();\n this._compositionHelper!.compositionstart();\n this._compositionHelper!.updateCompositionElements();\n }));\n this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));\n this._register(addDisposableListener(this.textarea!, 'compositionend', (e: CompositionEvent) => {\n if (this._compositionHelper instanceof CompositionHelper) {\n if (this._compositionHelper.compositionend(e)) {\n this.textarea!.dispatchEvent(new CustomEvent(\n 'xterm-composition-transaction-accepted',\n { bubbles: true }\n ));\n }\n } else {\n this._compositionHelper!.compositionend();\n }\n }));\n this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));\n this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n if (!parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n if (!parent.isConnected) {\n this._logService.debug('Terminal.open was called on an element that was not attached to the DOM');\n }\n\n // If the terminal is already opened\n if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {\n // Adjust the window if needed\n if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {\n this._coreBrowserService.window = this.element.ownerDocument.defaultView;\n }\n return;\n }\n\n this._document = parent.ownerDocument;\n if (this.options.documentOverride && this.options.documentOverride instanceof Document) {\n this._document = this.optionsService.rawOptions.documentOverride as Document;\n }\n\n // Create main element container\n this.element = this._document.createElement('div');\n this.element.dir = 'ltr'; // xterm.css assumes LTR\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.classList.toggle('allow-transparency', this.options.allowTransparency);\n this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));\n parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = this._document.createDocumentFragment();\n this._viewportElement = this._document.createElement('div');\n this._viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this._viewportElement);\n\n this.screenElement = this._document.createElement('div');\n this.screenElement.classList.add('xterm-screen');\n this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this._helperContainer = this._document.createElement('div');\n this._helperContainer.classList.add('xterm-helpers');\n this.screenElement.appendChild(this._helperContainer);\n fragment.appendChild(this.screenElement);\n\n const textarea = this.textarea = this._document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('aria-label', Strings.promptLabel.get());\n if (!Browser.isChromeOS) {\n // ChromeVox on ChromeOS does not like this. See\n // https://issuetracker.google.com/issues/260170397\n this.textarea.setAttribute('aria-multiline', 'false');\n }\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this._register(this.optionsService.onSpecificOptionChange('disableStdin', () => textarea.readOnly = this.optionsService.rawOptions.disableStdin));\n this.textarea.readOnly = this.optionsService.rawOptions.disableStdin;\n\n // Register the core browser service before the generic textarea handlers are registered so it\n // handles them first. Otherwise the renderers may use the wrong focus state.\n this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,\n this.textarea,\n parent.ownerDocument.defaultView ?? window,\n // Force unsafe null in node.js environment for tests\n this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)\n ));\n this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);\n\n this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));\n this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));\n this._helperContainer.appendChild(this.textarea);\n\n this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);\n this._instantiationService.setService(ICharSizeService, this._charSizeService);\n\n this._themeService = this._instantiationService.createInstance(ThemeService);\n this._instantiationService.setService(IThemeService, this._themeService);\n\n // CSI ? 996 n - color scheme query (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)\n this._register(this._inputHandler.onRequestColorSchemeQuery(() => this._reportColorScheme()));\n\n // Emit unsolicited color scheme notification on theme change when DECSET 2031 is enabled\n this._register(this._themeService.onChangeColors(() => {\n if (this.coreService.decPrivateModes.colorSchemeUpdates) {\n this._reportColorScheme();\n }\n }));\n\n this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);\n this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);\n\n this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));\n this._instantiationService.setService(IRenderService, this._renderService);\n this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));\n this._register(this._renderService.onDimensionsChange(e => this._onDimensionsChange.fire({\n css: {\n canvas: { ...e.css.canvas },\n cell: { ...e.css.cell }\n },\n device: {\n canvas: { ...e.device.canvas },\n cell: { ...e.device.cell },\n char: { ...e.device.char }\n }\n })));\n this.onResize(e => this._renderService!.resize(e.cols, e.rows));\n\n this._compositionView = this._document.createElement('div');\n this._compositionView.classList.add('composition-view');\n this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);\n this._register(toDisposable(() => {\n if (this._compositionHelper instanceof CompositionHelper) {\n this._compositionHelper.dispose();\n }\n }));\n this._helperContainer.appendChild(this._compositionView);\n\n this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService);\n this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService);\n\n const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n try {\n this._onWillOpen.fire(this.element);\n } catch (e) {\n this._logService.error('onWillOpen handler threw an exception', e);\n }\n if (!this._renderService.hasRenderer()) {\n this._renderService.setRenderer(this._createRenderer());\n }\n\n this._register(this.onCursorMove(() => {\n this._renderService!.handleCursorMove();\n this._syncTextArea();\n }));\n this._register(this.onResize(() => {\n this._renderService!.handleResize(this.cols, this.rows);\n this._syncTextArea();\n }));\n this._register(this.onBlur(() => this._renderService!.handleBlur()));\n this._register(this.onFocus(() => this._renderService!.handleFocus()));\n\n this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));\n this._register(this._viewport.onRequestScrollLines(e => {\n super.scrollLines(e, false);\n this.refresh(0, this.rows - 1);\n }));\n\n this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,\n this.element,\n this.screenElement,\n linkifier\n ));\n this._instantiationService.setService(ISelectionService, this._selectionService);\n this._mouseService = this._instantiationService.createInstance(MouseService);\n this._instantiationService.setService(IMouseService, this._mouseService);\n this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));\n this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));\n this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));\n this._register(this._selectionService.onLinuxMouseSelection(text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea!.value = text;\n this.textarea!.focus();\n this.textarea!.select();\n }));\n this._register(EventUtils.any(\n this._onScroll.event,\n this._inputHandler.onScroll\n )(() => {\n this._selectionService!.refresh();\n this._viewport?.queueSync();\n }));\n\n this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));\n this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));\n\n // apply mouse event classes set by escape codes before terminal was attached\n if (this.mouseStateService.areMouseEventsActive && !this.options.mouseEventsRequireAlt) {\n this._selectionService.disable();\n this.element.classList.add(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n } else {\n this._selectionService.enable();\n this.element.classList.remove(MouseEventCssClasses.ENABLE_MOUSE_EVENTS);\n }\n\n if (this.options.screenReaderMode) {\n // Note that this must be done *after* the renderer is created in order to\n // ensure the correct order of the dprchange event\n this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);\n }\n this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));\n\n const showScrollbar = this.options.scrollbar?.showScrollbar ?? true;\n const overviewRulerWidth = this.options.scrollbar?.width;\n if (showScrollbar && overviewRulerWidth) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n this.optionsService.onSpecificOptionChange('scrollbar', value => {\n const shouldShow = (value?.showScrollbar ?? true) && !!value?.width;\n if (!this._overviewRulerRenderer && shouldShow && this._viewportElement && this.screenElement) {\n this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));\n }\n });\n // Measure the character size\n this._charSizeService.measure();\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this._initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this._mouseService.bindMouse({\n element: this.element!,\n screenElement: this.screenElement!,\n document: this._document!,\n handleTouchScroll: amount => this._viewport?.handleTouchScroll(amount)\n }, disposable => this._register(disposable), () => this.focus());\n }\n\n private _createRenderer(): IRenderer {\n return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier!);\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param start The row to start from (between 0 and this.rows - 1).\n * @param end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number, sync: boolean = false): void {\n this._renderService?.refreshRows(start, end, sync);\n }\n\n /**\n * Change the cursor style for different selection modes\n */\n public updateCursorStyle(ev: KeyboardEvent | MouseEvent): void {\n if (this._selectionService?.shouldColumnSelect(ev)) {\n this.element!.classList.add('column-select');\n } else {\n this.element!.classList.remove('column-select');\n }\n }\n\n /**\n * Display the cursor element\n */\n private _showCursor(): void {\n if (!this.coreService.isCursorInitialized) {\n this.coreService.isCursorInitialized = true;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n // All scrollLines methods need to go via the viewport in order to support smooth scroll\n if (this._viewport) {\n this._viewport.scrollLines(disp);\n } else {\n super.scrollLines(disp, suppressScrollEvent);\n }\n this.refresh(0, this.rows - 1);\n }\n\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n public scrollToTop(): void {\n this.scrollLines(-this._bufferService.buffer.ydisp);\n }\n\n public scrollToBottom(disableSmoothScroll?: boolean): void {\n if (disableSmoothScroll && this._viewport) {\n this._viewport.scrollToLine(this.buffer.ybase, true);\n } else {\n this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);\n }\n }\n\n public scrollToLine(line: number): void {\n const scrollAmount = line - this._bufferService.buffer.ydisp;\n if (scrollAmount !== 0) {\n this.scrollLines(scrollAmount);\n }\n }\n\n public paste(data: string): void {\n paste(data, this.textarea!, this.coreService, this.optionsService);\n }\n\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this._customKeyEventHandler = customKeyEventHandler;\n }\n\n public attachCustomWheelEventHandler(customWheelEventHandler: CustomWheelEventHandler): void {\n this.mouseStateService.setCustomWheelEventHandler(customWheelEventHandler);\n }\n\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._linkProviderService.registerLinkProvider(linkProvider);\n }\n\n public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n const joinerId = this._characterJoinerService.register(handler);\n this.refresh(0, this.rows - 1);\n return joinerId;\n }\n\n public deregisterCharacterJoiner(joinerId: number): void {\n if (!this._characterJoinerService) {\n throw new Error('Terminal must be opened first');\n }\n if (this._characterJoinerService.deregister(joinerId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n\n public get markers(): IMarker[] {\n return this.buffer.markers;\n }\n\n public registerMarker(cursorYOffset: number): IMarker {\n return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n }\n\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n return this._decorationService.registerDecoration(decorationOptions);\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this._selectionService ? this._selectionService.hasSelection : false;\n }\n\n /**\n * Selects text within the terminal.\n * @param column The column the selection starts at..\n * @param row The row the selection starts at.\n * @param length The length of the selection.\n */\n public select(column: number, row: number, length: number): void {\n this._selectionService!.setSelection(column, row, length);\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this._selectionService ? this._selectionService.selectionText : '';\n }\n\n public getSelectionPosition(): IBufferRange | undefined {\n if (!this._selectionService || !this._selectionService.hasSelection) {\n return undefined;\n }\n\n return {\n start: {\n x: this._selectionService.selectionStart![0],\n y: this._selectionService.selectionStart![1]\n },\n end: {\n x: this._selectionService.selectionEnd![0],\n y: this._selectionService.selectionEnd![1]\n }\n };\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._selectionService?.clearSelection();\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._selectionService?.selectAll();\n }\n\n public selectLines(start: number, end: number): void {\n this._selectionService?.selectLines(start, end);\n }\n\n /**\n * Handle a keydown [KeyboardEvent].\n *\n * [KeyboardEvent]: https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n */\n protected _keyDown(event: KeyboardEvent): boolean | undefined {\n this._keyDownHandled = false;\n this._keyDownSeen = true;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n return false;\n }\n\n // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled\n const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;\n\n if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {\n if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom(true);\n }\n return false;\n }\n\n if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) {\n this._unprocessedDeadKey = true;\n }\n\n const result = this._keyboardService.evaluateKeyDown(event);\n\n this.updateCursorStyle(event);\n\n if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n const scrollCount = this.rows - 1;\n this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n if (result.type === KeyboardResultType.SELECT_ALL) {\n this.selectAll();\n }\n\n if (this._isThirdLevelShift(this.browser, event)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (!result.key) {\n return true;\n }\n\n // HACK: Process A-Z in the keypress event to fix an issue with macOS IMEs where lower case\n // letters cannot be input while caps lock is on. Skip this hack when using kitty protocol\n // or Win32 input mode as they need to send proper sequences for all key events.\n if (!this._keyboardService.useKitty && !this._keyboardService.useWin32InputMode && event.key && !event.ctrlKey && !event.altKey && !event.metaKey && event.key.length === 1) {\n if (event.key.charCodeAt(0) >= 65 && event.key.charCodeAt(0) <= 90) {\n return true;\n }\n }\n\n if (this._unprocessedDeadKey) {\n this._unprocessedDeadKey = false;\n return true;\n }\n\n // If ctrl+c or enter is being sent, clear out the textarea. This is done so that screen readers\n // will announce deleted characters. This will not work 100% of the time but it should cover\n // most scenarios.\n if (result.key === C0.ETX || result.key === C0.CR) {\n this.textarea!.value = '';\n }\n\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);\n this._onKey.fire({ key: result.key, domEvent: event });\n this._showCursor();\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n\n // Cancel events when not in screen reader mode so events don't get bubbled up and handled by\n // other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt\n // is also depressed) so that the cursor textarea can be updated, which triggers the screen\n // reader to read it.\n if (!this.optionsService.rawOptions.screenReaderMode || event.altKey || event.ctrlKey) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n this._keyDownHandled = true;\n }\n\n private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.altKey && ev.ctrlKey && !ev.metaKey) ||\n (browser.isWindows && ev.getModifierState('AltGraph'));\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n }\n\n protected _keyUp(ev: KeyboardEvent): void {\n this._keyDownSeen = false;\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return;\n }\n\n if (!wasModifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n\n // Handle key release for Kitty keyboard protocol\n const result = this._keyboardService.evaluateKeyUp(ev);\n if (result?.key) {\n const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);\n this.coreService.triggerDataEvent(result.key, !wasModifierOnly);\n }\n\n this.updateCursorStyle(ev);\n this._keyPressHandled = false;\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n this._keyPressHandled = false;\n\n if (this._keyDownHandled) {\n return false;\n }\n\n if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which === null || ev.which === undefined) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this._onKey.fire({ key, domEvent: ev });\n this._showCursor();\n if (!this._compositionHelper!.keypress?.(key)) {\n this.coreService.triggerDataEvent(key, true);\n }\n\n this._keyPressHandled = true;\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n return true;\n }\n\n /**\n * Handle an input event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent\n * @param ev The input event to be handled.\n */\n protected _inputEvent(ev: InputEvent): boolean {\n if (\n ev.data &&\n ev.inputType === 'insertText' &&\n !this.optionsService.rawOptions.screenReaderMode &&\n this._compositionHelper instanceof CompositionHelper &&\n this._compositionHelper.input(ev.data)\n ) {\n return true;\n }\n // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to\n // support reading out character input which can doubling up input characters\n // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679\n if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) {\n if (this._keyPressHandled) {\n return false;\n }\n\n // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow\n // keys could be ignored\n this._unprocessedDeadKey = false;\n\n const text = ev.data;\n this.coreService.triggerDataEvent(text, true);\n return true;\n }\n\n return false;\n }\n\n /**\n * Resizes the terminal.\n *\n * @param x The number of columns to resize to.\n * @param y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (this._charSizeService && !this._charSizeService.hasValidSize) {\n this._charSizeService.measure();\n }\n return;\n }\n\n super.resize(x, y);\n }\n\n private _afterResize(x: number, y: number): void {\n this._charSizeService?.measure();\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n this.buffer.clearAllMarkers();\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n }\n // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear\n // scroll event and that the viewport's state will be valid for immediate writes.\n this._onScroll.fire({ position: this.buffer.ydisp });\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Reset terminal.\n * Note: Calling this directly from JS is synchronous but does not clear\n * input buffers and does not reset the parser, thus the terminal will\n * continue to apply pending input data.\n * If you need in band reset (synchronous with input data) consider\n * using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).\n */\n public reset(): void {\n /**\n * Since _setup handles a full terminal creation, we have to carry forward\n * a few things that should not reset.\n */\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this._customKeyEventHandler;\n\n this._setup();\n super.reset();\n this._mouseService?.reset();\n this._selectionService?.reset();\n this._decorationService.reset();\n\n // reattach\n this._customKeyEventHandler = customKeyEventHandler;\n\n // do a full screen refresh\n this.refresh(0, this.rows - 1, true);\n }\n\n public clearTextureAtlas(): void {\n this._renderService?.clearTextureAtlas();\n }\n\n private _reportFocus(): void {\n if (this.element?.classList.contains('focus')) {\n this.coreService.triggerDataEvent(C0.ESC + '[I');\n } else {\n this.coreService.triggerDataEvent(C0.ESC + '[O');\n }\n }\n\n private _reportWindowsOptions(type: WindowsOptionsReportType): void {\n if (!this._renderService) {\n return;\n }\n\n switch (type) {\n case WindowsOptionsReportType.GET_WIN_SIZE_PIXELS:\n const canvasWidth = this._renderService.dimensions.css.canvas.width.toFixed(0);\n const canvasHeight = this._renderService.dimensions.css.canvas.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[4;${canvasHeight};${canvasWidth}t`);\n break;\n case WindowsOptionsReportType.GET_CELL_SIZE_PIXELS:\n const cellWidth = this._renderService.dimensions.css.cell.width.toFixed(0);\n const cellHeight = this._renderService.dimensions.css.cell.height.toFixed(0);\n this.coreService.triggerDataEvent(`${C0.ESC}[6;${cellHeight};${cellWidth}t`);\n break;\n }\n }\n\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18 || // Alt\n ev.keyCode === 91 || // Meta (Left)\n ev.keyCode === 92 || // Meta (Right)\n ev.keyCode === 93 || // Meta (Menu)\n ev.keyCode === 224 || // Meta (Firefox)\n ev.key === 'Meta';\n}\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm';\n\nexport interface ILoadedAddon {\n instance: ITerminalAddon;\n dispose: () => void;\n isDisposed: boolean;\n}\n\nexport class AddonManager implements IDisposable {\n protected _addons: ILoadedAddon[] = [];\n\n public dispose(): void {\n for (let i = this._addons.length - 1; i >= 0; i--) {\n this._addons[i].instance.dispose();\n }\n }\n\n public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {\n const loadedAddon: ILoadedAddon = {\n instance,\n dispose: instance.dispose,\n isDisposed: false\n };\n this._addons.push(loadedAddon);\n instance.dispose = () => this._wrappedAddonDispose(loadedAddon);\n instance.activate(terminal as any);\n }\n\n private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {\n if (loadedAddon.isDisposed) {\n // Do nothing if already disposed\n return;\n }\n let index = -1;\n for (let i = 0; i < this._addons.length; i++) {\n if (this._addons[i] === loadedAddon) {\n index = i;\n break;\n }\n }\n if (index === -1) {\n throw new Error('Could not dispose an addon that has not been loaded');\n }\n loadedAddon.isDisposed = true;\n loadedAddon.dispose.apply(loadedAddon.instance);\n this._addons.splice(index, 1);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CellData } from '../buffer/CellData';\nimport { IBufferLine, ICellData } from '../buffer/Types';\nimport { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm';\n\nexport class BufferLineApiView implements IBufferLineApi {\n constructor(private _line: IBufferLine) { }\n\n public get isWrapped(): boolean { return this._line.isWrapped; }\n public get length(): number { return this._line.length; }\n public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {\n if (x < 0 || x >= this._line.length) {\n return undefined;\n }\n\n if (cell) {\n this._line.loadCell(x, cell as unknown as ICellData);\n return cell;\n }\n return this._line.loadCell(x, new CellData()) as unknown as IBufferCellApi;\n }\n public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {\n return this._line.translateToString(trimRight, startColumn, endColumn);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm';\nimport { IBuffer } from '../buffer/Types';\nimport { BufferLineApiView } from './BufferLineApiView';\nimport { CellData } from '../buffer/CellData';\n\nexport class BufferApiView implements IBufferApi {\n constructor(\n private _buffer: IBuffer,\n public readonly type: 'normal' | 'alternate'\n ) { }\n\n public init(buffer: IBuffer): BufferApiView {\n this._buffer = buffer;\n return this;\n }\n\n public get cursorY(): number { return this._buffer.y; }\n public get cursorX(): number { return this._buffer.x; }\n public get viewportY(): number { return this._buffer.ydisp; }\n public get baseY(): number { return this._buffer.ybase; }\n public get length(): number { return this._buffer.lines.length; }\n public getLine(y: number): IBufferLineApi | undefined {\n const line = this._buffer.lines.get(y);\n if (!line) {\n return undefined;\n }\n return new BufferLineApiView(line);\n }\n public getNullCell(): IBufferCellApi { return new CellData(); }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm';\nimport { BufferApiView } from './BufferApiView';\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { Disposable } from '../Lifecycle';\nimport { Emitter } from '../Event';\n\nexport class BufferNamespaceApi extends Disposable implements IBufferNamespaceApi {\n private _normal: BufferApiView;\n private _alternate: BufferApiView;\n\n private readonly _onBufferChange = this._register(new Emitter());\n public readonly onBufferChange = this._onBufferChange.event;\n\n constructor(private _core: ICoreTerminal) {\n super();\n this._normal = new BufferApiView(this._core.buffers.normal, 'normal');\n this._alternate = new BufferApiView(this._core.buffers.alt, 'alternate');\n this._register(this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active)));\n }\n public get active(): IBufferApi {\n if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }\n if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }\n throw new Error('Active buffer is neither normal nor alternate');\n }\n public get normal(): IBufferApi {\n return this._normal.init(this._core.buffers.normal);\n }\n public get alternate(): IBufferApi {\n return this._alternate.init(this._core.buffers.alt);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IParams } from '../parser/Types';\nimport { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm';\nimport { ICoreTerminal } from '../CoreTerminal';\n\nexport class ParserApi implements IParser {\n constructor(private _core: ICoreTerminal) { }\n\n public registerCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerCsiHandler(id, (params: IParams) => callback(params.toArray()));\n }\n public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerCsiHandler(id, callback);\n }\n public registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this._core.registerDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray()));\n }\n public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean | Promise): IDisposable {\n return this.registerDcsHandler(id, callback);\n }\n public registerEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this._core.registerEscHandler(id, handler);\n }\n public addEscHandler(id: IFunctionIdentifier, handler: () => boolean | Promise): IDisposable {\n return this.registerEscHandler(id, handler);\n }\n public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerOscHandler(ident, callback);\n }\n public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable {\n return this.registerOscHandler(ident, callback);\n }\n public registerApcHandler(id: IFunctionIdentifier, callback: (data: string) => boolean | Promise): IDisposable {\n return this._core.registerApcHandler(id, callback);\n }\n}\n", "/**\n * Copyright (c) 2021 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICoreTerminal } from '../CoreTerminal';\nimport { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm';\n\nexport class UnicodeApi implements IUnicodeHandling {\n constructor(private _core: ICoreTerminal) { }\n\n public register(provider: IUnicodeVersionProvider): void {\n this._core.unicodeService.register(provider);\n }\n\n public get versions(): string[] {\n return this._core.unicodeService.versions;\n }\n\n public get activeVersion(): string {\n return this._core.unicodeService.activeVersion;\n }\n\n public set activeVersion(version: string) {\n this._core.unicodeService.activeVersion = version;\n }\n}\n", "/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from '../LocalizableStrings';\nimport { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';\nimport { IBufferRange, ITerminal } from '../Types';\nimport { Disposable } from '../../common/Lifecycle';\nimport { ITerminalOptions } from '../../common/Types';\nimport { AddonManager } from '../../common/public/AddonManager';\nimport { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';\nimport { ParserApi } from '../../common/public/ParserApi';\nimport { UnicodeApi } from '../../common/public/UnicodeApi';\nimport { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';\nimport type { IEvent } from '../../common/Event';\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nlet $value = 0;\n\nexport class Terminal extends Disposable implements ITerminalApi {\n private _core: ITerminal;\n private _addonManager: AddonManager;\n private _parser: IParser | undefined;\n private _buffer: BufferNamespaceApi | undefined;\n private _publicOptions: Required;\n\n constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {\n super();\n\n this._core = this._register(new TerminalCore(options));\n this._addonManager = this._register(new AddonManager());\n\n this._publicOptions = { ... this._core.options };\n const getter = (propName: string): any => {\n return this._core.options[propName];\n };\n const setter = (propName: string, value: any): void => {\n this._checkReadonlyOptions(propName);\n this._core.options[propName] = value;\n };\n\n for (const propName in this._core.options) {\n const desc = {\n get: getter.bind(this, propName),\n set: setter.bind(this, propName)\n };\n Object.defineProperty(this._publicOptions, propName, desc);\n }\n }\n\n private _checkReadonlyOptions(propName: string): void {\n // Throw an error if any constructor only option is modified\n // from terminal.options\n // Modifications from anywhere else are allowed\n if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {\n throw new Error(`Option \"${propName}\" can only be set in the constructor`);\n }\n }\n\n private _checkProposedApi(): void {\n if (!this._core.optionsService.rawOptions.allowProposedApi) {\n throw new Error('You must set the allowProposedApi option to true to use proposed API');\n }\n }\n\n public get onBell(): IEvent { return this._core.onBell; }\n public get onBinary(): IEvent { return this._core.onBinary; }\n public get onCursorMove(): IEvent { return this._core.onCursorMove; }\n public get onData(): IEvent { return this._core.onData; }\n public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n public get onLineFeed(): IEvent { return this._core.onLineFeed; }\n public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n public get onScroll(): IEvent { return this._core.onScroll; }\n public get onSelectionChange(): IEvent { return this._core.onSelectionChange; }\n public get onTitleChange(): IEvent { return this._core.onTitleChange; }\n public get onWriteParsed(): IEvent { return this._core.onWriteParsed; }\n public get onDimensionsChange(): IEvent { return this._core.onDimensionsChange; }\n\n public get element(): HTMLElement | undefined { return this._core.element; }\n public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }\n public get parser(): IParser {\n return this._parser ??= new ParserApi(this._core);\n }\n public get unicode(): IUnicodeHandling {\n this._checkProposedApi();\n return new UnicodeApi(this._core);\n }\n public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }\n public get rows(): number { return this._core.rows; }\n public get cols(): number { return this._core.cols; }\n public get buffer(): IBufferNamespaceApi {\n return this._buffer ??= this._register(new BufferNamespaceApi(this._core));\n }\n public get markers(): ReadonlyArray {\n return this._core.markers;\n }\n public get modes(): IModes {\n const m = this._core.coreService.decPrivateModes;\n let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';\n switch (this._core.mouseStateService.activeProtocol) {\n case 'X10': mouseTrackingMode = 'x10'; break;\n case 'VT200': mouseTrackingMode = 'vt200'; break;\n case 'DRAG': mouseTrackingMode = 'drag'; break;\n case 'ANY': mouseTrackingMode = 'any'; break;\n }\n return {\n applicationCursorKeysMode: m.applicationCursorKeys,\n applicationKeypadMode: m.applicationKeypad,\n bracketedPasteMode: m.bracketedPasteMode,\n insertMode: this._core.coreService.modes.insertMode,\n mouseTrackingMode: mouseTrackingMode,\n originMode: m.origin,\n reverseWraparoundMode: m.reverseWraparound,\n sendFocusMode: m.sendFocus,\n showCursor: !this._core.coreService.isCursorHidden,\n synchronizedOutputMode: m.synchronizedOutput,\n win32InputMode: m.win32InputMode,\n wraparoundMode: m.wraparound\n };\n }\n public get dimensions(): IRenderDimensions | undefined {\n return this._core.dimensions;\n }\n public get options(): Required {\n return this._publicOptions;\n }\n public set options(options: ITerminalOptions) {\n for (const propName in options) {\n this._publicOptions[propName] = options[propName];\n }\n }\n public blur(): void {\n this._core.blur();\n }\n public focus(): void {\n this._core.focus();\n }\n public input(data: string, wasUserInput: boolean = true): void {\n this._core.input(data, wasUserInput);\n }\n public resize(columns: number, rows: number): void {\n this._verifyIntegers(columns, rows);\n this._core.resize(columns, rows);\n }\n public open(parent: HTMLElement): void {\n this._core.open(parent);\n }\n public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n }\n public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {\n this._core.attachCustomWheelEventHandler(customWheelEventHandler);\n }\n public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {\n return this._core.registerLinkProvider(linkProvider);\n }\n public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n return this._core.registerCharacterJoiner(handler);\n }\n public deregisterCharacterJoiner(joinerId: number): void {\n this._core.deregisterCharacterJoiner(joinerId);\n }\n public registerMarker(cursorYOffset: number = 0): IMarker {\n this._verifyIntegers(cursorYOffset);\n return this._core.registerMarker(cursorYOffset);\n }\n public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {\n this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);\n return this._core.registerDecoration(decorationOptions);\n }\n public hasSelection(): boolean {\n return this._core.hasSelection();\n }\n public select(column: number, row: number, length: number): void {\n this._verifyIntegers(column, row, length);\n this._core.select(column, row, length);\n }\n public getSelection(): string {\n return this._core.getSelection();\n }\n public getSelectionPosition(): IBufferRange | undefined {\n return this._core.getSelectionPosition();\n }\n public clearSelection(): void {\n this._core.clearSelection();\n }\n public selectAll(): void {\n this._core.selectAll();\n }\n public selectLines(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.selectLines(start, end);\n }\n public dispose(): void {\n super.dispose();\n }\n public scrollLines(amount: number): void {\n this._verifyIntegers(amount);\n this._core.scrollLines(amount);\n }\n public scrollPages(pageCount: number): void {\n this._verifyIntegers(pageCount);\n this._core.scrollPages(pageCount);\n }\n public scrollToTop(): void {\n this._core.scrollToTop();\n }\n public scrollToBottom(): void {\n this._core.scrollToBottom();\n }\n public scrollToLine(line: number): void {\n this._verifyIntegers(line);\n this._core.scrollToLine(line);\n }\n public clear(): void {\n this._core.clear();\n }\n public write(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data, callback);\n }\n public writeln(data: string | Uint8Array, callback?: () => void): void {\n this._core.write(data);\n this._core.write('\\r\\n', callback);\n }\n public paste(data: string): void {\n this._core.paste(data);\n }\n public refresh(start: number, end: number): void {\n this._verifyIntegers(start, end);\n this._core.refresh(start, end);\n }\n public reset(): void {\n this._core.reset();\n }\n public clearTextureAtlas(): void {\n this._core.clearTextureAtlas();\n }\n public loadAddon(addon: ITerminalAddon): void {\n this._addonManager.loadAddon(this, addon);\n }\n public static get strings(): ILocalizableStrings {\n // A wrapper is required here because esbuild prevents setting an `export let`\n return {\n get promptLabel(): string { return Strings.promptLabel.get(); },\n set promptLabel(value: string) { Strings.promptLabel.set(value); },\n get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },\n set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }\n };\n }\n\n private _verifyIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {\n throw new Error('This API only accepts integers');\n }\n }\n }\n\n private _verifyPositiveIntegers(...values: number[]): void {\n for ($value of values) {\n if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {\n throw new Error('This API only accepts positive integers');\n }\n }\n }\n}\n"], ++ "mappings": "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CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EAAG,CAAC,KAAQ,IAAM,EACnD,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", + "names": ["promptLabelInternal", "promptLabel", "value", "tooMuchOutputInternal", "tooMuchOutput", "prepareTextForTerminal", "text", "bracketTextForPaste", "bracketedPasteMode", "copyHandler", "ev", "selectionService", "handlePasteEvent", "textarea", "coreService", "optionsService", "paste", "moveTextAreaUnderMouseCursor", "screenElement", "pos", "left", "top", "rightClickHandler", "shouldSelectWord", "stringFromCodePoint", "codePoint", "utf32ToString", "data", "start", "end", "result", "i", "codepoint", "StringToUtf32", "input", "target", "length", "size", "startPos", "second", "code", "Utf8ToUtf32", "byte1", "byte2", "byte3", "byte4", "discardInterim", "cp", "pos", "tmp", "type", "missing", "fourStop", "AttributeData", "_AttributeData", "ExtendedAttrs", "value", "newObj", "_ExtendedAttrs", "ext", "urlId", "val", "CellData", "_CellData", "AttributeData", "ExtendedAttrs", "value", "obj", "stringFromCodePoint", "combined", "code", "second", "other", "thisDefault", "otherDefault", "serviceRegistry", "getServiceDependencies", "ctor", "createDecorator", "id", "decorator", "target", "key", "index", "storeServiceDependency", "IBufferService", "createDecorator", "IMouseStateService", "ICoreService", "ICharsetService", "IInstantiationService", "ILogService", "createDecorator", "IOptionsService", "IOscLinkService", "IUnicodeService", "IDecorationService", "OscLinkProvider", "_bufferService", "_optionsService", "_oscLinkService", "CellData", "y", "callback", "line", "result", "linkHandler", "cell", "lineLength", "currentLinkId", "currentStart", "finishLink", "x", "text", "endX", "range", "ignoreLink", "parsed", "e", "defaultActivate", "startX", "linkId", "startY", "finalStartX", "endY", "finalEndX", "previousLine", "previousLineLength", "previousStartX", "currentLine", "currentLineLength", "nextLine", "nextLineLength", "nextEndX", "__decorateClass", "__decorateParam", "IBufferService", "IOptionsService", "IOscLinkService", "uri", "newWindow", "ICharSizeService", "createDecorator", "ICoreBrowserService", "IMouseCoordsService", "IMouseService", "IRenderService", "ISelectionService", "ICharacterJoinerService", "IThemeService", "ILinkProviderService", "IKeyboardService", "toDisposable", "fn", "dispose", "arg", "d", "DisposableStore", "o", "d", "Disposable", "MutableDisposable", "value", "disposableTimeout", "handler", "timeout", "store", "timer", "disposable", "toDisposable", "TimeoutTimer", "runner", "MicrotaskTimer", "IntervalTimer", "interval", "context", "handle", "getWindow", "e", "candidateNode", "candidateEvent", "DomListener", "node", "type", "handler", "options", "addDisposableListener", "useCaptureOrOptions", "addStandardDisposableListener", "useCapture", "eventType", "getDomNodePagePosition", "domNode", "bb", "win", "AnimationFrameQueueItem", "_runner", "priority", "a", "b", "animationFrameState", "getAnimationFrameState", "targetWindow", "state", "animationFrameRunner", "scheduleAtNextAnimationFrame", "runner", "item", "WindowIntervalTimer", "IntervalTimer", "interval", "FastDomNode", "domNode", "_width", "width", "numberAsPixels", "_height", "height", "_top", "top", "_left", "left", "_bottom", "bottom", "_right", "right", "className", "shouldHaveIt", "position", "layerHint", "contain", "name", "value", "Platform_exports", "__export", "getSafariVersion", "getZoomFactor", "isChrome", "isChromeOS", "isFirefox", "isLegacyEdge", "isLinux", "isMac", "isNode", "isSafari", "isWindows", "userAgent", "platform", "_targetWindow", "majorVersion", "sameOriginWindowChainCache", "getParentWindowIfSameOrigin", "w", "location", "parentLocation", "IframeUtils", "targetWindow", "windowChainCache", "parent", "childWindow", "ancestorWindow", "top", "left", "windowChain", "windowChainEl", "windowInChain", "boundingRect", "StandardMouseEvent", "iframeOffsets", "StandardWheelEvent", "e", "deltaX", "deltaY", "shouldFactorDPR", "isChrome", "chromeVersionMatch", "e1", "e2", "devicePixelRatio", "ev", "isFirefox", "isMac", "isSafari", "isWindows", "GlobalPointerMoveMonitor", "DisposableStore", "invokeStopCallback", "onStopCallback", "initialElement", "pointerId", "initialButtons", "pointerMoveCallback", "eventSource", "toDisposable", "getWindow", "addDisposableListener", "eventType", "e", "Widget", "Disposable", "domNode", "listener", "addDisposableListener", "eventType", "e", "StandardMouseEvent", "getWindow", "ScrollbarArrow", "Widget", "opts", "arrowSize", "GlobalPointerMoveMonitor", "addStandardDisposableListener", "eventType", "e", "WindowIntervalTimer", "TimeoutTimer", "scheduleRepeater", "getWindow", "pointerMoveData", "Emitter", "listener", "thisArgs", "disposables", "toDisposable", "entry", "result", "idx", "event", "fn", "listeners", "EventUtils", "forward", "from", "to", "e", "map", "i", "any", "events", "store", "DisposableStore", "runAndSubscribe", "handler", "initial", "ScrollState", "_ScrollState", "_forceIntegerValues", "width", "scrollWidth", "scrollLeft", "height", "scrollHeight", "scrollTop", "other", "update", "useRawScrollPositions", "previous", "inSmoothScrolling", "widthChanged", "scrollWidthChanged", "scrollLeftChanged", "heightChanged", "scrollHeightChanged", "scrollTopChanged", "Scrollable", "Disposable", "options", "Emitter", "smoothScrollDuration", "scrollPosition", "dimensions", "newState", "reuseAnimation", "validTarget", "newSmoothScrolling", "SmoothScrollingOperation", "oldState", "SmoothScrollingUpdate", "isDone", "createEaseOutCubic", "from", "to", "delta", "completion", "easeOutCubic", "createComposed", "a", "b", "cut", "_SmoothScrollingOperation", "startTime", "duration", "viewportSize", "stop1", "stop2", "state", "now", "newScrollLeft", "newScrollTop", "easeInCubic", "t", "ScrollbarVisibilityController", "Disposable", "visibility", "visibleClassName", "invisibleClassName", "TimeoutTimer", "rawShouldBeVisible", "shouldBeVisible", "isNeeded", "domNode", "withFadeAway", "POINTER_DRAG_RESET_DISTANCE", "AbstractScrollbar", "Widget", "opts", "ScrollbarVisibilityController", "GlobalPointerMoveMonitor", "FastDomNode", "addDisposableListener", "eventType", "arrow", "ScrollbarArrow", "top", "left", "width", "height", "e", "visibleSize", "elementScrollSize", "elementScrollPosition", "domTop", "sliderStart", "sliderStop", "pointerPos", "offsetX", "offsetY", "domNodePosition", "getDomNodePagePosition", "offset", "initialPointerPosition", "initialPointerOrthogonalPosition", "initialScrollbarState", "pointerMoveData", "pointerOrthogonalPosition", "pointerOrthogonalDelta", "isWindows", "pointerDelta", "_desiredScrollPosition", "desiredScrollPosition", "scrollbarSize", "ScrollbarState", "_ScrollbarState", "arrowSize", "scrollbarSize", "oppositeScrollbarSize", "visibleSize", "scrollSize", "scrollPosition", "iVisibleSize", "iScrollSize", "iScrollPosition", "iArrowSize", "computedAvailableSize", "computedRepresentableSize", "computedIsNeeded", "computedSliderSize", "computedSliderRatio", "computedSliderPosition", "r", "offset", "desiredSliderPosition", "correctedOffset", "desiredScrollPosition", "delta", "HorizontalScrollbar", "AbstractScrollbar", "scrollable", "options", "host", "scrollDimensions", "scrollPosition", "ScrollbarState", "sliderSize", "sliderPosition", "largeSize", "smallSize", "e", "offsetX", "offsetY", "size", "target", "VerticalScrollbar", "AbstractScrollbar", "scrollable", "options", "host", "scrollDimensions", "scrollPosition", "hasArrows", "ScrollbarState", "sliderSize", "sliderPosition", "largeSize", "smallSize", "offsetX", "offsetY", "size", "target", "delta", "currentPosition", "showArrows", "display", "arrow", "arrowSize", "MouseWheelClassifierItem", "timestamp", "deltaX", "deltaY", "_MouseWheelClassifier", "remainingInfluence", "score", "iteration", "index", "influence", "e", "isChrome", "targetWindow", "getWindow", "pageZoomFactor", "getZoomFactor", "previousItem", "item", "absDeltaX", "absDeltaY", "absPreviousDeltaX", "absPreviousDeltaY", "minDeltaX", "minDeltaY", "maxDeltaX", "maxDeltaY", "value", "MouseWheelClassifier", "SmoothScrollableElement", "Widget", "element", "options", "scrollable", "Emitter", "resolvedScrollable", "ownsScrollable", "Scrollable", "callback", "scheduleAtNextAnimationFrame", "resolveOptions", "scrollbarHost", "mouseWheelEvent", "VerticalScrollbar", "HorizontalScrollbar", "FastDomNode", "TimeoutTimer", "dispose", "dimensions", "update", "newClassName", "isMac", "newOptions", "browserEvent", "StandardWheelEvent", "shouldListen", "onMouseWheel", "addDisposableListener", "eventType", "classifier", "didScroll", "shiftConvert", "futureScrollPosition", "desiredScrollPosition", "deltaScrollTop", "desiredScrollTop", "deltaScrollLeft", "desiredScrollLeft", "consumeMouseWheel", "scrollState", "enableTop", "enableLeft", "leftClassName", "topClassName", "topLeftClassName", "opts", "result", "Viewport", "Disposable", "element", "screenElement", "_bufferService", "coreBrowserService", "_coreService", "mouseStateService", "themeService", "_optionsService", "_renderService", "Emitter", "scrollable", "Scrollable", "cb", "scheduleAtNextAnimationFrame", "SmoothScrollableElement", "type", "EventUtils", "toDisposable", "e", "disp", "pos", "line", "disableSmoothScroll", "showScrollbar", "showArrows", "verticalScrollbarSize", "ydisp", "newRow", "diff", "translationY", "__decorateClass", "__decorateParam", "IBufferService", "ICoreBrowserService", "ICoreService", "IMouseStateService", "IThemeService", "IOptionsService", "IRenderService", "BufferDecorationRenderer", "Disposable", "_screenElement", "_bufferService", "_coreBrowserService", "_decorationService", "_renderService", "decoration", "toDisposable", "element", "x", "line", "__decorateClass", "__decorateParam", "IBufferService", "ICoreBrowserService", "IDecorationService", "IRenderService", "ColorZoneStore", "decoration", "z", "padding", "zone", "line", "position", "drawHeight", "drawWidth", "drawX", "OverviewRulerRenderer", "Disposable", "_viewportElement", "_screenElement", "_bufferService", "_decorationService", "_renderService", "_optionsService", "_themeService", "_coreBrowserService", "ColorZoneStore", "toDisposable", "ctx", "scrollbar", "outerWidth", "innerWidth", "pixelsPerLine", "nonFullHeight", "cssCanvasHeight", "deviceCanvasHeight", "decoration", "zones", "zone", "updateCanvasDimensions", "updateAnchor", "__decorateClass", "__decorateParam", "IBufferService", "IDecorationService", "IRenderService", "IOptionsService", "IThemeService", "ICoreBrowserService", "XTERM_COMPOSITION_SESSION_START_EVENT", "XTERM_COMPOSITION_SESSION_END_EVENT", "XTERM_COMPOSITION_TRANSACTION_ACCEPTED_EVENT", "CompositionHelper", "_textarea", "_compositionView", "_bufferService", "_optionsService", "_coreService", "_renderService", "start", "end", "ev", "transactionId", "pending", "endData", "timer", "text", "repeatsPendingTextareaInput", "waitForPropagation", "wasComposing", "input", "includeFollowingInput", "textareaInput", "observedInput", "candidate", "observed", "findShortestOrder", "candidateFirstOverlap", "observedFirstOverlap", "overlap", "value", "suffixEnd", "compositionLength", "observedEnd", "suffix", "valueEnd", "dataAlreadySent", "settlesPending", "dispatchSessionEnd", "prevented", "event", "callback", "oldValue", "newValue", "diff", "dontRecurse", "cursorX", "cellHeight", "cursorTop", "cursorLeft", "maxWidth", "compositionViewBounds", "__decorateClass", "__decorateParam", "IBufferService", "IOptionsService", "ICoreService", "IRenderService", "$r", "$g", "$b", "$a", "NULL_COLOR", "channels", "toCss", "g", "b", "toPaddedHex", "toRgba", "toColor", "color", "blend", "bg", "fg", "fgR", "fgG", "fgB", "bgR", "bgG", "bgB", "css", "rgba", "isOpaque", "ensureContrastRatio", "ratio", "result", "opaque", "rgbaColor", "opacity", "multiplyOpacity", "factor", "toColorRGB", "$ctx", "$litmusColor", "canvas", "ctx", "rgbaMatch", "rgb", "relativeLuminance", "relativeLuminance2", "r", "rs", "gs", "bs", "rr", "rg", "rb", "bgRgba", "fgRgba", "bgL", "fgL", "contrastRatio", "resultA", "reduceLuminance", "resultARatio", "resultB", "increaseLuminance", "resultBRatio", "cr", "toChannels", "value", "c", "s", "l1", "l2", "JoinedCellData", "AttributeData", "firstCell", "chars", "width", "value", "CharacterJoinerService", "_bufferService", "CellData", "handler", "joiner", "joinerId", "i", "row", "line", "ranges", "lineStr", "trimmedLength", "rangeStartColumn", "currentStringIndex", "rangeStartStringIndex", "rangeAttrFG", "rangeAttrBG", "x", "joinedRanges", "startIndex", "endIndex", "lineData", "startCol", "text", "allJoinedRanges", "error", "joinerRanges", "j", "currentRangeIndex", "currentRangeStarted", "currentRange", "length", "newRange", "inRange", "range", "__decorateClass", "__decorateParam", "IBufferService", "throwIfFalsy", "value", "isPowerlineGlyph", "codepoint", "isBoxOrBlockGlyph", "codepoint", "treatGlyphAsBackgroundColor", "codepoint", "isPowerlineGlyph", "isBoxOrBlockGlyph", "createRenderDimensions", "createDimension", "DomRendererRowFactory", "_document", "_characterJoinerService", "_optionsService", "_coreBrowserService", "_coreService", "_decorationService", "_themeService", "CellData", "start", "end", "columnSelectMode", "lineData", "row", "isCursorRow", "cursorStyle", "cursorInactiveStyle", "cursorX", "cursorBlink", "blinkOn", "cellWidth", "widthCache", "linkStart", "linkEnd", "rowInfo", "elements", "joinedRanges", "colors", "lineLength", "charElement", "cellAmount", "text", "i", "oldBg", "oldFg", "oldExt", "oldLinkHover", "oldSpacing", "oldIsInSelection", "spacing", "skipJoinedCheckUntilX", "classes", "hasHover", "x", "width", "isJoined", "isValidJoinRange", "lastCharX", "cell", "range", "firstSelectionState", "JoinedCellData", "isInSelection", "isCursorCell", "isLinkHover", "isDecorated", "d", "chars", "AttributeData", "fg", "fgColorMode", "bg", "bgColorMode", "isInverse", "temp", "temp2", "bgOverride", "fgOverride", "isTop", "resolvedBg", "channels", "color", "element", "treatGlyphAsBackgroundColor", "cache", "adjustedColor", "ratio", "style", "y", "__decorateClass", "__decorateParam", "ICharacterJoinerService", "IOptionsService", "ICoreBrowserService", "ICoreService", "IDecorationService", "IThemeService", "WidthCache", "canvasFactory", "WidthCacheFontVariantCanvas", "font", "fontSize", "weight", "weightBold", "c", "bold", "italic", "cp", "width", "key", "variant", "throwIfFalsy", "fontFamily", "fontWeight", "fontStyle", "SelectionRenderModel", "terminal", "start", "end", "columnSelectMode", "viewportY", "viewportStartRow", "viewportEndRow", "viewportCappedStartRow", "viewportCappedEndRow", "x", "y", "createSelectionRenderModel", "TextBlinkStateManager", "Disposable", "_renderCallback", "_coreBrowserService", "_optionsService", "duration", "toDisposable", "needsBlinkInViewport", "isVisible", "wasBlinkOn", "nextTerminalId", "DomRenderer", "Disposable", "_terminal", "_document", "_element", "_screenElement", "_viewportElement", "_helperContainer", "_linkifier2", "instantiationService", "_charSizeService", "_optionsService", "_bufferService", "_coreService", "_coreBrowserService", "_themeService", "createSelectionRenderModel", "Emitter", "createRenderDimensions", "e", "DomRendererRowFactory", "CursorBlinkStateManager", "addDisposableListener", "toDisposable", "TextBlinkStateManager", "WidthCache", "dpr", "element", "styles", "colors", "color", "blinkAnimationUnderlineId", "blinkAnimationBarId", "blinkAnimationBlockId", "i", "c", "spacing", "cols", "rows", "row", "isVisible", "start", "end", "columnSelectMode", "oldViewportStart", "oldViewportEnd", "newViewportStart", "newViewportEnd", "viewportStartRow", "viewportEndRow", "viewportCappedStartRow", "viewportCappedEndRow", "documentFragment", "isXFlipped", "startCol", "endCol", "middleRowsCount", "finalEndCol", "renderStartRow", "renderEndRow", "cursorViewportRow", "colStart", "colEnd", "rowCount", "left", "width", "buffer", "cursorAbsoluteY", "cursorX", "cursorBlink", "cursorStyle", "cursorInactiveStyle", "rowInfo", "y", "rowElement", "lineData", "x", "x2", "y2", "enabled", "maxY", "bufferline", "hasBlinkingCells", "__decorateClass", "__decorateParam", "IInstantiationService", "ICharSizeService", "IOptionsService", "IBufferService", "ICoreService", "ICoreBrowserService", "IThemeService", "_rowContainer", "CharSizeService", "Disposable", "document", "parentElement", "_optionsService", "Emitter", "TextMetricsMeasureStrategy", "DomMeasureStrategy", "result", "__decorateClass", "__decorateParam", "IOptionsService", "BaseMeasureStategy", "Disposable", "width", "height", "DomMeasureStrategy", "_document", "_parentElement", "_optionsService", "TextMetricsMeasureStrategy", "a", "metrics", "CoreBrowserService", "Disposable", "_textarea", "_window", "mainDocument", "Emitter", "ScreenDprMonitor", "w", "EventUtils", "addDisposableListener", "value", "_parentWindow", "MutableDisposable", "toDisposable", "parentWindow", "LinkProviderService", "Disposable", "toDisposable", "linkProvider", "providerIndex", "getCoordsRelativeToElement", "window", "event", "element", "rect", "elementStyle", "leftPadding", "topPadding", "getCoords", "colCount", "rowCount", "hasValidCharSize", "cssCellWidth", "cssCellHeight", "isSelection", "coords", "MouseCoordsService", "_charSizeService", "_renderService", "event", "element", "colCount", "rowCount", "isSelection", "getCoords", "getWindow", "coords", "getCoordsRelativeToElement", "__decorateClass", "__decorateParam", "ICharSizeService", "IRenderService", "mainWindow", "tail", "array", "n", "memoize", "_target", "key", "descriptor", "fnKey", "fn", "memoizeKey", "descriptorAny", "args", "_LinkedListNode", "element", "LinkedListNode", "LinkedList", "atTheEnd", "newNode", "oldLast", "oldFirst", "didRemove", "node", "anchor", "EventType", "_Gesture", "Disposable", "targetWindow", "addDisposableListener", "e", "remove", "toDisposable", "timestamp", "i", "len", "touch", "evt", "activeTouchCount", "data", "holdTime", "finalX", "finalY", "deltaT", "deltaX", "deltaY", "dispatchTo", "t", "type", "initialTarget", "event", "currentTime", "setTapCount", "ignoreTarget", "targets", "target", "depth", "now", "a", "b", "t1", "vX", "dirX", "x", "vY", "dirY", "y", "scheduleAtNextAnimationFrame", "deltaPosX", "deltaPosY", "stopped", "d", "__decorateClass", "Gesture", "MouseService", "_renderService", "_mouseCoordsService", "_mouseStateService", "_coreService", "_bufferService", "_optionsService", "_selectionService", "_logService", "_coreBrowserService", "target", "register", "focus", "element", "document", "requestedEvents", "ctx", "eventListeners", "ev", "AltMouseCursorController", "events", "toDisposable", "addDisposableListener", "Gesture", "EventType", "e", "pos", "but", "action", "deltaY", "stripAltFromReport", "sequence", "cellHeight", "lines", "i", "amount", "dpr", "targetWheelEventPixels", "report", "e1", "e2", "pixels", "__decorateClass", "__decorateParam", "IRenderService", "IMouseCoordsService", "IMouseStateService", "ICoreService", "IBufferService", "IOptionsService", "ISelectionService", "ILogService", "ICoreBrowserService", "_element", "_document", "_isActive", "MutableDisposable", "store", "DisposableStore", "syncFromModifier", "targetWindow", "altHeld", "RenderDebouncer", "_renderCallback", "_coreBrowserService", "callback", "rowStart", "rowEnd", "rowCount", "start", "end", "TaskQueue", "logService", "task", "deadline", "taskDuration", "longestTask", "lastDeadlineRemaining", "deadlineRemaining", "PriorityTaskQueue", "callback", "identifier", "duration", "end", "IdleTaskQueueInternal", "IdleTaskQueue", "DebouncedIdleTask", "RenderService", "Disposable", "_rowCount", "screenElement", "_optionsService", "_logService", "_charSizeService", "_coreService", "decorationService", "bufferService", "_coreBrowserService", "themeService", "MutableDisposable", "Emitter", "DebouncedIdleTask", "RenderDebouncer", "start", "end", "SynchronizedOutputHandler", "toDisposable", "w", "observer", "e", "entry", "sync", "isRedrawOnly", "buffered", "cols", "rows", "renderer", "callback", "columnSelectMode", "__decorateClass", "__decorateParam", "IOptionsService", "ILogService", "ICharSizeService", "ICoreService", "IDecorationService", "IBufferService", "ICoreBrowserService", "IThemeService", "_onTimeout", "result", "moveToCellSequence", "targetX", "targetY", "bufferService", "applicationCursor", "startX", "startY", "resetStartingRow", "moveToRequestedRow", "moveToRequestedCol", "direction", "repeat", "sequence", "rowDifference", "cellsToMove", "colsFromRowEnd", "colsFromRowBeginning", "currX", "bufferLine", "wrappedRowsForRow", "startRow", "endRow", "rowsToMove", "wrappedRowsCount", "verticalDirection", "horizontalDirection", "wrappedRows", "i", "currentRow", "rowCount", "line", "lineWraps", "startCol", "endCol", "forward", "currentCol", "bufferStr", "mod", "count", "str", "rpt", "SelectionModel", "_bufferService", "startPlusLength", "start", "end", "amount", "getRangeLength", "range", "bufferCols", "NON_BREAKING_SPACE_CHAR", "ALL_NON_BREAKING_SPACE_REGEX", "SelectionService", "Disposable", "_element", "_screenElement", "_linkifier", "_bufferService", "_coreService", "_mouseCoordsService", "_optionsService", "_mouseStateService", "_renderService", "_coreBrowserService", "MutableDisposable", "CellData", "Emitter", "event", "amount", "e", "SelectionModel", "toDisposable", "start", "end", "buffer", "result", "startCol", "endCol", "i", "lineText", "startRowEndCol", "bufferLine", "line", "ALL_NON_BREAKING_SPACE_REGEX", "isWindows", "isLinuxMouseSelection", "isLinux", "coords", "x", "y", "allowWhitespaceOnlySelection", "range", "getRangeLength", "offset", "getCoordsRelativeToElement", "terminalHeight", "isMac", "hadSelection", "previousSelectionEnd", "timeElapsed", "coordinates", "sequence", "moveToCellSequence", "hasSelection", "charIndex", "length", "col", "row", "ev", "followWrappedLinesAbove", "followWrappedLinesBelow", "startIndex", "endIndex", "charOffset", "leftWideCharCount", "rightWideCharCount", "leftLongCharOffset", "rightLongCharOffset", "previousBufferLine", "previousLineWordPosition", "nextBufferLine", "nextLineWordPosition", "wordPosition", "endRow", "cell", "wrappedRange", "__decorateClass", "__decorateParam", "IBufferService", "ICoreService", "IMouseCoordsService", "IOptionsService", "IMouseStateService", "IRenderService", "ICoreBrowserService", "TwoKeyMap", "first", "second", "value", "ColorContrastCache", "TwoKeyMap", "bg", "fg", "value", "DEFAULT_ANSI_COLORS", "colors", "css", "v", "i", "r", "g", "b", "channels", "c", "DEFAULT_FOREGROUND", "css", "DEFAULT_BACKGROUND", "DEFAULT_CURSOR", "DEFAULT_CURSOR_ACCENT", "DEFAULT_SELECTION", "DEFAULT_OVERVIEW_RULER_BORDER", "ThemeService", "Disposable", "_optionsService", "ColorContrastCache", "Emitter", "color", "DEFAULT_ANSI_COLORS", "theme", "colors", "parseColor", "NULL_COLOR", "colorCount", "i", "slot", "callback", "__decorateClass", "__decorateParam", "IOptionsService", "cssString", "fallback", "KEYCODE_KEY_MAPPINGS", "evaluateKeyboardEvent", "ev", "applicationCursorMode", "isMac", "macOptionIsMeta", "result", "modifiers", "key", "keyCode", "keyString", "KittyKeyboard", "ev", "suffix", "mods", "macOptionAsAlt", "numpadCode", "modifierCode", "funcCode", "digit", "code", "letter", "modifiers", "eventType", "reportEventTypes", "needsEventType", "seq", "number", "keyCode", "flags", "isFunc", "isMod", "reportAlternateKeys", "shiftedKey", "textCode", "result", "csiLetter", "ss3Letter", "tildeCode", "specialKey", "legacyByte", "Win32InputMode", "ev", "vk", "controlChar", "codePoint", "state", "isKeyDown", "sc", "uc", "kd", "cs", "KeyboardService", "_coreService", "_optionsService", "Win32InputMode", "KittyKeyboard", "event", "kittyFlags", "isMac", "evaluateKeyboardEvent", "__decorateClass", "__decorateParam", "ICoreService", "IOptionsService", "ServiceCollection", "entries", "id", "service", "instance", "result", "callback", "key", "value", "InstantiationService", "IInstantiationService", "ctor", "args", "serviceDependencies", "getServiceDependencies", "a", "b", "serviceArgs", "dependency", "firstServiceArgPos", "optionsKeyToLogLevel", "LOG_PREFIX", "LogService", "Disposable", "_optionsService", "optionalParams", "i", "type", "message", "__decorateClass", "__decorateParam", "IOptionsService", "CircularList", "Disposable", "_maxLength", "Emitter", "newMaxLength", "newArray", "i", "newLength", "index", "value", "start", "deleteCount", "items", "countToTrim", "count", "offset", "expandListBy", "StringBuilder", "chunk", "LimitedStringBuilder", "_limit", "DEFAULT_ATTR_DATA", "AttributeData", "$startIndex", "$workCell", "CellData", "$translateToStringBuilder", "StringBuilder", "BufferLine", "_BufferLine", "_stringCache", "cols", "fillCellData", "isWrapped", "cell", "i", "index", "content", "cp", "stringFromCodePoint", "value", "codePoint", "width", "attrs", "pos", "n", "start", "end", "respectProtect", "uint32Cells", "data", "keys", "key", "extKeys", "line", "newLine", "src", "srcCol", "destCol", "length", "applyInReverse", "srcData", "trimRight", "startCol", "endCol", "outColumns", "isCanonicalRequest", "stringCacheEntry", "chars", "result", "cacheEntry", "createIfNeeded", "cachedEntry", "srcStart", "BufferLineStringCache", "Disposable", "MutableDisposable", "toDisposable", "entry", "timeoutMs", "disposableTimeout", "elapsed", "reflowLargerGetLinesToRemove", "lines", "oldCols", "newCols", "bufferAbsoluteY", "nullCell", "reflowCursorLine", "toRemove", "y", "i", "nextLine", "wrappedLines", "destLineIndex", "destCol", "getWrappedLineTrimmedLength", "srcLineIndex", "srcCol", "srcTrimmedTineLength", "srcRemainingCells", "destRemainingCells", "cellsToCopy", "countToRemove", "reflowLargerCreateNewLayout", "layout", "nextToRemoveIndex", "nextToRemoveStart", "countRemovedSoFar", "reflowLargerApplyNewLayout", "newLayout", "newLayoutLines", "reflowSmallerGetNewLineLengths", "newLineLengths", "cellsNeeded", "srcLine", "cellsAvailable", "oldTrimmedLength", "endsWithWide", "lineLength", "cols", "endsInNull", "followingLineStartsWithWide", "_Marker", "line", "Emitter", "dispose", "disposable", "Marker", "CHARSETS", "DEFAULT_CHARSET", "MAX_BUFFER_SIZE", "Buffer", "Disposable", "_hasScrollback", "_optionsService", "_bufferService", "_logService", "DEFAULT_ATTR_DATA", "DEFAULT_CHARSET", "CellData", "CircularList", "IdleTaskQueue", "toDisposable", "BufferLineStringCache", "attr", "ExtendedAttrs", "isWrapped", "BufferLine", "relativeY", "rows", "correctBufferLength", "fillAttr", "i", "newCols", "newRows", "nullCell", "dirtyMemoryLines", "newMaxLength", "addToY", "y", "amountToTrim", "maxY", "normalRun", "counted", "windowsPty", "reflowCursorLine", "toRemove", "reflowLargerGetLinesToRemove", "newLayoutResult", "reflowLargerCreateNewLayout", "reflowLargerApplyNewLayout", "countRemoved", "viewportAdjustments", "toInsert", "countToInsert", "nextLine", "wrappedLines", "absoluteY", "lastLineLength", "destLineLengths", "reflowSmallerGetNewLineLengths", "linesToAdd", "trimmedLines", "newLines", "newLine", "destLineIndex", "destCol", "srcLineIndex", "srcCol", "cellsToCopy", "wrappedLinesIndex", "getWrappedLineTrimmedLength", "insertEvents", "originalLines", "originalLinesLength", "originalLineIndex", "nextToInsertIndex", "nextToInsert", "countInsertedSoFar", "nextI", "insertCountEmitted", "lineIndex", "trimRight", "startCol", "endCol", "line", "first", "last", "x", "marker", "Marker", "amount", "event", "BufferSet", "Disposable", "_optionsService", "_bufferService", "_logService", "MutableDisposable", "Emitter", "Buffer", "fillAttr", "newCols", "newRows", "i", "BufferService", "Disposable", "optionsService", "logService", "Emitter", "BufferSet", "e", "cols", "rows", "colsChanged", "rowsChanged", "eraseAttr", "isWrapped", "buffer", "newLine", "topRow", "bottomRow", "willBufferBeTrimmed", "scrollRegionHeight", "disp", "suppressScrollEvent", "oldYdisp", "__decorateClass", "__decorateParam", "IOptionsService", "ILogService", "DEFAULT_OPTIONS", "isMac", "FONT_WEIGHT_OPTIONS", "OptionsService", "Disposable", "options", "Emitter", "defaultOptions", "key", "newValue", "e", "toDisposable", "listener", "eventKey", "keys", "getter", "propName", "setter", "value", "desc", "isCursorStyle", "DEFAULT_MODES", "DEFAULT_DEC_PRIVATE_MODES", "DEFAULT_KITTY_KEYBOARD_STATE", "CoreService", "Disposable", "_bufferService", "_logService", "_optionsService", "Emitter", "data", "wasUserInput", "buffer", "e", "__decorateClass", "__decorateParam", "IBufferService", "ILogService", "IOptionsService", "DEFAULT_PROTOCOLS", "e", "eventCode", "e", "isSGR", "code", "S", "DEFAULT_ENCODINGS", "params", "final", "MouseStateService", "Disposable", "Emitter", "name", "DEFAULT_PROTOCOLS", "protocol", "encoding", "customWheelEventHandler", "ev", "UnicodeService", "_UnicodeService", "Emitter", "value", "state", "width", "shouldJoin", "version", "provider", "num", "s", "result", "precedingInfo", "length", "i", "code", "second", "currentInfo", "chWidth", "codepoint", "preceding", "BMP_COMBINING", "HIGH_COMBINING", "table", "bisearch", "ucs", "data", "min", "max", "mid", "UnicodeV6", "r", "num", "codepoint", "preceding", "width", "shouldJoin", "oldWidth", "UnicodeService", "CharsetService", "g", "charset", "updateWindowsModeWrappedState", "bufferService", "lastChar", "nextLine", "Params", "_Params", "maxLength", "maxSubParamsLength", "values", "params", "i", "value", "k", "newParams", "res", "start", "end", "idx", "result", "length", "store", "cur", "EMPTY_HANDLERS", "OscParser", "ident", "handler", "handlerList", "handlerIndex", "j", "data", "start", "end", "utf32ToString", "code", "success", "promiseResult", "handlerResult", "fallThrough", "_OscHandler", "_handler", "LimitedStringBuilder", "ret", "res", "OscHandler", "EMPTY_HANDLERS", "DcsParser", "ident", "handler", "handlerList", "handlerIndex", "j", "params", "data", "start", "end", "utf32ToString", "success", "promiseResult", "handlerResult", "fallThrough", "EMPTY_PARAMS", "Params", "_DcsHandler", "_handler", "LimitedStringBuilder", "ret", "res", "DcsHandler", "EMPTY_HANDLERS", "ApcParser", "ident", "handler", "handlerList", "handlerIndex", "j", "data", "start", "end", "utf32ToString", "success", "promiseResult", "handlerResult", "fallThrough", "_ApcHandler", "_handler", "LimitedStringBuilder", "ret", "res", "ApcHandler", "TransitionTable", "length", "action", "next", "code", "state", "codes", "i", "NON_ASCII_PRINTABLE", "VT500_TRANSITION_TABLE", "table", "blueprint", "unused", "r", "start", "end", "PRINTABLES", "EXECUTABLES", "states", "EscapeSequenceParser", "Disposable", "_transitions", "Params", "data", "ident", "params", "toDisposable", "OscParser", "DcsParser", "ApcParser", "id", "finalRange", "res", "intermediate", "finalCode", "handler", "handlerList", "handlerIndex", "flag", "callback", "handlers", "handlerPos", "transition", "chunkPos", "promiseResult", "handlerResult", "k", "ch", "csiDone", "j", "c", "l4", "handlersEsc", "jj", "RGB_REX", "HASH_REX", "parseColor", "data", "low", "m", "base", "adv", "result", "i", "c", "pad", "bits", "s", "s2", "toRgbString", "color", "r", "g", "b", "XTERM_VERSION", "GLEVEL", "paramToWindowOption", "opts", "$temp", "InputHandler", "Disposable", "_bufferService", "_charsetService", "_coreService", "_logService", "_optionsService", "_oscLinkService", "_mouseStateService", "_unicodeService", "_parser", "EscapeSequenceParser", "StringToUtf32", "Utf8ToUtf32", "DEFAULT_ATTR_DATA", "Emitter", "DirtyRowTracker", "e", "ident", "params", "code", "identifier", "action", "data", "payload", "start", "end", "OscHandler", "flag", "CHARSETS", "state", "DcsHandler", "cursorStartX", "cursorStartY", "decodedLength", "position", "p", "slowTimeout", "slowPromise", "_res", "rej", "err", "promiseResult", "result", "wasPaused", "i", "len", "viewportEnd", "viewportStart", "chWidth", "charset", "screenReaderMode", "cols", "wraparoundMode", "insertMode", "curAttr", "bufferRow", "precedingJoinState", "pos", "ch", "currentInfo", "UnicodeService", "shouldJoin", "oldWidth", "stringFromCodePoint", "linkId", "oldRow", "oldCol", "BufferLine", "offset", "delta", "id", "callback", "paramToWindowOption", "ApcHandler", "line", "originalX", "maxCol", "x", "y", "diffToTop", "diffToBottom", "param", "clearWrap", "respectProtect", "j", "nextLine", "scrollBackSize", "row", "scrollBottomRowsOffset", "scrollBottomAbsolute", "joinState", "length", "text", "idata", "itext", "tlength", "XTERM_VERSION", "term", "DEFAULT_CHARSET", "ansi", "V", "dm", "mouseProtocol", "mouseEncoding", "cs", "buffers", "active", "alt", "opts", "f", "m", "v", "b2v", "value", "color", "mode", "c1", "c2", "c3", "AttributeData", "attr", "accu", "cSpace", "advance", "subparams", "style", "l", "isBlinking", "top", "bottom", "second", "event", "slots", "idx", "spec", "index", "isValidColorIndex", "parseColor", "uri", "parsedParams", "idParamIndex", "collectAndFlag", "GLEVEL", "scrollRegionHeight", "level", "cell", "CellData", "yOffset", "s", "b", "STYLES", "y1", "y2", "flags", "stack", "count", "__decorateClass", "__decorateParam", "IBufferService", "WriteBuffer", "Disposable", "_action", "TimeoutTimer", "Emitter", "toDisposable", "chunk", "didProcess", "cb", "data", "maxSubsequentCalls", "callback", "lastTime", "promiseResult", "startTime", "result", "continuation", "r", "err", "OscLinkService", "_bufferService", "data", "buffer", "marker", "entry", "castData", "key", "match", "linkId", "y", "e", "linkData", "index", "__decorateClass", "__decorateParam", "IBufferService", "hasWriteSyncWarnHappened", "CoreTerminal", "Disposable", "options", "MutableDisposable", "Emitter", "InstantiationService", "OptionsService", "IOptionsService", "LogService", "ILogService", "BufferService", "IBufferService", "CoreService", "ICoreService", "MouseStateService", "IMouseStateService", "UnicodeService", "UnicodeV6", "IUnicodeService", "CharsetService", "ICharsetService", "OscLinkService", "IOscLinkService", "InputHandler", "EventUtils", "WriteBuffer", "data", "promiseResult", "ev", "key", "callback", "maxSubsequentCalls", "wasUserInput", "x", "y", "eraseAttr", "isWrapped", "disp", "suppressScrollEvent", "pageCount", "disableSmoothScroll", "line", "scrollAmount", "id", "ident", "value", "windowsPty", "disposables", "updateWindowsModeWrappedState", "toDisposable", "d", "i", "SortedList", "_getKey", "logService", "IdleTaskQueue", "value", "sortedAddedValues", "a", "b", "sortedAddedValuesIndex", "arrayIndex", "newArray", "newArrayIndex", "key", "sortedDeletedIndices", "sortedDeletedIndicesIndex", "callback", "min", "max", "mid", "midKey", "$xmin", "$xmax", "DecorationService", "Disposable", "_logService", "_bufferService", "DecorationLineCache", "Emitter", "SortedList", "e", "toDisposable", "options", "decoration", "Decoration", "markerDispose", "listener", "d", "x", "line", "layer", "bucket", "callback", "__decorateClass", "__decorateParam", "ILogService", "IBufferService", "MutableDisposable", "MicrotaskTimer", "lines", "store", "DisposableStore", "amount", "event", "start", "height", "index", "callbacks", "cb", "newMap", "newLine", "existing", "i", "len", "spanCrossers", "deleteEnd", "toReindex", "css", "RENDER_DEBOUNCE_THRESHOLD_MS", "TimeBasedDebouncer", "_renderCallback", "_debounceThresholdMS", "rowStart", "rowEnd", "rowCount", "refreshRequestTime", "elapsed", "waitPeriodBeforeTrailingRefresh", "start", "end", "DEBUG", "AccessibilityManager", "Disposable", "_terminal", "instantiationService", "_coreBrowserService", "_renderService", "doc", "i", "e", "TimeBasedDebouncer", "char", "spaceCount", "addDisposableListener", "toDisposable", "tooMuchOutput", "keyChar", "start", "end", "buffer", "setSize", "line", "columns", "lineData", "posInSet", "element", "position", "boundaryElement", "beforeBoundaryElement", "lastRowPos", "topBoundaryElement", "bottomBoundaryElement", "newElement", "selection", "begin", "lastRowElement", "toRowColumn", "node", "offset", "rowElement", "row", "column", "beginRowColumn", "endRowColumn", "rows", "width", "lastColumn", "targetWidth", "__decorateClass", "__decorateParam", "IInstantiationService", "ICoreBrowserService", "IRenderService", "Linkifier", "Disposable", "_element", "_mouseCoordsService", "_renderService", "_bufferService", "_linkProviderService", "Emitter", "toDisposable", "dispose", "addDisposableListener", "event", "position", "composedPath", "i", "target", "useLineCache", "reply", "linkWithState", "linkProvided", "linkProvider", "links", "linksWithState", "link", "y", "replies", "occupiedCells", "providerReply", "startX", "endX", "x", "index", "hasLinkBefore", "j", "linkAtPosition", "currentLink", "linkEquals", "startRow", "endRow", "v", "e", "start", "end", "element", "showEvent", "range", "scrollOffset", "lower", "upper", "current", "coords", "x1", "y1", "x2", "y2", "fg", "__decorateClass", "__decorateParam", "IMouseCoordsService", "IRenderService", "IBufferService", "ILinkProviderService", "a", "b", "CoreBrowserTerminal", "CoreTerminal", "options", "MutableDisposable", "Platform_exports", "Emitter", "DecorationService", "IDecorationService", "KeyboardService", "IKeyboardService", "LinkProviderService", "ILinkProviderService", "OscLinkProvider", "e", "type", "event", "EventUtils", "toDisposable", "dimensions", "req", "acc", "ident", "colorRgb", "color", "toRgbString", "colors", "channels", "narrowedAcc", "bgLuminance", "rgb", "fgLuminance", "colorSchemeMode", "value", "AccessibilityManager", "ev", "CompositionHelper", "cursorY", "bufferLine", "cursorX", "cellHeight", "width", "cellWidth", "cursorTop", "cursorLeft", "addDisposableListener", "copyHandler", "pasteHandlerWrapper", "handlePasteEvent", "isFirefox", "rightClickHandler", "isLinux", "moveTextAreaUnderMouseCursor", "parent", "fragment", "textarea", "promptLabel", "isChromeOS", "CoreBrowserService", "ICoreBrowserService", "CharSizeService", "ICharSizeService", "ThemeService", "IThemeService", "CharacterJoinerService", "ICharacterJoinerService", "RenderService", "IRenderService", "MouseCoordsService", "IMouseCoordsService", "linkifier", "Linkifier", "Viewport", "SelectionService", "ISelectionService", "MouseService", "IMouseService", "text", "BufferDecorationRenderer", "showScrollbar", "overviewRulerWidth", "OverviewRulerRenderer", "shouldShow", "amount", "disposable", "DomRenderer", "start", "end", "sync", "disp", "suppressScrollEvent", "pageCount", "disableSmoothScroll", "line", "scrollAmount", "data", "paste", "customKeyEventHandler", "customWheelEventHandler", "linkProvider", "handler", "joinerId", "cursorYOffset", "decorationOptions", "column", "row", "length", "shouldIgnoreComposition", "result", "scrollCount", "wasModifierOnly", "wasModifierKeyOnlyEvent", "browser", "thirdLevelKey", "key", "x", "y", "i", "DEFAULT_ATTR_DATA", "canvasWidth", "canvasHeight", "AddonManager", "terminal", "instance", "loadedAddon", "index", "i", "BufferLineApiView", "_line", "x", "cell", "CellData", "trimRight", "startColumn", "endColumn", "BufferApiView", "_buffer", "type", "buffer", "y", "line", "BufferLineApiView", "CellData", "BufferNamespaceApi", "Disposable", "_core", "Emitter", "BufferApiView", "ParserApi", "_core", "id", "callback", "params", "data", "handler", "ident", "UnicodeApi", "_core", "provider", "version", "CONSTRUCTOR_ONLY_OPTIONS", "$value", "Terminal", "Disposable", "options", "CoreBrowserTerminal", "AddonManager", "getter", "propName", "setter", "value", "desc", "ParserApi", "UnicodeApi", "BufferNamespaceApi", "m", "mouseTrackingMode", "data", "wasUserInput", "columns", "rows", "parent", "customKeyEventHandler", "customWheelEventHandler", "linkProvider", "handler", "joinerId", "cursorYOffset", "decorationOptions", "column", "row", "length", "start", "end", "amount", "pageCount", "line", "callback", "addon", "promptLabel", "tooMuchOutput", "values"] } diff --git a/src/browser/CoreBrowserTerminal.ts b/src/browser/CoreBrowserTerminal.ts index 4557e1652c34737fdf853436bd9328d9918eee2b..aff6ba624523849c2a39878a2181cbd1e931791d 100644 --- a/src/browser/CoreBrowserTerminal.ts +++ b/src/browser/CoreBrowserTerminal.ts -@@ -322,12 +322,15 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { - /** - * Binds the desired blur behavior on a given terminal object. - */ +@@ -325,6 +325,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { private _handleTextAreaBlur(): void { // Text can safely be removed on blur. Doing it earlier could interfere with // screen readers reading it out. @@ -79,13 +72,7 @@ index 4557e1652c34737fdf853436bd9328d9918eee2b..aff6ba624523849c2a39878a2181cbd1 this.textarea!.value = ''; this.refresh(this.buffer.y, this.buffer.y); if (this.coreService.decPrivateModes.sendFocus) { - this.coreService.triggerDataEvent(C0.ESC + '[O'); - } - this.element!.classList.remove('focus'); -@@ -422,13 +425,24 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { - // until it is hidden and a custom move occurs. - this._syncTextArea(); - this._compositionHelper!.compositionstart(); +@@ -425,7 +428,18 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { this._compositionHelper!.updateCompositionElements(); })); this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e))); @@ -105,15 +92,7 @@ index 4557e1652c34737fdf853436bd9328d9918eee2b..aff6ba624523849c2a39878a2181cbd1 this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true)); this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements())); } -- -+ - /** - * Opens the terminal within an element. -@@ -548,12 +562,17 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { - }))); - this.onResize(e => this._renderService!.resize(e.cols, e.rows)); -- -+ +@@ -551,6 +565,11 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { this._compositionView = this._document.createElement('div'); this._compositionView.classList.add('composition-view'); this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView); @@ -123,38 +102,20 @@ index 4557e1652c34737fdf853436bd9328d9918eee2b..aff6ba624523849c2a39878a2181cbd1 + } + })); this._helperContainer.appendChild(this._compositionView); -- -+ + this._mouseCoordsService = this._instantiationService.createInstance(MouseCoordsService); - this._instantiationService.setService(IMouseCoordsService, this._mouseCoordsService); -- -+ - const linkifier = this._linkifier.value = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement)); -@@ -1005,13 +1024,15 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { - } -- -+ - key = String.fromCharCode(key); -- -+ +@@ -1008,7 +1027,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { + this._onKey.fire({ key, domEvent: ev }); this._showCursor(); - this.coreService.triggerDataEvent(key, true); + if (!this._compositionHelper!.keypress?.(key)) { + this.coreService.triggerDataEvent(key, true); + } -- -+ + this._keyPressHandled = true; -- -+ - // The key was handled so clear the dead key state, otherwise certain keystrokes like arrow - // keys could be ignored - this._unprocessedDeadKey = false; -@@ -1023,12 +1044,21 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { - * Handle an input event. - * Key Resources: - * - https://developer.mozilla.org/en-US/docs/Web/API/InputEvent + +@@ -1026,6 +1047,15 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { * @param ev The input event to be handled. */ protected _inputEvent(ev: InputEvent): boolean { @@ -170,18 +131,11 @@ index 4557e1652c34737fdf853436bd9328d9918eee2b..aff6ba624523849c2a39878a2181cbd1 // Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to // support reading out character input which can doubling up input characters // Based on these event traces: https://github.com/xtermjs/xterm.js/issues/3679 - if (ev.data && ev.inputType === 'insertText' && (!ev.composed || !this._keyDownSeen) && !this.optionsService.rawOptions.screenReaderMode) { - if (this._keyPressHandled) { - return false; diff --git a/src/browser/Types.ts b/src/browser/Types.ts index 497afcf535f3eaca00889525a77e15eb633ccd96..96d499b34605f860608382114c3fbdc07dc6b07f 100644 --- a/src/browser/Types.ts +++ b/src/browser/Types.ts -@@ -38,15 +38,16 @@ export type CustomWheelEventHandler = (event: WheelEvent) => boolean; - export type LineData = CharData[]; -- -+ - export interface ICompositionHelper { +@@ -41,9 +41,10 @@ export interface ICompositionHelper { readonly isComposing: boolean; compositionstart(): void; compositionupdate(ev: CompositionEvent): void; @@ -191,25 +145,16 @@ index 497afcf535f3eaca00889525a77e15eb633ccd96..96d499b34605f860608382114c3fbdc0 keydown(ev: KeyboardEvent): boolean; + keypress?(text: string): boolean; } -- -+ + export interface IBrowser { - isNode: boolean; - userAgent: string; - platform: string; diff --git a/src/browser/input/CompositionHelper.ts b/src/browser/input/CompositionHelper.ts -index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a859dedb166 100644 +index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..f1e96c7634a026fcee525e8894e534ce162b2b5a 100644 --- a/src/browser/input/CompositionHelper.ts +++ b/src/browser/input/CompositionHelper.ts -@@ -9,114 +9,281 @@ import { C0 } from '../../common/data/EscapeSequences'; -- -+ - interface IPosition { - start: number; +@@ -12,6 +12,28 @@ interface IPosition { end: number; } -- -+ + +interface IPendingComposition { + transactionId: number; + finalizerTimer?: ReturnType; @@ -235,12 +180,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 /** * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend * events, displaying the in-progress composition to the UI and forwarding the final composition - * to the handler. - */ - export class CompositionHelper { - /** - * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or - * IME. This variable determines whether the compositionText should be displayed on the UI. +@@ -24,6 +46,15 @@ export class CompositionHelper { */ private _isComposing: boolean; public get isComposing(): boolean { return this._isComposing; } @@ -253,21 +193,13 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + public get _pendingKeypressData(): string { + return this._pendingComposition?.keypressData ?? ''; + } -- -+ + /** * The position within the input textarea's value of the current composition. - */ - private _compositionPosition: IPosition; -- -+ - /** - * Text that existed after the composing range when composition started. - * This is used to avoid treating existing trailing text as new input. +@@ -36,22 +67,48 @@ export class CompositionHelper { */ private _compositionSuffix: string; -- -+ + - /** - * Whether a composition is in the process of being sent, setting this to false will cancel any - * in-progress composition. @@ -278,8 +210,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 * Data already sent due to keydown event. */ private _dataAlreadySent: string; -- -+ + + private _pendingComposition?: IPendingComposition; + + private _isAwaitingCompositionEnd: boolean; @@ -300,8 +231,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 * The pending textarea change timer, if any. */ private _textareaChangeTimer?: number; -- -+ + + /** + * Identifies the composition transaction that owns deferred work. + */ @@ -321,9 +251,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 constructor( private readonly _textarea: HTMLTextAreaElement, private readonly _compositionView: HTMLElement, - @IBufferService private readonly _bufferService: IBufferService, - @IOptionsService private readonly _optionsService: IOptionsService, - @ICoreService private readonly _coreService: ICoreService, +@@ -61,27 +118,58 @@ export class CompositionHelper { @IRenderService private readonly _renderService: IRenderService ) { this._isComposing = false; @@ -340,8 +268,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + this._compositionTransactionId = 0; + this._compositionTimers = new Set(); } -- -+ + /** * Handles the compositionstart event, activating the composition view. */ @@ -353,11 +280,6 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + this._compositionViewTimer = undefined; + this._cancelDeferredTimer(this._compositionEndTimer); + this._compositionEndTimer = undefined; -+ if (this._pendingComposition) { -+ this._cancelPendingFinalizer(this._pendingComposition); -+ this._endPendingCompositionSession(this._pendingComposition); -+ this._settlePendingComposition(this._pendingComposition); -+ } + if (this._textareaChangeTimer !== undefined) { + clearTimeout(this._textareaChangeTimer); + this._textareaChangeTimer = undefined; @@ -388,10 +310,9 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + detail: { id: this._compositionTransactionId } + })); } -- -+ + /** - * Handles the compositionupdate event, updating the composition view. +@@ -89,22 +177,87 @@ export class CompositionHelper { * @param ev The event. */ public compositionupdate(ev: Pick): void { @@ -420,8 +341,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + } + }); } -- -+ + /** * Handles the compositionend event, hiding the composition view and sending the composition to * the handler. @@ -485,11 +405,9 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + this._isComposing = false; + this._compositionTransactionId++; } -- -+ + /** - * Handles the keydown event, routing any necessary events to the CompositionHelper functions. - * @param ev The keydown event. +@@ -113,7 +266,16 @@ export class CompositionHelper { * @returns Whether the Terminal should continue processing the keydown event. */ public keydown(ev: KeyboardEvent): boolean { @@ -507,18 +425,10 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 if (ev.keyCode === 20 || ev.keyCode === 229) { // 20 is CapsLock, 229 is Enter // Continue composing if the keyCode is the "composition character" - return false; - } - if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { -@@ -135,75 +302,391 @@ export class CompositionHelper { - return false; - } -- -+ +@@ -138,6 +300,54 @@ export class CompositionHelper { return true; } -- -+ + + /** + * Defers keypress text while a composition finalizer is pending so all input is emitted once + * after reconciliation with the final textarea candidate. @@ -570,8 +480,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 /** * Finalizes the composition, resuming regular input actions. This is called when a composition * is ending. - * @param waitForPropagation Whether to wait for events to propagate before sending - * the input. This should be false if a non-composition keystroke is entered before the +@@ -146,23 +356,49 @@ export class CompositionHelper { * compositionend event is triggered, such as enter, so that the composition is sent before * the command is executed. */ @@ -583,8 +492,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + if (waitForPropagation && !wasComposing) { + return; + } -- -+ + if (!waitForPropagation) { - // Cancel any delayed composition send requests and send the input immediately. - this._isSendingComposition = false; @@ -630,13 +538,10 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 - const currentCompositionSuffix = this._compositionSuffix; + this._updatePostCompositionInputExpectation(pending); + this._pendingComposition = pending; -- -+ + // Since composition* events happen before the changes take place in the textarea on most // browsers, use a setTimeout with 0ms time to allow the native compositionend event to - // complete. This ensures the correct character is retrieved. - // This solution was used because: - // - The compositionend event's data property is unreliable, at least on Chromium +@@ -172,35 +408,280 @@ export class CompositionHelper { // - The last compositionupdate event's data property does not always accurately describe // the character, a counter example being Korean where an ending consonsant can move to // the following character if the following input is a vowel. @@ -673,8 +578,7 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + } + if (this._pendingComposition === pending) { + this._sendPendingComposition(pending, true); - } -- }, 0); ++ } + }); + } + } @@ -692,8 +596,11 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + pending.inputData || pending.keypressData, + pending.dataAlreadySent + ); ++ // Why: with no textarea, end, input, or keypress evidence the composition ++ // was cancelled (e.g. Backspace over the whole preedit); stale ++ // compositionupdate data must not be replayed as committed text. + const input = this._mergeTextObservations( -+ textareaInput || pending.endData || pending.compositionData, ++ textareaInput || pending.endData || (observedInput ? pending.compositionData : ''), + observedInput, + pending.keypressMayOverlapComposition + ); @@ -862,7 +769,8 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + id: pending.transactionId, + data: input, + dataPendingReconciliation: true -+ } + } +- }, 0); + } + )); + } @@ -939,19 +847,11 @@ index c9ec396ab66cb966d49aa63bed09cdf9cd6c4246..ef545ca0abfbda2a058e1dbe1e1c6a85 + clearTimeout(timer); + this._compositionTimers.delete(timer); } -- -+ + /** - * Apply any changes made to the textarea after the current event chain is allowed to complete. - * This should be called when not currently composing but a keydown event with the "composition - * character" (229) is triggered, in order to allow non-composition text to be entered when an -@@ -275,10 +758,11 @@ export class CompositionHelper { - this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px'; - this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px'; - this._textarea.style.lineHeight = compositionViewBounds.height + 'px'; +@@ -278,7 +759,8 @@ export class CompositionHelper { } -- -+ + if (!dontRecurse) { - setTimeout(() => this.updateCompositionElements(true), 0); + this._cancelDeferredTimer(this._compositionViewTimer); @@ -963,10 +863,7 @@ diff --git a/src/common/SortedList.ts b/src/common/SortedList.ts index 8a10076e3963e33b4a7d1e4602333eb3f4772dc9..df0761c35907ddc48eb102ba181b0dac8e61f00d 100644 --- a/src/common/SortedList.ts +++ b/src/common/SortedList.ts -@@ -84,12 +84,30 @@ export class SortedList { - return false; - } - const key = this._getKey(value); +@@ -87,6 +87,24 @@ export class SortedList { if (key === undefined) { return false; } @@ -991,6 +888,3 @@ index 8a10076e3963e33b4a7d1e4602333eb3f4772dc9..df0761c35907ddc48eb102ba181b0dac i = this._search(key); if (i === -1) { return false; - } - if (this._getKey(this._array[i]) !== key) { - return false; diff --git a/config/reliability-gates.jsonc b/config/reliability-gates.jsonc index 343ff1c6ac7..ad6fdd1550c 100644 --- a/config/reliability-gates.jsonc +++ b/config/reliability-gates.jsonc @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "updatedAt": "2026-08-01", + "updatedAt": "2026-08-03", "policy": { "maturityLevels": ["experimental", "soak", "blocking", "accepted-gap", "deprecated"], "blockingPromotion": { @@ -10,6 +10,101 @@ } }, "gates": [ + { + "id": "editor.restored-sibling-owner-reparent", + "title": "Restored sibling tabs migrate filesystem authority before becoming editable", + "maturity": "experimental", + "protection": "partial", + "owner": "editor-runtime", + "layer": "renderer-store-controller-contract", + "surfaces": [ + "restored editor tabs", + "editor save and autosave", + "filesystem watches and hot-exit persistence" + ], + "platforms": ["macos", "linux", "windows"], + "providers": ["local", "ssh", "paired-runtime"], + "coveredPlatforms": ["macos"], + "coveredProviders": ["local", "ssh", "paired-runtime"], + "coverageNotes": "Deterministic store/controller tests cover local, direct-SSH, paired-runtime identity, folder workspaces, queue quiescence, stale route and connection-generation rejection, authoritative active-workspace projection, owner-derived IDs, drafts and editor maps, tab/group placement, exact watch replacement, change/delete/rename correlation, explicit save, autosave, collision refusal without activation reconciliation, provenance, and restart hot-exit persistence. Live headed/headless paired-runtime and post-establish Electron IPC remain uncollected.", + "motivatingLinks": [ + "https://github.com/stablyai/orca/issues/11304", + "https://github.com/stablyai/orca/pull/11369" + ], + "invariant": "A restored absolute path owned by a same-host sibling workspace cannot read, save, watch, or persist until old saves drain, the exact route and host generations are revalidated, and one authoritative activation transaction installs the sibling owner, target projection, editor state, reconciliation, and first-activation terminal preparation; collisions and stale routes fail before activation preparation or reconciliation.", + "oracle": "Hold an old-owner save in flight, start migration, then remove the sibling, change a folder root, or reconnect SSH and require owner migration to fail closed after quiescence. On a stable route require one coherent target-workspace projection, first-activation terminal generation preparation, destination authority for explicit save and autosave, exact watch replacement, destination-only change/delete/rename handling, owner-derived state rekeys, and hot-exit restart ownership. Seed an invalid destination tab/group model before a collision and require the target projection to remain byte-identical.", + "commands": [ + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/restored-editor-owner-reparent.test.ts src/renderer/src/components/editor/restored-editor-owner-save-lifecycle.test.ts src/renderer/src/lib/runtime-workspace-file-route.test.ts" + ], + "testFiles": [ + "src/renderer/src/store/slices/restored-editor-owner-reparent.test.ts", + "src/renderer/src/components/editor/restored-editor-owner-save-lifecycle.test.ts", + "src/renderer/src/lib/runtime-workspace-file-route.test.ts" + ], + "assertionRefs": [ + { + "file": "src/renderer/src/store/slices/restored-editor-owner-reparent.test.ts", + "assertions": [ + "one atomic commit rekeys owner-derived editor, preview, draft, cursor, view, tab, group, active, reveal, focus, provenance, and persistence state", + "active reparenting uses the centralized workspace activation transaction for terminal, browser, pending-creation, explorer, first-activation, and post-commit state", + "source watch unsubscribes once, destination watch subscribes once, and only destination change/delete/rename events reach the file", + "dirty and clean destination collisions fail closed without changing either open session or reconciling destination tabs and groups", + "folder and direct-SSH owners retain exact root, host, target, and connection-generation authority" + ] + }, + { + "file": "src/renderer/src/components/editor/restored-editor-owner-save-lifecycle.test.ts", + "assertions": [ + "migration waits for the old save queue and routes later explicit and automatic saves through the destination worktree", + "a removed sibling, changed folder root, or changed direct-SSH generation after quiescence rejects migration without changing ownership" + ] + }, + { + "file": "src/renderer/src/lib/runtime-workspace-file-route.test.ts", + "assertions": [ + "same-host runtime, folder, local, and direct-SSH roots resolve without cross-host fallback" + ] + } + ], + "evidenceRuns": [ + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/store/slices/restored-editor-owner-reparent.test.ts src/renderer/src/components/editor/restored-editor-owner-save-lifecycle.test.ts src/renderer/src/lib/runtime-workspace-file-route.test.ts", + "result": "passed", + "durationSeconds": 3, + "summary": "Three deterministic files passed 20 lifecycle, stale-route, activation, ownership, host, collision, persistence, watch, and save tests." + } + ], + "runtimeBudget": { + "p95Seconds": 5, + "scope": "focused renderer store/controller contract on a local development runner" + }, + "flakeHistory": { + "status": "unknown", + "evidence": "One local deterministic run is recorded; CI and soak history have not started." + }, + "redGreenEvidence": { + "status": "complete", + "evidence": "The final2 verifier's byte-identical post-quiescence lifecycle scope passed 21/21 on 7890271160 and failed 7 tests on f92db196a1; base e08eba674c, published 1bcfe3bcb0, and revert b3627461ab were structurally red. The permanent collision oracle is in test blob ac62a89c671a0c8f081ebf06736715bd2150ce9f (SHA-256 a61970ace80be1cb56f781aee6f878a8446c6c4527f9eb0cd0c151d8df96bf50). The same byte-identical blob is structurally red on base, published, and revert, behaviorally red on rejected final2 candidate 7890271160 because pre-commit reconciliation removes the stale destination tab, and green on implementation b72a838cdc; the full permanent gate passes 20/20." + }, + "performanceBudget": { + "required": true, + "evidence": "Route lookup scans only the already-indexed renderer workspace catalog, while migration is O(open editor files + source/destination tabs/groups) and performs no provider call, Git scan, polling, retry, subprocess, or global fanout beyond the required old/new watch delta." + }, + "promotionCriteria": [ + "Collect two fresh child-verifier decisions against the correction candidate.", + "Collect headed and headless paired-runtime coverage after the post-establish Electron IPC gap is fixed.", + "Collect physical Windows or WSL path/host evidence and CI soak history." + ], + "knownGaps": [ + "Headed Electron post-establish IPC, paired headless, reconnect, and physical Windows/WSL journeys are uncollected.", + "Cold many-repo main-process sibling discovery remains a separately measured follow-up.", + "Registered-workspace symlink policy remains inherited and unchanged." + ], + "demotionRule": "Keep experimental or demote if migration can race a save, retain source authority, fan out watches, lose dirty/editor state, accept an owner-generation change, merge a collision, or the focused contract flakes without a product or harness bug." + }, { "id": "terminal-provider.login-session-retirement", "title": "macOS login-session retirement preserves live daemons through transient rejection bursts", @@ -1031,6 +1126,126 @@ ], "demotionRule": "Demote if any probe can run before lifecycle ownership, if more than one shared heartbeat timer is armed, if first-socket cleanup exceeds one interval, if later-socket cleanup exceeds two intervals, or if close/error cleanup retains listeners or timers." }, + { + "id": "runtime.streaming-subscription-close-delivery", + "title": "Retiring a runtime transport always tells the renderer its streams closed", + "maturity": "experimental", + "protection": "partial", + "owner": "runtime-platform", + "layer": "runtime-subscription-ipc-contract", + "surfaces": [ + "paired remote server", + "runtime environment disconnect and re-pair", + "terminal.multiplex streaming", + "browser screencast streaming", + "parked remote terminal reveal" + ], + "platforms": ["macos", "linux", "windows"], + "providers": ["remote-runtime"], + "coveredPlatforms": ["macos"], + "coveredProviders": ["remote-runtime"], + "coverageNotes": "Deterministic main-IPC contract tests cover disconnect-driven close delivery, exactly-once close, per-subscription teardown isolation against a failing socket close and a throwing liveness probe, containment of a throwing renderer send on the unguarded host-close path, and continued suppression of stale payloads from a retired transport. A headed paired-server journey (real Orca host plus a separate paired Orca desktop client) covers hidden-but-mounted reveal, cold-parked reveal, and cold-parked reveal across a disconnect/reconnect. Live Linux and Windows paired-server evidence and real sleep/wake transport loss remain uncollected.", + "motivatingLinks": [ + "tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts", + "docs/reference/headless-linux-server.md" + ], + "invariant": "Every renderer-held runtime subscription receives exactly one terminal close event when its transport is retired, including when the retirement advanced the transport generation first, and a single failing teardown never abandons that environment's remaining subscriptions nor escapes into the transport that reported the close. Payload frames from a retired transport stay suppressed. A revealed remote terminal therefore reattaches over a live multiplex connection: its buffer restores, typed input reaches the host PTY, the echo paints without a tab flip, and the PTY converges on the revealed pane grid.", + "oracle": "The main IPC contract test subscribes terminal.multiplex through the real handler, disconnects the environment, and asserts the renderer received exactly one {type: close} subscription event. Two isolation tests subscribe a second stream to the same environment and make the first one fail -- in its socket close, and in the liveness probe inside notifyClosed -- then assert the disconnect does not throw, both transports closed, and every close the renderer could still receive was delivered. A third drives a host-initiated close through the transport callback, which is the one notifyClosed call site with no surrounding guard, with a renderer send that throws, and asserts it cannot escape into the WebSocket close handler. A fourth test asserts that after retirement a late response frame is not forwarded and a late transport close does not re-send. The paired-server journey runs three reveal scenarios against one real host and one real paired desktop client, and for each records buffer restore, host-side receipt of the typed marker through an out-of-band host sink file, live paint without a tab flip, and PTY-versus-pane grid convergence.", + "commands": [ + "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/runtime-environments.test.ts", + "pnpm exec playwright test tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" + ], + "testFiles": [ + "src/main/ipc/runtime-environments.test.ts", + "tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts" + ], + "assertionRefs": [ + { + "file": "src/main/ipc/runtime-environments.test.ts", + "assertions": [ + "tells the renderer when retiring the transport closes its streaming subscription (the load-bearing repro; red with the fix reverted)", + "retires an environment's remaining subscriptions when one teardown throws (load-bearing; red without per-subscription isolation)", + "contains a throwing renderer send on a host-initiated close (load-bearing; red without the guarded send, and the only coverage of the unguarded notifyClosed call site)", + "retires remaining subscriptions when a liveness probe inside notifyClosed throws (load-bearing; keeps the isolation structural rather than comment-asserted)", + "suppresses stale payloads from a retired transport but never re-sends its close (forward guard on the retained generation gate, not a repro)" + ] + }, + { + "file": "tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts", + "assertions": [ + "a revealed hidden-but-mounted remote terminal restores, accepts input, and paints live", + "a revealed cold-parked remote terminal restores, accepts input, and paints live", + "a cold-parked remote terminal revealed after a runtime disconnect and reconnect restores, accepts input, and paints live", + "the host PTY grid converges on the revealed pane grid in every scenario" + ] + } + ], + "evidenceRuns": [ + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/runtime-environments.test.ts", + "result": "passed", + "durationSeconds": 0.81, + "summary": "53 runtime environment IPC tests passed, including the new close-delivery, both teardown-isolation, transport-path containment, and stale-payload-suppression contracts." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec playwright test tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", + "result": "passed", + "durationSeconds": 15.5, + "summary": "All three reveal scenarios restored their buffer, delivered typed input to the host PTY, painted live without a tab flip, and converged the PTY on the 135x60 pane grid. Before the fix the reconnect-parked scenario stayed blank at recoveryState connecting with the PTY stranded at the host 128x60 grid." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec playwright test tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", + "result": "passed", + "durationSeconds": 15.5, + "summary": "Repeat run on a clean uninstrumented build; all three scenarios green with identical grids." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec playwright test tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", + "result": "passed", + "durationSeconds": 14.7, + "summary": "Third consecutive pass after the review follow-ups (env save/restore and the hidden-mounted stayed-mounted assertion)." + } + ], + "runtimeBudget": { + "p95Seconds": 60, + "scope": "focused runtime environment IPC tests plus one headed paired-server reveal journey" + }, + "flakeHistory": { + "status": "unknown", + "evidence": "Deterministic IPC coverage plus the three recorded paired-server journey runs, which passed consecutively on macOS at 14.7-15.5s; the spec also passed once on a shared CI runner. Longer soak history is not yet available." + }, + "redGreenEvidence": { + "status": "complete", + "evidence": "On main the paired-server journey reproduced a blank, non-interactive pane after revealing a cold-parked remote terminal across a reconnect: recoveryState stayed connecting, the xterm buffer stayed empty, typed input never reached the host sink, a tab flip did not recover it, and the PTY stayed at the host 128x60 grid. Renderer instrumentation showed the multiplexer reusing a dead subscription (ensureConnected reuse-ready) and never receiving a subscribed event. Reverting the main-side fix also turns the close-delivery IPC test red; with the fix the multiplexer observes handleClose, reconnects fresh, and every scenario passes." + }, + "performanceBudget": { + "required": true, + "evidence": "The fix adds one boolean latch and at most one extra IPC send per retired subscription, on a path that already tears the subscription down. It introduces no timer, poll, retry, subprocess, or per-frame work, and the close is deduplicated so a transport-driven close after an environment-wide retirement sends nothing." + }, + "promotionCriteria": [ + "Collect at least 100 consecutive CI or soak passes or 14 days without an unexplained flake.", + "Collect live Linux and Windows paired-server reveal evidence.", + "Add real sleep/wake and network-loss transport drops alongside the explicit disconnect trigger." + ], + "knownGaps": [ + "Live paired-server validation currently covers macOS host and client only.", + "The transport drop is an explicit runtime disconnect; real sleep/wake and network partitions are not yet exercised by this gate.", + "Browser screencast subscribers share the fixed contract but have no dedicated reveal journey; the web and mobile clients run parallel transports and are unaffected." + ], + "demotionRule": "Demote if a retired runtime transport can leave a renderer subscription without a close event, if a close is delivered more than once, if one failing teardown strands its sibling subscriptions, if payload frames from a retired transport reach the renderer, or if a revealed remote terminal can stay blank or reject input after a reconnect." + }, { "id": "editor.live-log-append-stability", "title": "Long live session logs retain their Monaco viewport while appending", @@ -1695,13 +1910,15 @@ "invariant": "Reconnect, replay, or lifecycle observations from a viewer that negotiated explicit close intent must never kill a live PTY. A capable reasonless close must keep and republish; a legacy paired viewer must retain current-main behavior because its intentional close and cleanup echo are wire-identical. Lifecycle close requires the exact observed publication, terminal, environment, and authoritative liveness, never signals a process, and leaves renderer-owned or partial-split retirement to its owner. Legacy daemon hello and warm reattachment remain non-destructive.", "oracle": "Start isolated v25 and v26 daemon generations with one capable-viewer PTY and one legacy-viewer PTY per generation in four target worktrees plus an unaddressed control PTY in a fifth worktree. Route them through the production desktop scanner, runtime, RPC dispatcher, renderer-close relay, and daemon router. First issue sequential reasonless closes from an authenticated capable connection and require refusal, snapshot republish, zero shutdown calls, exact process survival, and post-close I/O. Then issue the byte-identical requests without the negotiated capability and require current-main behavior: two ordered immediate shutdowns, session-killed events, and exact root/descendant death, while capable and control PTYs survive. An observer lists all targets before, between, and after while issuing zero closes. Unit contracts also require in-process reasonless refusal, legacy runtime/mobile compatibility, explicit user closes, encrypted client-auth advertisement, and old-server lifecycle calls never to fall back.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orca-runtime.test.ts src/main/runtime/remote-runtime-request-connection.integration.test.ts src/main/runtime/rpc/methods/session-tabs.test.ts src/main/runtime/rpc/methods/session-tabs-schemas.test.ts src/main/runtime/rpc/e2ee-channel.test.ts src/main/runtime/rpc/e2ee-channel-v2.test.ts src/main/runtime/rpc/mobile-socket-wiring.test.ts src/main/runtime/rpc/runtime-client-capabilities.test.ts src/shared/remote-runtime-client.test.ts src/shared/remote-runtime-request-connection.test.ts src/shared/remote-runtime-shared-control-connection.test.ts src/cli/runtime/websocket-transport.test.ts src/renderer/src/web/web-runtime-client.test.ts src/renderer/src/runtime/web-runtime-session.test.ts src/renderer/src/runtime/web-session-close-intent.test.ts src/renderer/src/runtime/web-session-tabs-sync.test.ts src/renderer/src/components/terminal/terminal-tab-actions.test.ts src/renderer/src/components/terminal/terminal-close-incarnation.test.ts src/renderer/src/components/terminal-pane/terminal-parked-tab-watchers.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/daemon-server-kill-attribution.test.ts src/main/runtime/orca-runtime.test.ts src/main/runtime/remote-runtime-request-connection.integration.test.ts src/main/runtime/rpc/runtime-close-attribution-topology.test.ts src/main/runtime/rpc/methods/session-tabs.test.ts src/main/runtime/rpc/methods/session-tabs-schemas.test.ts src/main/runtime/rpc/e2ee-channel.test.ts src/main/runtime/rpc/e2ee-channel-v2.test.ts src/main/runtime/rpc/mobile-socket-wiring.test.ts src/main/runtime/rpc/runtime-client-capabilities.test.ts src/shared/remote-runtime-client.test.ts src/shared/remote-runtime-request-connection.test.ts src/shared/remote-runtime-shared-control-connection.test.ts src/cli/runtime/websocket-transport.test.ts src/renderer/src/web/web-runtime-client.test.ts src/renderer/src/runtime/web-runtime-session.test.ts src/renderer/src/runtime/web-session-close-intent.test.ts src/renderer/src/runtime/web-session-tabs-sync.test.ts src/renderer/src/components/terminal/terminal-tab-actions.test.ts src/renderer/src/components/terminal/terminal-close-incarnation.test.ts src/renderer/src/components/terminal-pane/terminal-parked-tab-watchers.test.ts", "pnpm exec playwright test tests/e2e/daemon-generation-reconnect-safety.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", "pnpm exec playwright test tests/e2e/daemon-generation-legacy-close-safety.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" ], "testFiles": [ + "src/main/daemon/daemon-server-kill-attribution.test.ts", "src/main/runtime/orca-runtime.test.ts", "src/main/runtime/remote-runtime-request-connection.integration.test.ts", + "src/main/runtime/rpc/runtime-close-attribution-topology.test.ts", "src/main/runtime/rpc/methods/session-tabs.test.ts", "src/main/runtime/rpc/methods/session-tabs-schemas.test.ts", "src/main/runtime/rpc/e2ee-channel.test.ts", @@ -1723,6 +1940,19 @@ "tests/e2e/daemon-generation-legacy-close-safety.spec.ts" ], "assertionRefs": [ + { + "file": "src/main/daemon/daemon-server-kill-attribution.test.ts", + "assertions": [ + "successful and failed daemon kill requests retain the authenticated control-client identity without claiming a failed kill succeeded" + ] + }, + { + "file": "src/main/runtime/rpc/runtime-close-attribution-topology.test.ts", + "assertions": [ + "remote, legacy, reconnect, stale, concurrent, cross-worktree, and unowned close spans retain authoritative runtime, target, requester, decision, and outcome identities without serializing the bearer credential", + "close attribution adds no terminal inventory scan or provider fanout" + ] + }, { "file": "src/main/runtime/remote-runtime-request-connection.integration.test.ts", "assertions": [ @@ -2114,31 +2344,47 @@ "maturity": "experimental", "protection": "partial", "owner": "agent-session", - "layer": "renderer-state", + "layer": "cross-boundary", "surfaces": [ "agent launch", "workspace activation", "sleep and hibernate restore", "provider session dedupe", - "sidebar and mobile identity" + "sidebar and mobile identity", + "runtime-owned background PTY mount and remount" ], "platforms": ["macos", "linux", "windows"], "providers": ["local", "daemon", "ssh", "wsl", "remote-runtime"], "coveredPlatforms": ["macos"], - "coveredProviders": [], - "coverageNotes": "Local macOS evidence over the ownership/dedupe suite on main@1282f5c2d. Queued/pending resume-claim indexing, same-session and wrong-session hook proofs, and Electron repeat-activation coverage arrive with the pending stack (#7008).", + "coveredProviders": ["local", "daemon", "remote-runtime"], + "coverageNotes": "Renderer ownership/dedupe contracts cover provider-session claims. Local and daemon attach-only contracts prove an existing stable-pane owner is adopted without provider creation, while remote-runtime transport contracts preserve adopted ownership through cancellation. The Electron oracle covers a local macOS runtime and daemon with real agent, Setup, and unrelated-canary processes; SSH, WSL, paired-server, Linux, and Windows remain contract-only or unrun.", "motivatingLinks": [ "https://github.com/stablyai/orca/pull/6800", "https://github.com/stablyai/orca/pull/5240", "https://github.com/stablyai/orca/pull/6411", - "https://github.com/stablyai/orca/pull/6833" + "https://github.com/stablyai/orca/pull/6833", + "https://github.com/stablyai/orca/pull/11789", + "https://github.com/stablyai/orca/pull/11819" ], - "invariant": "Workspace activation, launch, restore, sleep, hibernate, dedupe, clearing, and reconnect code must not replay or resume a provider session id already owned, queued, pending, or live in that workspace.", - "oracle": "The current renderer-state slice asserts provider-session claim keys are owned by preserved active tabs, inactive split leaves, visible non-focused split groups, live records, quit records, worktree-sleep records, queued startup payloads, time-bounded resume bridge claims, and same-session live hook evidence; duplicates clear without launching a second resume command. The provider list is the risk scope, not proof that every provider has a live integration gate.", + "invariant": "Workspace activation, launch, restore, sleep, hibernate, dedupe, clearing, mount, remount, and reconnect code must not replay or resume a provider session id already owned, queued, pending, live, or durably bound to a host PTY in that workspace. A renderer with missing projection state must adopt the exact runtime-owned PTY for the original tab and leaf rather than create a replacement.", + "oracle": "Renderer-state tests assert provider-session ownership across preserved and queued panes. Main/provider contracts assert atomic attach-only adoption, stable host/worktree/tab/leaf identity, no fresh spawn on adoption, and safe paired-runtime cancellation. The Electron oracle creates inactive runtime-owned Codex and Setup PTYs plus an unrelated canary, seeds an exact resumable provider session, removes only the target renderer projections, and activates the workspace. It requires byte-stable handle, PTY, incarnation, tab, leaf, process PID, renderer graph, persisted binding, runtime id, graph epoch, and daemon PID across first mount and reload; PID-specific DOM keyboard I/O must remain live with one launch, zero resume argv, zero signals, zero interruption text, and no canary mutation.", "commands": [ - "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/resume-sleeping-agent-session.test.ts" + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/resume-sleeping-agent-session.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/resume-sleeping-agent-session.test.ts src/main/providers/local-pty-provider.test.ts src/main/daemon/terminal-host.test.ts src/main/daemon/daemon-pty-adapter.test.ts src/main/ipc/pty.test.ts src/main/runtime/orca-runtime.test.ts src/renderer/src/lib/pane-manager/pane-fit.test.ts src/renderer/src/components/terminal-pane/pty-connection.test.ts src/renderer/src/components/terminal-pane/pty-transport.test.ts", + "pnpm exec electron-vite build --mode e2e && SKIP_BUILD=1 pnpm exec playwright test tests/e2e/live-background-terminal-mount-authority.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1" + ], + "testFiles": [ + "src/renderer/src/lib/resume-sleeping-agent-session.test.ts", + "src/main/providers/local-pty-provider.test.ts", + "src/main/daemon/terminal-host.test.ts", + "src/main/daemon/daemon-pty-adapter.test.ts", + "src/main/ipc/pty.test.ts", + "src/main/runtime/orca-runtime.test.ts", + "src/renderer/src/lib/pane-manager/pane-fit.test.ts", + "src/renderer/src/components/terminal-pane/pty-connection.test.ts", + "src/renderer/src/components/terminal-pane/pty-transport.test.ts", + "tests/e2e/live-background-terminal-mount-authority.spec.ts" ], - "testFiles": ["src/renderer/src/lib/resume-sleeping-agent-session.test.ts"], "assertionRefs": [ { "file": "src/renderer/src/lib/resume-sleeping-agent-session.test.ts", @@ -2148,6 +2394,42 @@ "active stable-pane records owned by preserved or visible panes are not resumed again", "hibernated stable panes with cleared live PTY bindings are skipped" ] + }, + { + "file": "src/main/ipc/pty.test.ts", + "assertions": [ + "a completed runtime-owned stable pane is adopted with its original PTY and incarnation while renderer resume intent is stripped", + "an exact persisted owner is attach-only adopted when the runtime projection is missing", + "runtime and persisted stable-pane owner conflicts fail closed before provider creation" + ] + }, + { + "file": "src/renderer/src/lib/pane-manager/pane-fit.test.ts", + "assertions": [ + "withheld hidden-window animation frames exhaust the bounded fit retry and release its continuation" + ] + }, + { + "file": "src/renderer/src/components/terminal-pane/pty-connection.test.ts", + "assertions": [ + "same-generation explicit reattach drains the authoritative snapshot before immediate live bytes and ACKs their delivery credit" + ] + }, + { + "file": "src/renderer/src/components/terminal-pane/pty-transport.test.ts", + "assertions": [ + "paired-runtime stable-pane adoption reports reattach without fresh-spawn ownership", + "cancellation after a paired-runtime adoption cannot close the original owner" + ] + }, + { + "file": "tests/e2e/live-background-terminal-mount-authority.spec.ts", + "assertions": [ + "first mount and renderer reload preserve exact agent and Setup handle, PTY, incarnation, tab, leaf, and PID identity", + "PID-specific keyboard input and output remain user-visible in both mounted panes", + "runtime inventory, renderer graph, persisted session, runtime epoch, and daemon PID converge without replacement or resume", + "the unrelated canary remains writable and receives no signal across target projection repair" + ] } ], "evidenceRuns": [ @@ -2162,30 +2444,32 @@ } ], "runtimeBudget": { - "p95Seconds": 15, - "scope": "local renderer state test" + "p95Seconds": 180, + "scope": "focused renderer/main/provider contracts plus one isolated Electron mount-and-reload journey" }, "flakeHistory": { "status": "unknown", - "evidence": "Registered after targeted tests were found; needs soak history before blocking promotion." + "evidence": "The renderer gate has prior local evidence; the stable-pane Electron oracle is new and needs CI soak before blocking promotion." }, "redGreenEvidence": { "status": "partial", - "evidence": "Tests encode provider-session dedupe and ownership claims across active/inactive/visible split records, queued pendingStartupByTabId resume payloads, time-bounded runtime automaticAgentResumeClaimsByTabId bridge claims, live same-session hook evidence, wrong-session hook rejection, and a bounded queued-claim index over many records/tabs. Needs saved red/green artifact for the class-level replay invariant." + "evidence": "Renderer tests encode provider-session dedupe across active, inactive, queued, and live claims. The cross-boundary Electron oracle is constructed for byte-identical latest-main, candidate, and candidate-revert runs; record those three terminal results before promoting this gate." }, "performanceBudget": { "required": true, - "evidence": "Current state tests are cheap and assert queued pending-startup provider-session ids are indexed once per activation. PRs adding new ownership scans must show bounded work over records and no hidden-pane wake loop before blocking promotion." + "evidence": "Renderer state tests assert bounded provider-session indexing. Stable-pane adoption is a targeted owner lookup and attach-only call; focused contracts require no provider listing scan, fresh spawn callback, or repeated resume probe. The Electron oracle checks exact launch counts but is not a throughput benchmark." }, "promotionCriteria": [ "Run in soak for at least 100 consecutive passes or 14 days across required CI platforms.", "Add bounded-work assertions for delayed hook/status ownership scans if those paths grow.", - "Attach red/green evidence that display/replay evidence alone cannot claim ownership." + "Attach red/green evidence that display/replay evidence alone cannot claim ownership.", + "Record byte-identical latest-main, candidate, and candidate-revert Electron results." ], "knownGaps": [ - "Providers listed on this gate are affected identity surfaces; the current executable command is renderer-state coverage, not live local/daemon/SSH/WSL/remote-runtime coverage.", - "Current command models live same-session and wrong-session hook evidence, but does not run the real hook timing through Electron.", - "Current command does not run a real workspace activation loop repeatedly through Electron." + "Providers listed on this gate are affected identity surfaces; live integration is limited to local macOS while daemon and remote-runtime adoption also have focused contracts.", + "The Electron oracle seeds the production hook-store contract instead of running an authenticated Codex hook end to end.", + "The live Electron topology is local macOS only; folder workspaces, SSH, WSL, paired headed/headless servers, Linux, and Windows are not exercised by that journey.", + "The oracle covers first activation and one renderer reload, not repeated soak activation or an installed-app update." ], "demotionRule": "Demote or quarantine if failures are non-actionable or if a duplicate resume escape occurs outside the modeled matrix." }, @@ -6457,21 +6741,25 @@ "providers": ["local", "daemon", "ssh", "wsl", "remote-runtime"], "coveredPlatforms": ["macos"], "coveredProviders": ["local", "daemon", "ssh"], - "coverageNotes": "Deterministic units cover authority-aware legacy formatting, exact legacy worker identity planning, local worker presentation, retained-output reads after adoption, reveal-failure warnings, stable-pane Run/Dispatch routing, the SSH in-process CLI fallback, and federated non-reveal. Two isolated macOS Electron journeys launch fake Codex workers through the real RPC path and record append-only spawn/interruption ledgers. They assert immediate inactive presentation, one live agent PID, stable PTY/incarnation/tab/leaf/worktree/Task/Dispatch identity, and no interruption after workspace re-entry; the restart journey additionally removes renderer ownership, marks the Dispatch legacy, retains the daemon process across an app restart, and proves exact background adoption with readable ACK output and no resume replay. Distinct A/B artifacts plus live SSH, WSL, folder, remote-runtime, Linux, and Windows cutover journeys remain explicit gaps.", + "coverageNotes": "A deterministic service-state-machine oracle now models a current-contract worker and coordinator whose renderer graph identities disappear across an app/runtime update. It exercises the production verifier with restored PTY and hydrated hook commitments, proves authenticated completion replay across a fresh runtime, explicit takeover, ordinary mail routing, remote-attachment process fencing, retained Task/Dispatch/terminal identity, and unchanged fixture marker bytes, and rejects foreign pane evidence. Other deterministic units cover authority-aware legacy formatting, exact legacy worker identity planning, local worker presentation, retained-output reads after adoption, reveal-failure warnings, stable-pane Run/Dispatch routing, creator pane/process/Run-generation fencing, indexed retained-Run lookup scaling, the SSH in-process CLI fallback, and federated non-reveal. Two isolated macOS Electron journeys launch fake Codex workers through the real RPC path and record append-only spawn/interruption ledgers. They assert immediate inactive presentation, one live agent PID, stable PTY/incarnation/tab/leaf/worktree/Task/Dispatch identity, and no interruption after workspace re-entry; the restart journey additionally removes renderer ownership, marks the Dispatch legacy, retains the daemon process across an app restart, and proves exact background adoption with readable ACK output and no resume replay. Distinct A/B artifacts plus live SSH, WSL, folder, remote-runtime, Linux, and Windows cutover journeys remain explicit gaps.", "motivatingLinks": ["https://github.com/stablyai/orca/pull/11107#discussion_r3663321387"], - "invariant": "Starting a worker in the coordinator's current workspace must materialize one inactive terminal tab before worker-start returns, preserve coordinator focus, and remain exactly once after workspace re-entry. After an app update or restart, an exact live legacy worker must fence automatic provider resume, adopt its original PTY into its original background pane, retain readable output, and clear the resume record without spawning, writing, signalling, interrupting, replacing, or focusing the worker. An exact existing target workspace must receive a discoverable tab without stealing coordinator focus; if renderer reveal fails, worker-start must expose that the live worker remains background-only. Run and Dispatch checks must resolve through the caller's stable pane identity when a terminal handle is reminted, while a live handle outranks mismatched pane metadata, explicit legacy terminal inspection remains handle-scoped, and remote or headless worker presentation remains background-only.", - "oracle": "Drive Run create, Task create, and worker-start through production Electron runtimes with a deterministic Codex fixture. Require append-only ledgers with one still-live PID and no interruption, a visible inactive worker tab while the coordinator stays active, Run delivery through stable pane identity, and stable PTY/incarnation, tab, leaf, worktree, Task, and Dispatch across workspace re-entry. In a restart journey, retain the original daemon PTY and PID, remove renderer ownership, retain sleeping-session evidence, mark the Dispatch legacy, relaunch, and require exact inactive tab adoption, readable ACK output, cleared resume state, one spawn, and no resume argv or Conversation interrupted text after another workspace round trip. Unit tests separately assert authority-specific legacy affordances, exact identity and owner matching, retained-output fallback, pane-stable routing, federated non-activation, and SSH fallback parity.", + "invariant": "Starting a worker in the coordinator's current workspace must materialize one inactive terminal tab before worker-start returns, preserve coordinator focus, and remain exactly once after workspace re-entry. After an app update or restart, an exact live legacy worker must fence automatic provider resume, adopt its original PTY into its original background pane, retain readable output, and clear the resume record without spawning, writing, signalling, interrupting, replacing, or focusing the worker. A current-contract worker whose renderer graph identity is temporarily absent must retain its Dispatch capability and settle exactly once from exact hook-attested handle, pane, and process evidence; otherwise only an exact attested coordinator may take over. An exact existing target workspace must receive a discoverable tab without stealing coordinator focus; if renderer reveal fails, worker-start must expose that the live worker remains background-only. Run and Dispatch checks must resolve through the caller's stable pane identity when a terminal handle is reminted, while a live handle outranks mismatched pane metadata. A nested worker's creator edge requires the current creator pane, process incarnation, and owning Run generation; reminting and rebinding that pane to another Run must remove the stale edge. Explicit legacy terminal inspection remains handle-scoped, and remote or headless worker presentation remains background-only.", + "oracle": "Drive Run create, Task create, and worker-start through production Electron runtimes with a deterministic Codex fixture. Require append-only ledgers with one still-live PID and no interruption, a visible inactive worker tab while the coordinator stays active, Run delivery through stable pane identity, and stable PTY/incarnation, tab, leaf, worktree, Task, and Dispatch across workspace re-entry. In a restart journey, retain the original daemon PTY and PID, remove renderer ownership, retain sleeping-session evidence, mark the Dispatch legacy, relaunch, and require exact inactive tab adoption, readable ACK output, cleared resume state, one spawn, and no resume argv or Conversation interrupted text after another workspace round trip. The service oracle removes renderer lookup identity from current-contract callers while retaining real restored-PTY and hook commitments, replays authenticated completion and takeover across fresh runtimes, and requires one Task, Dispatch, terminal authority, message, mutation, ordinary-mail delivery, remote process fencing, and unchanged fixture marker bytes while foreign pane evidence remains rejected. Unit tests separately remint a creator pane and process from Run A into Run B, require the nested Run A worker to fall back to its current coordinator, require indexed query plans, and bound 300 Task reads with 50,000 retained Runs. They also assert authority-specific legacy affordances, exact identity and owner matching, retained-output fallback, pane-stable routing, federated non-activation, and SSH fallback parity.", "commands": [ + "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts --reporter=dot", "pnpm exec vitest run --config config/vitest.config.ts src/cli/handlers/orchestration.test.ts src/cli/handlers/orchestration-check-identity.test.ts src/cli/handlers/orchestration-worker-cli.test.ts src/main/runtime/rpc/methods/orchestration.test.ts src/main/ssh/ssh-remote-orca-cli.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orchestration/formatter.test.ts src/main/runtime/rpc/methods/orchestration-federation.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orchestration/orchestration-legacy-worker-terminal-recovery.test.ts", + "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts", "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orca-runtime.test.ts", "pnpm run test:e2e -- tests/e2e/orchestration-worker-terminal-visibility.spec.ts --workers=1", "pnpm run test:e2e -- tests/e2e/orchestration-legacy-worker-restart-recovery.spec.ts --workers=1" ], "testFiles": [ + "src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts", "src/main/runtime/orchestration/formatter.test.ts", "src/main/runtime/orchestration/orchestration-legacy-worker-terminal-recovery.test.ts", + "src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts", "src/main/runtime/orca-runtime.test.ts", "src/cli/handlers/orchestration.test.ts", "src/cli/handlers/orchestration-check-identity.test.ts", @@ -6483,6 +6771,23 @@ "tests/e2e/orchestration-legacy-worker-restart-recovery.spec.ts" ], "assertionRefs": [ + { + "file": "src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts", + "assertions": [ + "an exact current worker settles once through an app/runtime update even when renderer graph identity is absent", + "only an attested current coordinator may explicitly take over retained live work", + "Task, Dispatch, terminal authority, completion, and filesystem bytes are neither lost nor duplicated", + "foreign pane evidence cannot borrow retained lifecycle authority", + "ordinary mail and remote attachments use the same attested pane and process authority" + ] + }, + { + "file": "src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts", + "assertions": [ + "creator lookup uses the assignee-handle and pane-leaf indexes without a retained-Run scan", + "300 Task reads remain bounded with 50,000 unrelated retained Runs" + ] + }, { "file": "src/main/runtime/orchestration/orchestration-legacy-worker-terminal-recovery.test.ts", "assertions": [ @@ -6562,6 +6867,42 @@ } ], "evidenceRuns": [ + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts --reporter=dot", + "result": "failed", + "durationSeconds": 3.07, + "summary": "The byte-identical 5f45c270f1 oracle, applied as the sole tree overlay in 063340a8ba on origin/main@34291f07e9, failed 3 of 5 rows: completion remained dispatched, takeover lacked a stable pane, and remote attachment authority lost process identity." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts --reporter=dot", + "result": "passed", + "durationSeconds": 3.13, + "summary": "The same byte-identical oracle passed 5 tests on candidate@2748b0b29b, exercising the production verifier and fresh-runtime replay while preserving exact DB identity and unchanged fixture bytes." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts --reporter=dot", + "result": "failed", + "durationSeconds": 3.14, + "summary": "With current-authority propagation actually disabled in candidate child 08a7db37bf, the same byte-identical oracle failed 2 of 5 rows: completion remained dispatched and remote attachment authority was rejected." + }, + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts --reporter=dot", + "result": "passed", + "durationSeconds": 3.1, + "summary": "After reverting the intentional break in d2a4e2e024, the same byte-identical oracle passed all 5 tests." + }, { "date": "2026-07-28", "runner": "local", @@ -6609,7 +6950,7 @@ }, "redGreenEvidence": { "status": "partial", - "evidence": "The focused presentation and stale-handle tests failed against the pre-fix implementation. The restart journey additionally failed first on empty retained output while the original PTY/PID remained live, then passed after the scoped recovered-worker snapshot fallback. The live incident and pre-fix Electron topology showed workspace re-entry replaying provider resume against a worker whose tab binding was missing. Saved intentional-break and CI artifacts are still needed." + "evidence": "The byte-identical 5f45c270f1 service oracle is red as the sole overlay 063340a8ba on origin/main@34291f07e9, green on candidate@2748b0b29b, red with current-authority propagation actually disabled in child 08a7db37bf, and green again after revert d2a4e2e024. The focused presentation and stale-handle tests failed against the earlier pre-fix implementation. The restart journey additionally failed first on empty retained output while the original PTY/PID remained live, then passed after the scoped recovered-worker snapshot fallback. The live incident and pre-fix Electron topology showed workspace re-entry replaying provider resume against a worker whose tab binding was missing. Distinct installed A/B and CI artifacts are still needed." }, "performanceBudget": { "required": true, @@ -6631,6 +6972,104 @@ ], "demotionRule": "Keep experimental or demote if either Electron journey flakes without a product or harness defect, if local worker-start can return before tab materialization without an explicit reveal warning, if focus moves to the worker, if restart or workspace re-entry spawns/resumes/duplicates/interferes with the worker, if retained output becomes unreadable, or if pane-stable delivery reads the wrong mailbox." }, + { + "id": "orchestration.settled-worker-terminal-release", + "title": "Settled worker cleanup preserves one exact terminal lease and immutable output", + "maturity": "experimental", + "protection": "partial", + "owner": "orchestration", + "layer": "runtime-sqlite-terminal-lifecycle", + "surfaces": [ + "worker-release", + "worker-retain", + "explicit terminal reuse", + "restart reconciliation", + "worker-read archives", + "orchestration reset" + ], + "platforms": ["macos", "linux", "windows"], + "providers": ["local", "daemon", "ssh", "wsl", "remote-runtime"], + "coveredPlatforms": ["macos"], + "coveredProviders": ["local"], + "coverageNotes": "Deterministic service tests cover release-versus-reuse ordering, transactional retain and takeover cancellation, exact host/pane/process identity, conservative schema-v23 backfill, immutable transcript and bounded terminal archives, mutation restart, reset cleanup, replay idempotency, and 50-resource accounting. Live SSH, WSL, Windows, paired-runtime, and provider-close lost-ack journeys remain explicit gaps.", + "motivatingLinks": ["https://github.com/stablyai/orca/pull/12355", "STA-905"], + "invariant": "A settled Dispatch may close only its one coordinator-created terminal lease. Explicit reuse, real user input, retain, identity or host change, ambiguity, and another resource for the same exact host/pane/process must fence closure. Output preservation and the requested-to-releasing transition are atomic, archives remain readable without the provider file, retries resume idempotently, and orchestration reset removes archive and authority state.", + "oracle": "Record release intent for a settled owner, attempt exact reuse before close, and require worker-start to fail with terminal_release_in_progress while the terminal stays open; then release the original owner exactly once. Race retain and real user input against a controlled archive promise and require no committed archive or close. Change host or process identity and inject duplicate resource evidence to require retention. Freeze a structured transcript, delete its source file, and require archived worker-read to return the same bounded redacted messages. Restart a pending mutation, reset orchestration state, and create 50 resources while asserting replay convergence, zero orphan rows, two-query worker listing, and no unrelated close.", + "commands": [ + "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/orchestration-worker-release.test.ts src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts src/main/runtime/rpc/orchestration-mutation-ledger.test.ts src/main/runtime/orchestration/worker-transcript-read.test.ts src/renderer/src/lib/worker-terminal-takeover-report.test.ts --reporter=dot" + ], + "testFiles": [ + "src/main/runtime/rpc/methods/orchestration-worker-release.test.ts", + "src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts", + "src/main/runtime/rpc/orchestration-mutation-ledger.test.ts", + "src/main/runtime/orchestration/worker-transcript-read.test.ts", + "src/renderer/src/lib/worker-terminal-takeover-report.test.ts" + ], + "assertionRefs": [ + { + "file": "src/main/runtime/rpc/methods/orchestration-worker-release.test.ts", + "assertions": [ + "rejects exact reuse after release intent instead of closing the new worker", + "lets an explicit retain cancel a release while output capture is pending", + "retains when the terminal host scope changed instead of closing", + "reads an immutable transcript snapshot after the provider file disappears", + "backfills a legacy creator plus explicit reuser as ambiguous", + "removes terminal authority and archived output on orchestration reset" + ] + }, + { + "file": "src/main/runtime/rpc/orchestration-mutation-ledger.test.ts", + "assertions": ["resumes a pending idempotent worker release after restart"] + }, + { + "file": "src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts", + "assertions": [ + "finishes a requested release after restart-style interruption", + "coalesces overlapping reconciliation passes and closes each resource once", + "keeps live terminals bounded across 50 settled workers while controls survive" + ] + } + ], + "evidenceRuns": [ + { + "date": "2026-08-03", + "runner": "local", + "platform": "macos", + "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/rpc/methods/orchestration-worker-release.test.ts src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts src/main/runtime/rpc/orchestration-mutation-ledger.test.ts src/main/runtime/orchestration/worker-transcript-read.test.ts src/renderer/src/lib/worker-terminal-takeover-report.test.ts --reporter=dot", + "result": "passed", + "durationSeconds": 3.48, + "summary": "Five focused files passed 56 tests covering lease serialization, reminted-handle transfer, duplicate-identity fencing, retain and takeover races, immutable archives, conservative legacy migration, mutation restart, reset cleanup, bounded accounting, and renderer input reporting." + } + ], + "runtimeBudget": { + "p95Seconds": 8, + "scope": "deterministic runtime, SQLite, transcript, renderer-input, and mutation contracts" + }, + "flakeHistory": { + "status": "unknown", + "evidence": "First local deterministic run only; focused CI and soak history are not yet available." + }, + "redGreenEvidence": { + "status": "complete", + "evidence": "The byte-identical 56-test oracle produced 12 deterministic failures and 44 passes with production restored to exact PR head 4aa66b62e3, including ready reuse during release, unsafe migration, stale archives, mutable transcript output, host/identity close gaps, and mutation replay loss. Candidate 457bc4edd1 passed all 56; restoring the same five production files to 4aa66b62e3 reproduced the same red state." + }, + "performanceBudget": { + "required": true, + "evidence": "Release performs constant-count indexed resource and identity queries plus one bounded archive capture. Worker-list uses two set queries rather than one resource lookup per worker. Reconciliation remains serial and adds no polling, timers, subprocesses, renderer subscriptions, or provider-wide listing." + }, + "promotionCriteria": [ + "Collect 100 consecutive focused CI passes or 14 days of soak history.", + "Add live headed and headless paired-runtime release/reuse journeys.", + "Add Docker SSH reconnect and physical Windows WSL host-scope evidence.", + "Prove provider-close lost acknowledgements converge with an exact durable close receipt." + ], + "knownGaps": [ + "Provider close has no durable cross-process operation receipt, so a crash after host mutation but before SQLite settlement remains release_pending until exact inventory returns.", + "Federated release remains explicitly unsupported and retained.", + "Mobile/direct remote input takeover and live Linux, Windows, WSL, SSH, headed, and headless paired-runtime release are not exercised." + ], + "demotionRule": "Keep experimental or demote if release can overlap exact reuse, close a conflicting lease, lose immutable output, retain reset archives, fan out per worker, or any focused ordering test flakes without a product or harness defect." + }, { "id": "terminal-render.windows-cjk-repaint", "title": "Windows ConPTY wide glyphs and cursor rewrites repaint without stale cells", @@ -7781,8 +8220,8 @@ "https://github.com/stablyai/orca/pull/5787", "https://github.com/stablyai/orca/pull/8034" ], - "invariant": "After a renderer lifecycle reset (did-start-loading / render-process-gone / destroyed), no surviving PTY remains delivery-gated by pre-reset unacked bytes: main's in-flight counters and pending backlog equal the true state of the new page (zero in-flight, zero pending). Delivery then resumes only once the reloaded page's pty:data dispatcher re-registers and signals pty:rendererDispatcherReady; during the boot window before that handshake main holds all sends (data accrues losslessly in the capped pending backlog) so bytes cannot be dropped into a listener-less page and re-pin the gate. The hold itself cannot become a permanent freeze: a one-shot ~10s watchdog armed on each reset force-opens the gate (incrementing rendererDispatcherReadyForcedCount) if the handshake is lost, and the real handshake or a re-registration cancels it. The reset fires only for a main-frame load: did-start-loading also fires for in-page subframe loads (sandboxed srcDoc iframes in notebook HTML output), which are filtered out via isLoadingMainFrame() so a subframe load never clears accounting or holds the gate on the still-alive page. If a lifecycle-reset edge is missed entirely — a main-frame reload overlapped by an in-page subframe load emits no did-start-loading at all — a backstop still recovers: because the handshake is one-shot per page load, receiving pty:rendererDispatcherReady while the gate is already open proves a reset was missed (or the watchdog force-opened the gate), so the handler reconciles by clearing the stale accounting before re-opening. The renderer sends that handshake exactly once per page load, after its pty:data listener registers.", - "oracle": "Ingest more than 512 KB of PTY output with no renderer ACKs and assert the per-PTY gate closes (sends stop at the 512 KB high-water, remainder accrues as pending). Fire the registered did-start-loading listener and assert rendererInFlightChars and pendingChars are zero and the new diagnostics record the reset (rendererLifecycleResetCount 1, lastLifecycleResetClearedChars 512 KB). Then, before any dispatcher-ready handshake, ingest another chunk and assert it is NOT sent and NOT counted in-flight (held for the boot window, accruing in pending). Finally fire the pty:rendererDispatcherReady handshake and assert the held chunk is delivered to the renderer. Counters-zero without proving both the boot-window hold and that delivery resumes is insufficient. Additional cases prove the boot-window hold also covers the interactive direct-send fast path (input-primed keystroke echo is held, not sent, until the handshake) and that the self-heal watchdog force-opens the gate (rendererDispatcherReadyForcedCount 1) when no handshake arrives, while a timely handshake cancels the watchdog and leaves no orphaned timer. A further case fires did-start-loading with isLoadingMainFrame() false (a subframe/iframe load) and asserts accounting is untouched (rendererLifecycleResetCount stays 0, pending preserved, ready stays true) and delivery still drains on ACK — proving an in-page iframe load cannot trigger a spurious freeze. A backstop case saturates the gate, then fires pty:rendererDispatcherReady while the gate is still open (ready true) with no preceding reset — modeling a missed lifecycle edge — and asserts the handler reconciles: in-flight and pending clear, rendererLifecycleResetCount increments, and fresh output flows immediately (a straggler ACK is clamped and cannot underflow). A renderer-side case (pty-dispatcher-pi-routing.test.ts) asserts ensurePtyDispatcher() sends pty:rendererDispatcherReady exactly once across two attach calls — proving the send fires (it is optional-chained) and the one-shot guard holds.", + "invariant": "After a renderer lifecycle reset (main-frame did-start-navigation / render-process-gone / destroyed), no surviving PTY remains delivery-gated by pre-reset unacked bytes: main's in-flight counters and pending backlog equal the true state of the new page (zero in-flight, zero pending). Delivery then resumes only once the reloaded page's pty:data dispatcher re-registers and signals pty:rendererDispatcherReady; during the boot window before that handshake main holds all sends (data accrues losslessly in the capped pending backlog) so bytes cannot be dropped into a listener-less page and re-pin the gate. The hold itself cannot become a permanent freeze: a one-shot ~10s watchdog armed on each reset force-opens the gate (incrementing rendererDispatcherReadyForcedCount) if the handshake is lost, and the real handshake or a re-registration cancels it. The reset fires only for a new-document main-frame navigation: did-start-navigation carries exact frame and same-document details, so overlapping subframe or in-page navigation never clears accounting or holds the gate on the still-alive page. If a renderer lifecycle edge is otherwise missed, a backstop still recovers: because the handshake is one-shot per page load, receiving pty:rendererDispatcherReady while the gate is already open proves a reset was missed (or the watchdog force-opened the gate), so the handler reconciles by clearing the stale accounting before re-opening. The renderer sends that handshake exactly once per page load, after its pty:data listener registers.", + "oracle": "Ingest more than 512 KB of PTY output with no renderer ACKs and assert the per-PTY gate closes (sends stop at the 512 KB high-water, remainder accrues as pending). Fire the registered main-frame did-start-navigation listener and assert rendererInFlightChars and pendingChars are zero and the new diagnostics record the reset (rendererLifecycleResetCount 1, lastLifecycleResetClearedChars 512 KB). Then, before any dispatcher-ready handshake, ingest another chunk and assert it is NOT sent and NOT counted in-flight (held for the boot window, accruing in pending). Finally fire the pty:rendererDispatcherReady handshake and assert the held chunk is delivered to the renderer. Counters-zero without proving both the boot-window hold and that delivery resumes is insufficient. Additional cases prove the boot-window hold also covers the interactive direct-send fast path (input-primed keystroke echo is held, not sent, until the handshake) and that the self-heal watchdog force-opens the gate (rendererDispatcherReadyForcedCount 1) when no handshake arrives, while a timely handshake cancels the watchdog and leaves no orphaned timer. A further case opens the new page with a main-frame navigation and dispatcher handshake, then fires an overlapping subframe navigation and asserts the gate stays ready, the reset count stays at exactly one, and fresh output delivers without the watchdog — proving an iframe cannot reclose the live page. A backstop case saturates the gate, then fires pty:rendererDispatcherReady while the gate is still open (ready true) with no preceding reset — modeling a missed lifecycle edge — and asserts the handler reconciles: in-flight and pending clear, rendererLifecycleResetCount increments, and fresh output flows immediately (a straggler ACK is clamped and cannot underflow). A renderer-side case (pty-dispatcher-pi-routing.test.ts) asserts ensurePtyDispatcher() sends pty:rendererDispatcherReady exactly once across two attach calls — proving the send fires (it is optional-chained) and the one-shot guard holds.", "commands": [ "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/pty.test.ts src/renderer/src/components/terminal-pane/pty-dispatcher-pi-routing.test.ts" ], @@ -7795,12 +8234,12 @@ "file": "src/main/ipc/pty.test.ts", "assertions": [ "a PTY saturated past the 512 KB per-PTY high-water with no ACKs stops sending and accrues pending output (gate closed)", - "firing the registered did-start-loading listener zeroes rendererInFlightChars and pendingData and records rendererLifecycleResetCount and lastLifecycleResetClearedChars", + "firing the registered main-frame did-start-navigation listener zeroes rendererInFlightChars and pendingData and records rendererLifecycleResetCount and lastLifecycleResetClearedChars", "after the reset, output ingested during the boot window is NOT sent and NOT counted in-flight until the pty:rendererDispatcherReady handshake fires (held in pending)", "firing the pty:rendererDispatcherReady handshake releases the held backlog and delivery resumes (delivery gated on the handshake, not just counters cleared)", "interactive input-primed keystroke echo is also held during the boot window (interactive fast path gated on the handshake) and delivered once it fires", "when no handshake arrives, the ~10s watchdog force-opens the gate (rendererDispatcherReadyForcedCount 1) and the held backlog drains; a timely handshake cancels the watchdog and leaves no orphaned timer", - "a did-start-loading with isLoadingMainFrame() false (in-page subframe/iframe load) does NOT reset accounting (rendererLifecycleResetCount stays 0, pending and in-flight preserved, rendererPtyDispatcherReady stays true) and delivery still drains on ACK", + "an overlapping subframe did-start-navigation after the fresh dispatcher handshake does NOT reclose delivery (rendererLifecycleResetCount stays 1, rendererPtyDispatcherReady stays true, forced count stays 0) and fresh output delivers immediately", "a pty:rendererDispatcherReady handshake arriving while the gate is still open (ready true, no preceding reset — a missed lifecycle edge) reconciles the stale accounting: in-flight and pending clear, rendererLifecycleResetCount increments, fresh output flows, and a straggler ACK is clamped", "re-registering handlers (macOS re-activate / new window) cancels the prior registration's armed dispatcher-ready watchdog via the cross-registration bridge, leaving no orphaned ~10s timer to force-open a dead window's gate" ] @@ -7814,13 +8253,13 @@ ], "evidenceRuns": [ { - "date": "2026-07-09", + "date": "2026-08-02", "runner": "local", "platform": "macos", "command": "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/pty.test.ts src/renderer/src/components/terminal-pane/pty-dispatcher-pi-routing.test.ts", "result": "passed", - "durationSeconds": 1, - "summary": "243 tests passed (232 main-process + 11 renderer dispatcher) including the lifecycle-reset, boot-window (dispatcher-ready handshake), interactive-gate hold, watchdog self-heal, main-frame-filter (subframe did-start-loading is ignored), missed-reset reconcile backstop (handshake-while-open), cross-registration watchdog-cancel, and renderer-side one-shot handshake-send regressions. Removing the reset call reproduces the reload freeze (rendererInFlightChars stays 524288); removing the send-hold reproduces the boot-window leak; removing the interactive-path flag check sends keystroke echo into the not-yet-ready page; removing the watchdog arm leaves the gate held forever; removing the watchdog cancel leaves an orphaned timer after the handshake; removing the isLoadingMainFrame filter lets a subframe iframe load run a spurious reset; removing the handshake-while-open reconcile leaves the survivors pinned at 524288 after a missed lifecycle edge." + "durationSeconds": 5, + "summary": "439 tests passed including the lifecycle-reset, boot-window (dispatcher-ready handshake), interactive-gate hold, watchdog self-heal, exact-navigation filter (overlapping subframe navigation is ignored), missed-reset reconcile backstop (handshake-while-open), cross-registration watchdog-cancel, and renderer-side one-shot handshake-send regressions. Removing the reset call reproduces the reload freeze (rendererInFlightChars stays 524288); removing the send-hold reproduces the boot-window leak; removing the interactive-path flag check sends keystroke echo into the not-yet-ready page; removing the watchdog arm leaves the gate held forever; removing the watchdog cancel leaves an orphaned timer after the handshake; switching back to aggregate did-start-loading state lets an overlapping iframe load reclose the gate; removing the handshake-while-open reconcile leaves the survivors pinned at 524288 after a missed lifecycle edge." } ], "runtimeBudget": { @@ -7833,7 +8272,7 @@ }, "redGreenEvidence": { "status": "partial", - "evidence": "Locally verified red/green on every load-bearing branch: (1) reset call removed -> rendererInFlightChars stays 524288 after did-start-loading; (2) boot-window send-hold removed -> post-reload output is sent into the not-yet-ready page ('NOT sent until handshake' fails); (3) interactive-path flag check removed -> input-primed keystroke echo is sent during the hold; (4) watchdog arm removed -> the gate is never force-opened and the held backlog never drains; (5) watchdog cancel removed -> an orphaned ~10s timer survives the handshake (getTimerCount 1); (6) isLoadingMainFrame filter removed -> a subframe did-start-loading runs a spurious reset (rendererLifecycleResetCount 1, pending cleared, ready dropped) — locally verified red; (7) handshake-while-open reconcile removed -> a pty:rendererDispatcherReady arriving after a missed lifecycle edge leaves the gate pinned (rendererInFlightChars stays 524288, pending 90112, rendererLifecycleResetCount 0) — locally verified red; (8) cross-registration bridge cancel removed (top-of-registerPtyHandlers clearRendererDispatcherReadyWatchdog) -> a prior registration's armed watchdog survives re-registration as an orphaned timer (getTimerCount 1 instead of 0) — locally verified red. With the full fix all eight are green. The performance budget below still holds: the watchdog is a single unref'd one-shot per reset, not per-chunk. Needs a saved CI or intentional-break artifact before blocking promotion." + "evidence": "Locally verified red/green on every load-bearing branch: (1) reset call removed -> rendererInFlightChars stays 524288 after main-frame did-start-navigation; (2) boot-window send-hold removed -> post-reload output is sent into the not-yet-ready page ('NOT sent until handshake' fails); (3) interactive-path flag check removed -> input-primed keystroke echo is sent during the hold; (4) watchdog arm removed -> the gate is never force-opened and the held backlog never drains; (5) watchdog cancel removed -> an orphaned ~10s timer survives the handshake (getTimerCount 1); (6) aggregate did-start-loading classification restored -> an overlapping subframe navigation recloses the gate after the handshake (ready false until watchdog) — deterministically red; (7) handshake-while-open reconcile removed -> a pty:rendererDispatcherReady arriving after a missed lifecycle edge leaves the gate pinned (rendererInFlightChars stays 524288, pending 90112, rendererLifecycleResetCount 0) — locally verified red; (8) cross-registration bridge cancel removed (top-of-registerPtyHandlers clearRendererDispatcherReadyWatchdog) -> a prior registration's armed watchdog survives re-registration as an orphaned timer (getTimerCount 1 instead of 0) — locally verified red. With the full fix all eight are green. The performance budget below still holds: the watchdog is a single unref'd one-shot per reset, not per-chunk. Needs a saved CI or intentional-break artifact before blocking promotion." }, "performanceBudget": { "required": true, diff --git a/config/scripts/adhoc-build-version.mjs b/config/scripts/adhoc-build-version.mjs index db7c95676d7..b62f28d1c4f 100644 --- a/config/scripts/adhoc-build-version.mjs +++ b/config/scripts/adhoc-build-version.mjs @@ -2,6 +2,10 @@ import { execFileSync } from 'node:child_process' import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import { formatReleaseTitleTimestamp } from './release-title-timestamp.mjs' +import { + readPublishedVersionsFromEnv, + resolveDevChannelBaseVersion +} from './dev-channel-base-version.mjs' /** Long enough to name a feature, short enough that a picker row stays readable. */ export const ADHOC_LABEL_MAX_LENGTH = 32 @@ -83,12 +87,13 @@ export function formatAdhocReleaseName(version, label, commit, date) { ].join(' • ') } -export function getAdhocBuildIdentity(now = new Date(), label = '') { +export function getAdhocBuildIdentity(now = new Date(), label = '', publishedVersions = []) { const packageJson = JSON.parse(readFileSync(resolve('package.json'), 'utf8')) const commit = execFileSync('git', ['rev-parse', '--short=12', 'HEAD'], { encoding: 'utf8' }).trim() - const version = createAdhocBuildVersion(packageJson.version, now) + const base = resolveDevChannelBaseVersion(packageJson.version, publishedVersions) + const version = createAdhocBuildVersion(base, now) return { commit, version, @@ -98,7 +103,11 @@ export function getAdhocBuildIdentity(now = new Date(), label = '') { } if (process.argv[1] && resolve(process.argv[1]) === resolve(import.meta.filename)) { - const identity = getAdhocBuildIdentity(new Date(), process.env.ORCA_ADHOC_LABEL ?? '') + const identity = getAdhocBuildIdentity( + new Date(), + process.env.ORCA_ADHOC_LABEL ?? '', + readPublishedVersionsFromEnv() + ) // Consumed by the workflow via $GITHUB_OUTPUT. process.stdout.write( `version=${identity.version}\ncommit=${identity.commit}\nlabel=${identity.label}\nname=${identity.name}\n` diff --git a/config/scripts/build-windows-cli-launcher.test.mjs b/config/scripts/build-windows-cli-launcher.test.mjs index 0d14e2373b6..6e4803ed7ba 100644 --- a/config/scripts/build-windows-cli-launcher.test.mjs +++ b/config/scripts/build-windows-cli-launcher.test.mjs @@ -1,4 +1,12 @@ -import { copyFileSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { + copyFileSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + writeFileSync +} from 'node:fs' import { tmpdir } from 'node:os' import { dirname, join, resolve } from 'node:path' import { spawnSync } from 'node:child_process' @@ -31,6 +39,20 @@ describe('Windows CLI launcher', () => { } }) + itCrossHost('never materializes the child environment block from ProcessStartInfo', () => { + // Why: both ProcessStartInfo env properties copy the process block into a case-insensitive + // dictionary that throws when the inherited block holds PATH and Path (stablyai/orca#12046). + const source = readFileSync( + join(projectRoot, 'native', 'windows-cli-launcher', 'OrcaCliLauncher.cs'), + 'utf8' + ) + const code = source.replace(/^\s*\/\/.*$/gm, '') + + expect(code).not.toContain('EnvironmentVariables') + expect(code).not.toContain('startInfo.Environment') + expect(code).toContain('Environment.SetEnvironmentVariable') + }) + itWindows('preserves a multiline argument from PowerShell through the native launcher', () => { const appRoot = mkdtempSync(join(tmpdir(), 'orca cli launcher ')) try { @@ -89,4 +111,70 @@ describe('Windows CLI launcher', () => { rmSync(appRoot, { recursive: true, force: true }) } }) + + itWindows('survives an inherited environment block containing PATH and Path', () => { + const appRoot = mkdtempSync(join(tmpdir(), 'orca duplicate path launcher ')) + try { + const resourcesPath = join(appRoot, 'resources') + const launcherPath = join(resourcesPath, 'bin', 'orca.exe') + const cliPath = join(resourcesPath, 'app.asar.unpacked', 'out', 'cli', 'index.js') + const outputPath = join(appRoot, 'child-result.json') + const harnessSourcePath = join( + projectRoot, + 'config', + 'scripts', + 'fixtures', + 'DuplicatePathProcessLauncher.cs' + ) + const harnessPath = join(appRoot, 'DuplicatePathLauncher.exe') + mkdirSync(dirname(launcherPath), { recursive: true }) + mkdirSync(dirname(cliPath), { recursive: true }) + copyFileSync(process.execPath, join(appRoot, 'Orca.exe')) + writeFileSync( + cliPath, + `require('node:fs').writeFileSync(process.env.ORCA_TEST_OUTPUT, JSON.stringify({ + electronRunAsNode: process.env.ELECTRON_RUN_AS_NODE, + pathKeys: Object.keys(process.env).filter((key) => key.toLowerCase() === 'path') +}))\n`, + 'utf8' + ) + const build = spawnSync( + process.execPath, + ['config/scripts/build-windows-cli-launcher.mjs', '--output', launcherPath], + { cwd: projectRoot, encoding: 'utf8' } + ) + expect(build.status, `${build.stdout}\n${build.stderr}`).toBe(0) + + const compiler = findFrameworkCompiler() + expect(compiler).not.toBeNull() + const compileHarness = spawnSync( + compiler, + ['/nologo', '/target:exe', `/out:${harnessPath}`, harnessSourcePath], + { encoding: 'utf8' } + ) + expect(compileHarness.status, `${compileHarness.stdout}\n${compileHarness.stderr}`).toBe(0) + + const launch = spawnSync(harnessPath, [launcherPath, outputPath], { encoding: 'utf8' }) + expect(launch.status, `${launch.stdout}\n${launch.stderr}`).toBe(0) + expect(JSON.parse(readFileSync(outputPath, 'utf8'))).toEqual({ + electronRunAsNode: '1', + pathKeys: ['PATH', 'Path'] + }) + } finally { + rmSync(appRoot, { recursive: true, force: true }) + } + }) }) + +function findFrameworkCompiler() { + const windowsDirectory = process.env.WINDIR ?? process.env.SystemRoot + if (!windowsDirectory) { + return null + } + return ( + [ + join(windowsDirectory, 'Microsoft.NET', 'Framework64', 'v4.0.30319', 'csc.exe'), + join(windowsDirectory, 'Microsoft.NET', 'Framework', 'v4.0.30319', 'csc.exe') + ].find((candidate) => existsSync(candidate)) ?? null + ) +} diff --git a/config/scripts/dev-channel-base-version.mjs b/config/scripts/dev-channel-base-version.mjs new file mode 100644 index 00000000000..62a28c6a374 --- /dev/null +++ b/config/scripts/dev-channel-base-version.mjs @@ -0,0 +1,66 @@ +const SEMVER = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/ + +function parseVersionTriple(value) { + const match = SEMVER.exec(String(value ?? '').trim()) + if (!match) { + return null + } + return { + major: Number(match[1]), + minor: Number(match[2]), + patch: Number(match[3]), + prerelease: match[4] ?? null + } +} + +function compareTriples(a, b) { + return a.major - b.major || a.minor - b.minor || a.patch - b.patch +} + +/** + * The base `X.Y.Z` an hourly or adhoc build should carry. + * + * Why not package.json alone: main's version only moves on `release:` commits, and + * stable patches are cut from release branches that never merge back. On + * 2026-08-03 main read `1.4.165-rc.0` for twenty hours while 1.4.165, 1.4.166 and + * 1.4.167 all shipped — so hourlies built from that main claimed 1.4.165 while + * carrying code newer than 1.4.167, and sorted *below* the stable their user was + * already running. Published tags are the only honest answer to "what number is + * taken"; package.json is a floor, not a source of truth. + */ +export function resolveDevChannelBaseVersion(packageVersion, publishedVersions = []) { + const fromPackage = parseVersionTriple(packageVersion) + if (!fromPackage) { + throw new Error(`Package version is not valid semver: ${packageVersion}`) + } + + // Unparseable tags are skipped rather than fatal: the main repo carries old tags + // that predate the current scheme, and one of them must not fail every build. + const published = publishedVersions.map(parseVersionTriple).filter(Boolean) + + let base = fromPackage + if (published.length > 0) { + const highest = published.reduce((best, entry) => + compareTriples(entry, best) > 0 ? entry : best + ) + // A shipped stable owns its number, so the next dev build belongs on the patch + // above it. A bare prerelease does not — rc.1 of 1.4.168 means 1.4.168 is still + // the version being worked toward, which is exactly what main is building. + const shipped = published.some( + (entry) => !entry.prerelease && compareTriples(entry, highest) === 0 + ) + const next = shipped ? { ...highest, patch: highest.patch + 1 } : highest + if (compareTriples(next, base) > 0) { + base = next + } + } + + return `${base.major}.${base.minor}.${base.patch}` +} + +/** Tag list the workflow reads out of the main repo, newline separated. */ +export function readPublishedVersionsFromEnv(value = process.env.ORCA_PUBLISHED_VERSIONS) { + return String(value ?? '') + .split(/\s+/) + .filter(Boolean) +} diff --git a/config/scripts/dev-channel-base-version.test.mjs b/config/scripts/dev-channel-base-version.test.mjs new file mode 100644 index 00000000000..d2631eff0e9 --- /dev/null +++ b/config/scripts/dev-channel-base-version.test.mjs @@ -0,0 +1,67 @@ +import { describe, expect, it } from 'vitest' +import { + readPublishedVersionsFromEnv, + resolveDevChannelBaseVersion +} from './dev-channel-base-version.mjs' + +describe('dev channel base version', () => { + it('falls back to package.json when no tags are supplied', () => { + expect(resolveDevChannelBaseVersion('1.4.168-rc.1')).toBe('1.4.168') + expect(resolveDevChannelBaseVersion('1.4.168', [])).toBe('1.4.168') + }) + + // The bug this exists for: main sat at 1.4.165-rc.0 for twenty hours while three + // stables shipped, so hourlies claimed a version their users had already passed. + it('climbs past stables that shipped while main stood still', () => { + expect( + resolveDevChannelBaseVersion('1.4.165-rc.0', [ + 'v1.4.165', + 'v1.4.166', + 'v1.4.167', + 'v1.4.165-rc.0' + ]) + ).toBe('1.4.168') + }) + + // Why +1 on a stable but not on a prerelease: 1.4.167 is spent, so the next dev + // build is 1.4.168. But 1.4.168-rc.1 means 1.4.168 is still being built toward, + // which is what main holds — claiming 1.4.169 would jump a release nobody cut. + it('takes the patch above a shipped stable and holds at an open prerelease', () => { + expect(resolveDevChannelBaseVersion('1.4.167', ['v1.4.167'])).toBe('1.4.168') + expect(resolveDevChannelBaseVersion('1.4.168-rc.1', ['v1.4.168-rc.1'])).toBe('1.4.168') + }) + + // Why max and not most-recent: a hotfix on an old line published today would + // otherwise drag every subsequent hourly backwards. + it('reads the highest tag, not the last one listed', () => { + expect(resolveDevChannelBaseVersion('1.4.160', ['v1.4.167', 'v1.3.99', 'v1.4.120'])).toBe( + '1.4.168' + ) + }) + + it('treats package.json as a floor when it leads the tags', () => { + expect(resolveDevChannelBaseVersion('1.5.0-rc.0', ['v1.4.167'])).toBe('1.5.0') + }) + + // Why skipped rather than fatal: the main repo carries legacy tags, and one + // unparseable entry must not fail every hourly build. + it('ignores tags it cannot parse', () => { + expect(resolveDevChannelBaseVersion('1.4.160', ['nightly', '', 'v1.4.167', 'latest'])).toBe( + '1.4.168' + ) + }) + + it('rejects a package version that is not semver', () => { + expect(() => resolveDevChannelBaseVersion('not-a-version')).toThrow(/not valid semver/) + }) + + it('carries major and minor rollovers through the bump', () => { + expect(resolveDevChannelBaseVersion('1.4.0', ['v2.0.0'])).toBe('2.0.1') + }) + + it('splits an env tag list on any whitespace', () => { + expect(readPublishedVersionsFromEnv('v1.4.167\nv1.4.166\n')).toEqual(['v1.4.167', 'v1.4.166']) + expect(readPublishedVersionsFromEnv('')).toEqual([]) + expect(readPublishedVersionsFromEnv(undefined)).toEqual([]) + }) +}) diff --git a/config/scripts/electron-builder-config.test.mjs b/config/scripts/electron-builder-config.test.mjs index b7ea67875f9..3227d957b24 100644 --- a/config/scripts/electron-builder-config.test.mjs +++ b/config/scripts/electron-builder-config.test.mjs @@ -420,40 +420,42 @@ describe('electron-builder config', () => { expect(findAsarEntry(['/out/main/index.js'], 'out/main/index.js')).toBe('/out/main/index.js') }) - it('prunes non-target node-pty prebuilds from packaged runtime resources', async () => { + it('prunes non-target node-pty architecture outputs from packaged runtime resources', async () => { const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-node-pty-prune-')) try { - const prebuildsDir = join(resourcesDir, 'node_modules', 'node-pty', 'prebuilds') + const nodePtyDir = join(resourcesDir, 'node_modules', 'node-pty') + const prebuildsDir = join(nodePtyDir, 'prebuilds') + const binDir = join(nodePtyDir, 'bin') await mkdir(join(prebuildsDir, 'darwin-arm64'), { recursive: true }) await mkdir(join(prebuildsDir, 'darwin-x64'), { recursive: true }) await mkdir(join(prebuildsDir, 'linux-x64'), { recursive: true }) await mkdir(join(prebuildsDir, 'win32-x64'), { recursive: true }) - await mkdir(join(resourcesDir, 'node_modules', 'node-pty', 'third_party', 'conpty'), { - recursive: true - }) - await mkdir(join(resourcesDir, 'node_modules', 'node-pty', 'deps', 'winpty'), { + await mkdir(join(binDir, 'darwin-arm64-148'), { recursive: true }) + await mkdir(join(binDir, 'darwin-x64-148'), { recursive: true }) + await mkdir(join(nodePtyDir, 'third_party', 'conpty'), { recursive: true }) + await mkdir(join(nodePtyDir, 'deps', 'winpty'), { recursive: true }) - prunePackagedNodePty(resourcesDir, 'darwin') + prunePackagedNodePty(resourcesDir, 'darwin', 3) - await expect(readdir(prebuildsDir).then((entries) => entries.sort())).resolves.toEqual([ - 'darwin-arm64', - 'darwin-x64' - ]) - await expect( - readdir(join(resourcesDir, 'node_modules', 'node-pty', 'third_party')) - ).resolves.toEqual([]) - await expect( - readdir(join(resourcesDir, 'node_modules', 'node-pty', 'deps')) - ).resolves.toEqual([]) + await expect(readdir(prebuildsDir)).resolves.toEqual(['darwin-arm64']) + await expect(readdir(binDir)).resolves.toEqual(['darwin-arm64-148']) + await expect(readdir(join(nodePtyDir, 'third_party'))).resolves.toEqual([]) + await expect(readdir(join(nodePtyDir, 'deps'))).resolves.toEqual([]) + expect(() => prunePackagedNodePty(resourcesDir, 'darwin', 4)).toThrow( + 'Unsupported packaged runtime architecture: 4' + ) } finally { await rm(resourcesDir, { recursive: true, force: true }) } }) it('copies the Windows node-pty ConPTY runtime beside the rebuilt addon', async () => { - for (const arch of ['x64', 'arm64']) { + for (const [arch, electronArch] of [ + ['x64', 1], + ['arm64', 3] + ]) { const resourcesDir = await mkdtemp(join(tmpdir(), `orca-node-pty-conpty-${arch}-`)) try { const nodePtyDir = join(resourcesDir, 'node_modules', 'node-pty') @@ -472,7 +474,7 @@ describe('electron-builder config', () => { ) } - prunePackagedNodePty(resourcesDir, 'win32', arch) + prunePackagedNodePty(resourcesDir, 'win32', electronArch) await expect(readFile(join(releaseDir, 'conpty', 'conpty.dll'), 'utf8')).resolves.toBe( `dll payload ${arch}` @@ -500,7 +502,7 @@ describe('electron-builder config', () => { ).toBe(true) }) - it('prunes non-target @parcel/watcher platform subpackages from packaged runtime resources', async () => { + it('prunes non-target @parcel/watcher architecture subpackages', async () => { const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-parcel-watcher-prune-')) try { const parcelDir = join(resourcesDir, 'node_modules', '@parcel') @@ -511,13 +513,15 @@ describe('electron-builder config', () => { await mkdir(join(parcelDir, 'watcher-linux-arm64-glibc'), { recursive: true }) await mkdir(join(parcelDir, 'watcher-win32-x64'), { recursive: true }) - prunePackagedParcelWatcher(resourcesDir, 'linux') + prunePackagedParcelWatcher(resourcesDir, 'linux', 'arm64') await expect(readdir(parcelDir).then((entries) => entries.sort())).resolves.toEqual([ 'watcher', - 'watcher-linux-arm64-glibc', - 'watcher-linux-x64-glibc' + 'watcher-linux-arm64-glibc' ]) + expect(() => prunePackagedParcelWatcher(resourcesDir, 'linux', 'universal')).toThrow( + 'Unsupported packaged runtime architecture: universal' + ) } finally { await rm(resourcesDir, { recursive: true, force: true }) } @@ -533,7 +537,7 @@ describe('electron-builder config', () => { // A hypothetical future @parcel/* runtime dep that is NOT a watcher subpackage. await mkdir(join(parcelDir, 'transformer-js'), { recursive: true }) - prunePackagedParcelWatcher(resourcesDir, 'linux') + prunePackagedParcelWatcher(resourcesDir, 'linux', 1) await expect(readdir(parcelDir).then((entries) => entries.sort())).resolves.toEqual([ 'transformer-js', @@ -653,7 +657,8 @@ describe('electron-builder config', () => { await electronBuilderConfig.afterPack({ appOutDir: join(root, 'linux-unpacked'), - electronPlatformName: 'linux' + electronPlatformName: 'linux', + arch: 1 }) expect((await stat(launcherPath)).mode & 0o111).not.toBe(0) @@ -662,4 +667,39 @@ describe('electron-builder config', () => { } } ) + + // Why: the .deb/.rpm update-recovery path keys entirely off the resources/package-type marker that + // app-builder-lib's FpmTarget writes. If packaging silently stops shipping an fpm target, or adds + // one the recovery path does not cover, getLinuxRootPackageType() returns null, autoInstallOnAppQuit + // quietly goes back to true, and no unit test notices. + describe('linux root-package update recovery contract', () => { + // FpmTarget writes resources/package-type only for targets it supports auto-update for. + const MARKER_TARGETS = new Set(['deb', 'rpm', 'pacman']) + const RECOVERABLE_TARGETS = new Set(['deb', 'rpm']) + const linuxTargets = electronBuilderConfig.linux.target.map((entry) => + typeof entry === 'string' ? entry : entry.target + ) + + it('still ships an AppImage plus at least one root-package target', () => { + expect(linuxTargets).toContain('AppImage') + expect(linuxTargets.some((target) => MARKER_TARGETS.has(target))).toBe(true) + }) + + it('ships no root-package target the recovery path cannot recover', () => { + const unrecoverable = linuxTargets.filter( + (target) => MARKER_TARGETS.has(target) && !RECOVERABLE_TARGETS.has(target) + ) + expect(unrecoverable).toEqual([]) + }) + + it('accepts exactly the markers electron-updater maps to a root-package updater', async () => { + const source = await readFile( + new URL('../../src/main/linux-update-package-type.ts', import.meta.url), + 'utf8' + ) + for (const target of linuxTargets.filter((entry) => RECOVERABLE_TARGETS.has(entry))) { + expect(source).toContain(`value === '${target}'`) + } + }) + }) }) diff --git a/config/scripts/fixtures/DuplicatePathProcessLauncher.cs b/config/scripts/fixtures/DuplicatePathProcessLauncher.cs new file mode 100644 index 00000000000..6b46382103b --- /dev/null +++ b/config/scripts/fixtures/DuplicatePathProcessLauncher.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Text; + +internal static class DuplicatePathProcessLauncher +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct StartupInfo + { + public int cb; + public string lpReserved; + public string lpDesktop; + public string lpTitle; + public int dwX; + public int dwY; + public int dwXSize; + public int dwYSize; + public int dwXCountChars; + public int dwYCountChars; + public int dwFillAttribute; + public int dwFlags; + public short wShowWindow; + public short cbReserved2; + public IntPtr lpReserved2; + public IntPtr hStdInput; + public IntPtr hStdOutput; + public IntPtr hStdError; + } + + [StructLayout(LayoutKind.Sequential)] + private struct ProcessInformation + { + public IntPtr hProcess; + public IntPtr hThread; + public int dwProcessId; + public int dwThreadId; + } + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool CreateProcess( + string applicationName, + StringBuilder commandLine, + IntPtr processAttributes, + IntPtr threadAttributes, + bool inheritHandles, + uint creationFlags, + IntPtr environment, + string currentDirectory, + ref StartupInfo startupInfo, + out ProcessInformation processInformation + ); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool GetExitCodeProcess(IntPtr process, out uint exitCode); + + [DllImport("kernel32.dll")] + private static extern bool CloseHandle(IntPtr handle); + + private static int Main(string[] args) + { + List entries = new List(); + foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) + { + if (!String.Equals((string)entry.Key, "PATH", StringComparison.OrdinalIgnoreCase)) + { + entries.Add((string)entry.Key + "=" + (string)entry.Value); + } + } + entries.Add("PATH=C:\\live"); + entries.Add("Path=C:\\shadowed"); + entries.Add("ORCA_TEST_OUTPUT=" + args[1]); + + IntPtr environment = Marshal.StringToHGlobalUni(String.Join("\0", entries.ToArray()) + "\0\0"); + StartupInfo startupInfo = new StartupInfo(); + startupInfo.cb = Marshal.SizeOf(startupInfo); + ProcessInformation processInformation; + try + { + bool started = CreateProcess( + args[0], + new StringBuilder("\"" + args[0] + "\""), + IntPtr.Zero, + IntPtr.Zero, + false, + 0x00000400, + environment, + null, + ref startupInfo, + out processInformation + ); + if (!started) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + finally + { + Marshal.FreeHGlobal(environment); + } + + try + { + WaitForSingleObject(processInformation.hProcess, 0xffffffff); + uint exitCode; + if (!GetExitCodeProcess(processInformation.hProcess, out exitCode)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + return (int)exitCode; + } + finally + { + CloseHandle(processInformation.hThread); + CloseHandle(processInformation.hProcess); + } + } +} diff --git a/config/scripts/hourly-build-version.mjs b/config/scripts/hourly-build-version.mjs index f4545af086b..12257c2b4ff 100644 --- a/config/scripts/hourly-build-version.mjs +++ b/config/scripts/hourly-build-version.mjs @@ -2,6 +2,10 @@ import { execFileSync } from 'node:child_process' import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import { formatReleaseTitleTimestamp } from './release-title-timestamp.mjs' +import { + readPublishedVersionsFromEnv, + resolveDevChannelBaseVersion +} from './dev-channel-base-version.mjs' /** `1.4.160-hourly.202607281400` — UTC to the minute, so tags sort chronologically * by semver and every build is uniquely versioned. */ @@ -45,18 +49,19 @@ export function formatHourlyReleaseName(version, buildNumber, commit, date) { ].join(' • ') } -export function getHourlyBuildIdentity(now = new Date(), buildNumber = 1) { +export function getHourlyBuildIdentity(now = new Date(), buildNumber = 1, publishedVersions = []) { const packageJson = JSON.parse(readFileSync(resolve('package.json'), 'utf8')) const commit = execFileSync('git', ['rev-parse', '--short=12', 'HEAD'], { encoding: 'utf8' }).trim() - const version = createHourlyBuildVersion(packageJson.version, now) + const base = resolveDevChannelBaseVersion(packageJson.version, publishedVersions) + const version = createHourlyBuildVersion(base, now) return { commit, version, name: formatHourlyReleaseName(version, buildNumber, commit, now) } } if (process.argv[1] && resolve(process.argv[1]) === resolve(import.meta.filename)) { const buildNumber = Number(process.env.ORCA_HOURLY_BUILD_NUMBER ?? '1') - const identity = getHourlyBuildIdentity(new Date(), buildNumber) + const identity = getHourlyBuildIdentity(new Date(), buildNumber, readPublishedVersionsFromEnv()) // Consumed by the workflow via $GITHUB_OUTPUT. process.stdout.write( `version=${identity.version}\ncommit=${identity.commit}\nname=${identity.name}\n` diff --git a/config/scripts/live-freeze-bounded-history.mjs b/config/scripts/live-freeze-bounded-history.mjs new file mode 100644 index 00000000000..7b64b7d5246 --- /dev/null +++ b/config/scripts/live-freeze-bounded-history.mjs @@ -0,0 +1,38 @@ +export class BoundedLiveFreezeHistory { + #entries = [] + #limit + #nextIndex = 0 + #totalCount = 0 + + constructor(limit) { + if (!Number.isInteger(limit) || limit <= 0) { + throw new Error(`History limit must be a positive integer, got ${limit}`) + } + this.#limit = limit + } + + add(entry) { + this.#totalCount += 1 + if (this.#entries.length < this.#limit) { + this.#entries.push(entry) + return + } + this.#entries[this.#nextIndex] = entry + this.#nextIndex = (this.#nextIndex + 1) % this.#limit + } + + get retainedCount() { + return this.#entries.length + } + + get totalCount() { + return this.#totalCount + } + + values() { + if (this.#entries.length < this.#limit || this.#nextIndex === 0) { + return [...this.#entries] + } + return [...this.#entries.slice(this.#nextIndex), ...this.#entries.slice(0, this.#nextIndex)] + } +} diff --git a/config/scripts/live-freeze-bounded-history.test.mjs b/config/scripts/live-freeze-bounded-history.test.mjs new file mode 100644 index 00000000000..48d1cfb5b3e --- /dev/null +++ b/config/scripts/live-freeze-bounded-history.test.mjs @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest' +import { BoundedLiveFreezeHistory } from './live-freeze-bounded-history.mjs' + +describe('BoundedLiveFreezeHistory', () => { + it('retains the newest entries in insertion order and counts the full run', () => { + const history = new BoundedLiveFreezeHistory(3) + + for (let value = 1; value <= 7; value += 1) { + history.add(value) + } + + expect(history.values()).toEqual([5, 6, 7]) + expect(history.retainedCount).toBe(3) + expect(history.totalCount).toBe(7) + }) + + it('rejects invalid retention limits', () => { + expect(() => new BoundedLiveFreezeHistory(0)).toThrow('positive integer') + expect(() => new BoundedLiveFreezeHistory(1.5)).toThrow('positive integer') + }) +}) diff --git a/config/scripts/live-remote-bulk-open-freeze-metrics.mjs b/config/scripts/live-remote-bulk-open-freeze-metrics.mjs new file mode 100644 index 00000000000..4f24e59ff2b --- /dev/null +++ b/config/scripts/live-remote-bulk-open-freeze-metrics.mjs @@ -0,0 +1,262 @@ +/** + * Pure metrics helpers for the live remote bulk-open freeze harness. + * Kept separate so unit tests can drive the same code the repro uses. + */ + +export const DEFAULT_SOFT_MS = 2000 +export const DEFAULT_HARD_MS = 5000 + +export function readFreezeNumberEnv(name, fallback) { + const raw = process.env[name] + if (raw == null || raw.trim() === '') { + return fallback + } + const value = Number(raw) + if (!Number.isFinite(value)) { + throw new Error(`Invalid ${name}: expected a finite number, got ${JSON.stringify(raw)}`) + } + return value +} + +export function extractTerminalHandle(result) { + if (!result || typeof result !== 'object') { + return null + } + const candidates = [ + result.handle, + result.terminalHandle, + result.agentTerminalHandle, + typeof result.terminal === 'string' ? result.terminal : result.terminal?.handle, + result.startupTerminal?.handle, + result.tab?.terminal, + result.tab?.handle + ] + for (const value of candidates) { + if (typeof value === 'string' && value.startsWith('term_')) { + return value + } + } + for (const value of Object.values(result)) { + if (typeof value === 'string' && value.startsWith('term_')) { + return value + } + if (value && typeof value === 'object') { + for (const nested of Object.values(value)) { + if (typeof nested === 'string' && nested.startsWith('term_')) { + return nested + } + } + } + } + return null +} + +export function worktreeSelector(wt) { + if (typeof wt?.id === 'string' && wt.id.length > 0) { + return `id:${wt.id}` + } + if (typeof wt?.path === 'string' && wt.path.length > 0) { + return `path:${wt.path}` + } + return null +} + +/** + * Peak stall across individual switch latency and concurrent batch wall. + * Hard freeze when peak >= hardMs (default 5000). + */ +export function evaluateFreezeSignals({ + maxSwitchMs = 0, + maxBatchWallMs = 0, + statusProbeMs = 0, + memoryProbeMs = null, + softMs = DEFAULT_SOFT_MS, + hardMs = DEFAULT_HARD_MS +}) { + const peakLatencyMs = Math.max(maxSwitchMs, maxBatchWallMs) + const softFreeze = + peakLatencyMs >= softMs || + statusProbeMs >= softMs || + (memoryProbeMs != null && memoryProbeMs >= softMs) + const hardFreeze = + peakLatencyMs >= hardMs || + statusProbeMs >= hardMs || + (memoryProbeMs != null && memoryProbeMs >= hardMs) + return { peakLatencyMs, softFreeze, hardFreeze } +} + +export function shouldCapSwitchTargets(maxSwitchTargets) { + return Number.isFinite(maxSwitchTargets) && maxSwitchTargets > 0 +} + +export function applySwitchTargetCap(targets, maxSwitchTargets) { + if (!shouldCapSwitchTargets(maxSwitchTargets)) { + return targets + } + return targets.slice(0, maxSwitchTargets) +} + +/** Scenarios that model real user recovery, not concurrent CLI pileup. */ +export const REALISTIC_SCENARIOS = [ + 'idle-backlog-open', + 'idle-backlog-reconnect-open', + 'restart-proxy', + /** Idle + flood + reconnect storm overlapped with concurrent open fan-out. */ + 'lockup-storm' +] + +/** + * Permanent lockup: app/host stops making progress — not a single recovered timeout. + * Distinct from multi-second hard stall that still recovers (status answers, most opens ok). + */ +export function evaluatePermanentLockup({ + timedOutOps = 0, + statusHangMs = 0, + consecutiveSwitchFailures = 0, + openFailed = 0, + openTotal = 0, + permanentTimeoutMs = 60_000, + /** Fraction of opens that must fail to count as lockup without status hang. */ + failRateThreshold = 0.25, + minTimedOutOps = 3 +}) { + const failRate = openTotal > 0 ? openFailed / openTotal : 0 + const permanentLockup = + statusHangMs >= permanentTimeoutMs || + timedOutOps >= minTimedOutOps || + consecutiveSwitchFailures >= 5 || + (openTotal >= 8 && failRate >= failRateThreshold) + return { + permanentLockup, + timedOutOps, + statusHangMs, + consecutiveSwitchFailures, + failRate, + recoveredHardStallCandidate: + !permanentLockup && timedOutOps < minTimedOutOps && statusHangMs < permanentTimeoutMs + } +} + +/** + * Peak across open latencies + optional reconnect-refresh wall + probes. + * Used by the naturalistic harness (no parallel switch amp). + */ +export function evaluateRealisticFreezeSignals({ + maxOpenMs = 0, + firstOpenMs = 0, + reconnectRefreshMs = 0, + statusProbeMs = 0, + memoryProbeMs = null, + softMs = DEFAULT_SOFT_MS, + hardMs = DEFAULT_HARD_MS +}) { + const peakLatencyMs = Math.max(maxOpenMs, firstOpenMs, reconnectRefreshMs) + return evaluateFreezeSignals({ + maxSwitchMs: peakLatencyMs, + maxBatchWallMs: 0, + statusProbeMs, + memoryProbeMs, + softMs, + hardMs + }) +} + +export function humanPaceDelayMs(baseMs, jitterMs = 0) { + const base = Math.max(0, baseMs) + const jitter = Math.max(0, jitterMs) + if (jitter === 0) { + return base + } + return base + Math.floor(Math.random() * (jitter + 1)) +} + +/** Full-app forever freeze: host RPC dead for a continuous window, not a recovered stall. */ +export const DEFAULT_FOREVER_WINDOW_MS = 30_000 +export const DEFAULT_STATUS_SLOW_MS = 15_000 + +/** + * Analyze mid-storm status samples for a continuous unhealthy window. + * Sample: { tMs, ms, ok, hang } + */ +export function evaluateFullAppFreeze({ + statusSamples = [], + statusSummary = {}, + foreverWindowMs = DEFAULT_FOREVER_WINDOW_MS, + statusSlowMs = DEFAULT_STATUS_SLOW_MS, + killOnlyRecovery = false +}) { + const infrastructureErrors = statusSamples.filter((sample) => sample.infrastructureError) + const infrastructureErrorCount = Math.max( + infrastructureErrors.length, + statusSummary.infrastructureErrorCount ?? 0 + ) + const maxStatusMs = Math.max( + 0, + ...statusSamples.map((s) => s.ms || 0), + statusSummary.maxStatusMs ?? 0 + ) + if (killOnlyRecovery) { + return { + foreverUiLockupObserved: true, + longestUnhealthyWindowMs: foreverWindowMs, + maxStatusMs, + unhealthySampleCount: statusSummary.sampleCount ?? statusSamples.length, + infrastructureErrorCount, + reason: 'kill-only recovery documented' + } + } + + const unhealthy = statusSamples.map((s) => { + const hang = !s.infrastructureError && (Boolean(s.hang) || s.ok === false) + const slow = !s.infrastructureError && (s.ms || 0) >= statusSlowMs + return { ...s, unhealthy: hang || slow } + }) + + let longest = statusSummary.longestUnhealthyWindowMs ?? 0 + let runStart = null + for (const s of unhealthy) { + if (s.unhealthy) { + runStart ??= s.tMs ?? 0 + const end = (s.tMs ?? 0) + (s.ms || 0) + longest = Math.max(longest, end - runStart) + } else { + runStart = null + } + } + + // If timestamps missing, fall back to consecutive unhealthy count * assumed interval. + if (longest === 0 && unhealthy.some((s) => s.unhealthy)) { + let run = 0 + for (const s of unhealthy) { + if (s.unhealthy) { + run += 1 + longest = Math.max(longest, run) + } else { + run = 0 + } + } + // Without wall clock, consecutive count alone is not a ms window. + longest = 0 + } + + const foreverUiLockupObserved = longest >= foreverWindowMs + const unhealthySampleCount = Math.max( + unhealthy.filter((s) => s.unhealthy).length, + statusSummary.unhealthySampleCount ?? 0 + ) + + return { + foreverUiLockupObserved, + longestUnhealthyWindowMs: longest, + maxStatusMs, + unhealthySampleCount, + infrastructureErrorCount, + reason: foreverUiLockupObserved + ? `status unhealthy ≥${foreverWindowMs}ms continuous` + : infrastructureErrorCount > 0 + ? `status watchdog infrastructure errors: ${infrastructureErrorCount}` + : maxStatusMs >= statusSlowMs + ? `status slow peak ${maxStatusMs}ms but no ≥${foreverWindowMs}ms window` + : 'status remained healthy through storm' + } +} diff --git a/config/scripts/live-remote-bulk-open-freeze-metrics.test.mjs b/config/scripts/live-remote-bulk-open-freeze-metrics.test.mjs new file mode 100644 index 00000000000..586364b43ad --- /dev/null +++ b/config/scripts/live-remote-bulk-open-freeze-metrics.test.mjs @@ -0,0 +1,239 @@ +import { describe, expect, it } from 'vitest' +import { + applySwitchTargetCap, + evaluateFreezeSignals, + evaluateFullAppFreeze, + evaluatePermanentLockup, + evaluateRealisticFreezeSignals, + extractTerminalHandle, + humanPaceDelayMs, + readFreezeNumberEnv, + REALISTIC_SCENARIOS, + shouldCapSwitchTargets, + worktreeSelector +} from './live-remote-bulk-open-freeze-metrics.mjs' + +describe('live-remote-bulk-open-freeze-metrics', () => { + it('extracts term_ handles from nested create payloads', () => { + expect(extractTerminalHandle({ handle: 'term_abc' })).toBe('term_abc') + expect(extractTerminalHandle({ terminal: { handle: 'term_nested' } })).toBe('term_nested') + expect(extractTerminalHandle({ tab: { terminal: 'term_tab' } })).toBe('term_tab') + expect(extractTerminalHandle({ startupTerminal: { handle: 'term_start' } })).toBe('term_start') + expect(extractTerminalHandle({ junk: { deep: 'term_deep' } })).toBe('term_deep') + expect(extractTerminalHandle({ handle: 'not-a-term' })).toBeNull() + expect(extractTerminalHandle(null)).toBeNull() + }) + + it('builds worktree selectors from id/path', () => { + expect( + worktreeSelector({ id: 'repo::C:/Users/neil/orca/orca', path: 'C:/Users/neil/orca/orca' }) + ).toBe('id:repo::C:/Users/neil/orca/orca') + expect(worktreeSelector({ path: '/tmp/x' })).toBe('path:/tmp/x') + expect(worktreeSelector({})).toBeNull() + }) + + it('does not cap switch targets when max is 0 (regression for Math.max(2,0) bug)', () => { + expect(shouldCapSwitchTargets(0)).toBe(false) + expect(shouldCapSwitchTargets(-1)).toBe(false) + expect(shouldCapSwitchTargets(2)).toBe(true) + const many = Array.from({ length: 111 }, (_, i) => `term_${i}`) + expect(applySwitchTargetCap(many, 0)).toHaveLength(111) + expect(applySwitchTargetCap(many, 2)).toHaveLength(2) + }) + + it('classifies hard freeze at >=5000ms peak (individual or batch wall)', () => { + expect(evaluateFreezeSignals({ maxSwitchMs: 3874, maxBatchWallMs: 3874 }).hardFreeze).toBe( + false + ) + expect(evaluateFreezeSignals({ maxSwitchMs: 3874, maxBatchWallMs: 3874 }).softFreeze).toBe(true) + + const hardIndividual = evaluateFreezeSignals({ maxSwitchMs: 19954, maxBatchWallMs: 1000 }) + expect(hardIndividual.hardFreeze).toBe(true) + expect(hardIndividual.peakLatencyMs).toBe(19954) + + const hardBatch = evaluateFreezeSignals({ maxSwitchMs: 900, maxBatchWallMs: 20201 }) + expect(hardBatch.hardFreeze).toBe(true) + expect(hardBatch.peakLatencyMs).toBe(20201) + }) + + it('evaluates naturalistic peaks without requiring parallel batch amp', () => { + expect(REALISTIC_SCENARIOS).toContain('idle-backlog-open') + expect(REALISTIC_SCENARIOS).toContain('idle-backlog-reconnect-open') + expect(REALISTIC_SCENARIOS).toContain('lockup-storm') + const soft = evaluateRealisticFreezeSignals({ + maxOpenMs: 3200, + firstOpenMs: 2800, + reconnectRefreshMs: 900 + }) + expect(soft.softFreeze).toBe(true) + expect(soft.hardFreeze).toBe(false) + expect(soft.peakLatencyMs).toBe(3200) + + const hardFromReconnect = evaluateRealisticFreezeSignals({ + maxOpenMs: 800, + firstOpenMs: 700, + reconnectRefreshMs: 6200 + }) + expect(hardFromReconnect.hardFreeze).toBe(true) + expect(hardFromReconnect.peakLatencyMs).toBe(6200) + }) + + it('flags full-app freeze only for continuous unhealthy status window ≥30s', () => { + const healthy = evaluateFullAppFreeze({ + statusSamples: [ + { tMs: 0, ms: 150, ok: true }, + { tMs: 2000, ms: 180, ok: true }, + { tMs: 4000, ms: 140, ok: true } + ], + foreverWindowMs: 30_000, + statusSlowMs: 15_000 + }) + expect(healthy.foreverUiLockupObserved).toBe(false) + + const forever = evaluateFullAppFreeze({ + statusSamples: [ + { tMs: 0, ms: 16_000, ok: true }, + { tMs: 16_000, ms: 16_000, ok: true }, + { tMs: 32_000, ms: 16_000, ok: false, hang: true } + ], + foreverWindowMs: 30_000, + statusSlowMs: 15_000 + }) + expect(forever.foreverUiLockupObserved).toBe(true) + expect(forever.longestUnhealthyWindowMs).toBeGreaterThanOrEqual(30_000) + + expect( + evaluateFullAppFreeze({ statusSamples: [], killOnlyRecovery: true }).foreverUiLockupObserved + ).toBe(true) + }) + + it('does not classify watchdog infrastructure errors as an app freeze', () => { + const result = evaluateFullAppFreeze({ + statusSamples: Array.from({ length: 25 }, (_, index) => ({ + tMs: index * 1500, + ms: 1, + ok: false, + infrastructureError: true, + error: 'spawn ENOENT' + })) + }) + + expect(result.foreverUiLockupObserved).toBe(false) + expect(result.unhealthySampleCount).toBe(0) + expect(result.infrastructureErrorCount).toBe(25) + }) + + it('preserves full-run watchdog peaks after sample retention rotates', () => { + const result = evaluateFullAppFreeze({ + statusSamples: [{ tMs: 60_000, ms: 100, ok: true }], + statusSummary: { + sampleCount: 40, + maxStatusMs: 16_000, + unhealthySampleCount: 3, + infrastructureErrorCount: 2, + longestUnhealthyWindowMs: 32_000 + }, + foreverWindowMs: 30_000, + statusSlowMs: 15_000 + }) + + expect(result.foreverUiLockupObserved).toBe(true) + expect(result.longestUnhealthyWindowMs).toBe(32_000) + expect(result.maxStatusMs).toBe(16_000) + expect(result.unhealthySampleCount).toBe(3) + expect(result.infrastructureErrorCount).toBe(2) + }) + + it('rejects invalid numeric environment values', () => { + process.env.ORCA_FREEZE_TEST_NUMBER = 'not-a-number' + expect(() => readFreezeNumberEnv('ORCA_FREEZE_TEST_NUMBER', 5)).toThrow( + 'Invalid ORCA_FREEZE_TEST_NUMBER' + ) + delete process.env.ORCA_FREEZE_TEST_NUMBER + expect(readFreezeNumberEnv('ORCA_FREEZE_TEST_NUMBER', 5)).toBe(5) + }) + + it('distinguishes recovered hard stall from permanent lockup', () => { + // Single reveal timeout with healthy status is NOT permanent app lockup. + expect( + evaluatePermanentLockup({ + timedOutOps: 1, + statusHangMs: 0, + consecutiveSwitchFailures: 1, + openFailed: 1, + openTotal: 64 + }).permanentLockup + ).toBe(false) + expect( + evaluatePermanentLockup({ + timedOutOps: 3, + statusHangMs: 0, + consecutiveSwitchFailures: 0, + openFailed: 3, + openTotal: 64 + }).permanentLockup + ).toBe(true) + expect( + evaluatePermanentLockup({ + timedOutOps: 0, + statusHangMs: 60_000, + consecutiveSwitchFailures: 0, + permanentTimeoutMs: 60_000 + }).permanentLockup + ).toBe(true) + expect( + evaluatePermanentLockup({ + timedOutOps: 0, + statusHangMs: 0, + consecutiveSwitchFailures: 5 + }).permanentLockup + ).toBe(true) + expect( + evaluatePermanentLockup({ + timedOutOps: 0, + openFailed: 20, + openTotal: 40 + }).permanentLockup + ).toBe(true) + }) + + it('human pace delay stays within base+jitter', () => { + for (let i = 0; i < 20; i += 1) { + const d = humanPaceDelayMs(250, 150) + expect(d).toBeGreaterThanOrEqual(250) + expect(d).toBeLessThanOrEqual(400) + } + expect(humanPaceDelayMs(100, 0)).toBe(100) + }) + + it('reads the real hard-freeze lab report when present', async () => { + const { readdirSync, readFileSync, existsSync } = await import('node:fs') + const { resolve } = await import('node:path') + const reportDir = resolve(process.cwd(), 'test-results/freeze-repro') + if (!existsSync(reportDir)) { + // Local clones without lab artifacts still pass pure metrics tests above. + return + } + const reportName = readdirSync(reportDir).find( + (name) => name.startsWith('live-bulk-open-freeze-') && name.endsWith('.json') + ) + if (reportName == null) { + return + } + const report = JSON.parse(readFileSync(resolve(reportDir, reportName), 'utf8')) + const evaluated = evaluateFreezeSignals({ + maxSwitchMs: report.maxSwitchMs, + maxBatchWallMs: report.maxBatchWallMs ?? 0, + statusProbeMs: report.statusProbeMs ?? 0, + memoryProbeMs: report.memoryProbeMs, + softMs: report.softMs, + hardMs: report.hardMs + }) + expect(evaluated.hardFreeze).toBe(report.hardFreeze) + expect(evaluated.peakLatencyMs).toBeGreaterThanOrEqual(5000) + expect(typeof report.environment).toBe('string') + expect(report.environment.length).toBeGreaterThan(0) + expect(report.switchTargets).toBeGreaterThan(50) + expect(report.parallel).toBeGreaterThanOrEqual(8) + }) +}) diff --git a/config/scripts/live-remote-bulk-open-freeze-repro.mjs b/config/scripts/live-remote-bulk-open-freeze-repro.mjs new file mode 100644 index 00000000000..9da369d7149 --- /dev/null +++ b/config/scripts/live-remote-bulk-open-freeze-repro.mjs @@ -0,0 +1,358 @@ +#!/usr/bin/env node +/** + * Live freeze repro against a running Orca desktop + paired remote runtime. + * + * Models bulk-open of remote sessions under multi-worktree load. + * + * Usage: + * node config/scripts/live-remote-bulk-open-freeze-repro.mjs + * ORCA_FREEZE_ENV=paired-remote ORCA_FREEZE_CREATE=12 ORCA_FREEZE_SWITCH_PASSES=5 \ + * ORCA_FREEZE_PARALLEL=8 node config/scripts/live-remote-bulk-open-freeze-repro.mjs + */ +import { spawnSync } from 'node:child_process' +import { mkdirSync, writeFileSync, copyFileSync } from 'node:fs' +import path from 'node:path' +import { BoundedLiveFreezeHistory } from './live-freeze-bounded-history.mjs' +import { + applySwitchTargetCap, + DEFAULT_HARD_MS, + DEFAULT_SOFT_MS, + evaluateFreezeSignals, + extractTerminalHandle, + readFreezeNumberEnv, + shouldCapSwitchTargets, + worktreeSelector +} from './live-remote-bulk-open-freeze-metrics.mjs' +import { createOrcaRpc } from './live-remote-freeze-rpc.mjs' + +const root = path.resolve(import.meta.dirname, '../..') +const reportDir = path.join(root, 'test-results', 'freeze-repro') +const envName = process.env.ORCA_FREEZE_ENV || 'paired-remote' +const createCount = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_CREATE', 0)) +const switchPasses = Math.max(1, readFreezeNumberEnv('ORCA_FREEZE_SWITCH_PASSES', 3)) +const parallel = Math.max(1, readFreezeNumberEnv('ORCA_FREEZE_PARALLEL', 1)) +// 0 = no cap (use all live terminals). Only positive env values limit targets. +const maxSwitchTargets = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_MAX_SWITCH_TARGETS', 0)) +const softMs = readFreezeNumberEnv('ORCA_FREEZE_SOFT_MS', DEFAULT_SOFT_MS) +const hardMs = readFreezeNumberEnv('ORCA_FREEZE_HARD_MS', DEFAULT_HARD_MS) +const createWorktreeSpan = Math.max(1, readFreezeNumberEnv('ORCA_FREEZE_CREATE_WT_SPAN', 16)) +const preFloodMs = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_PRE_FLOOD_MS', 3000)) +const scratchDir = process.env.ORCA_FREEZE_SCRATCH || '' + +const { orcaJsonSync, orcaJsonAsync } = createOrcaRpc({ envName }) + +async function mapPool(items, concurrency, worker) { + const results = Array.from({ length: items.length }) + let next = 0 + async function run() { + while (next < items.length) { + const index = next + next += 1 + results[index] = await worker(items[index], index) + } + } + const runners = Array.from({ length: Math.min(concurrency, items.length) }, () => run()) + await Promise.all(runners) + return results +} + +function sampleOrcaIfPossible() { + if (process.platform !== 'darwin') { + return null + } + try { + const status = orcaJsonSync(['status'], { local: true }).result + const pid = status?.app?.pid + if (!pid) { + return null + } + const out = path.join(reportDir, `orca-sample-${Date.now()}.txt`) + const sampled = spawnSync('sample', [String(pid), '5', '-file', out], { + timeout: 20_000, + stdio: 'ignore' + }) + return sampled.status === 0 ? out : null + } catch { + return null + } +} + +function floodCommand(marker) { + // Continuous 2KB frames @ ~8ms — agent-like remote output. + const script = + "const m=process.argv[1];process.stdout.write('READY:'+m+'\\n');let f=0;const c='A'.repeat(2048);setInterval(()=>{f++;process.stdout.write('BG:'+m+':'+f+':'+c+'\\n')},8);process.stdin.resume()" + return `node -e ${JSON.stringify(script)} ${JSON.stringify(marker)}` +} + +async function main() { + mkdirSync(reportDir, { recursive: true }) + const notes = [] + const timings = new BoundedLiveFreezeHistory(120) + const amplificationSteps = [] + + console.log( + `[live-freeze] env=${envName} create=${createCount} passes=${switchPasses} parallel=${parallel}` + ) + + const status = orcaJsonSync(['status']) + notes.push( + `remote version=${status.result?.runtime?.appVersion} state=${status.result?.runtime?.state}` + ) + const local = orcaJsonSync(['status'], { local: true }) + notes.push(`local version=${local.result?.runtime?.appVersion} pid=${local.result?.app?.pid}`) + + const worktrees = orcaJsonSync(['worktree', 'list']).result + const wtList = worktrees?.worktrees || worktrees?.items || worktrees || [] + if (!Array.isArray(wtList) || wtList.length === 0) { + throw new Error(`No worktrees on environment ${envName}`) + } + notes.push(`remote worktrees=${wtList.length}`) + amplificationSteps.push(`baseline worktrees=${wtList.length}`) + + const targets = wtList.slice(0, Math.min(createWorktreeSpan, wtList.length)) + const created = [] + + // Parallel flood-terminal creates across many worktrees. + if (createCount > 0) { + amplificationSteps.push(`create=${createCount} parallel=${Math.min(parallel, createCount)}`) + const createJobs = Array.from({ length: createCount }, (_, i) => i) + await mapPool(createJobs, Math.min(parallel, createCount), async (i) => { + const wt = targets[i % targets.length] + const selector = worktreeSelector(wt) + if (!selector) { + notes.push(`create ${i} skipped: no selector`) + return + } + const marker = `LIVE_BULK_${Date.now()}_${i}` + try { + const createdTerm = await orcaJsonAsync( + [ + 'terminal', + 'create', + '--worktree', + selector, + '--title', + `freeze-repro-${i}`, + '--command', + floodCommand(marker) + ], + { timeoutMs: 180_000 } + ) + timings.add({ op: 'terminal.create', ms: createdTerm.elapsedMs, ok: true, index: i }) + const handle = extractTerminalHandle(createdTerm.result) + if (handle) { + created.push({ handle, marker, worktree: selector }) + console.log( + `[live-freeze] created ${handle} on ${selector} in ${createdTerm.elapsedMs.toFixed(0)}ms` + ) + } else { + notes.push( + `create ${i} missing handle: ${JSON.stringify(createdTerm.result).slice(0, 400)}` + ) + } + } catch (error) { + timings.add({ op: 'terminal.create', ms: null, ok: false, error: String(error), index: i }) + notes.push(`create ${i} failed: ${String(error).slice(0, 300)}`) + console.warn(`[live-freeze] create failed: ${String(error)}`) + } + }) + } + + if (preFloodMs > 0 && created.length > 0) { + amplificationSteps.push(`preFloodMs=${preFloodMs}`) + await new Promise((r) => setTimeout(r, preFloodMs)) + } + + let live = [] + try { + const listed = orcaJsonSync(['terminal', 'list']) + const terms = listed.result?.terminals || [] + live = terms + .filter( + (t) => typeof t.handle === 'string' && t.handle.startsWith('term_') && t.connected !== false + ) + .map((t) => ({ handle: t.handle, title: t.title, worktreeId: t.worktreeId })) + notes.push(`live terminals listed=${live.length}`) + } catch (error) { + notes.push(`terminal list failed: ${String(error).slice(0, 200)}`) + } + + let switchTargets = [...created.map((c) => c.handle), ...live.map((t) => t.handle)].filter( + (v, i, a) => typeof v === 'string' && a.indexOf(v) === i + ) + + if (shouldCapSwitchTargets(maxSwitchTargets) && switchTargets.length > maxSwitchTargets) { + switchTargets = applySwitchTargetCap(switchTargets, maxSwitchTargets) + amplificationSteps.push(`capped switchTargets=${maxSwitchTargets}`) + } + + if (switchTargets.length < 2) { + throw new Error( + `Need ≥2 terminals to bulk-switch; got ${switchTargets.length}. notes=${notes.join('; ')}` + ) + } + + amplificationSteps.push( + `switchTargets=${switchTargets.length} passes=${switchPasses} parallel=${parallel}` + ) + console.log( + `[live-freeze] bulk-switching ${switchTargets.length} terminals × ${switchPasses} passes (parallel=${parallel})` + ) + + let maxSwitchMs = 0 + let maxBatchWallMs = 0 + let sumSwitchMs = 0 + let switchCount = 0 + const switchStarted = performance.now() + + for (let pass = 0; pass < switchPasses; pass += 1) { + // Chunk targets into concurrent batches — piles load onto client/UI path. + for (let offset = 0; offset < switchTargets.length; offset += parallel) { + const batch = switchTargets.slice(offset, offset + parallel) + const batchStarted = performance.now() + const batchResults = await Promise.all( + batch.map(async (handle) => { + try { + const sw = await orcaJsonAsync(['terminal', 'switch', '--terminal', handle], { + timeoutMs: 90_000 + }) + return { handle, ms: sw.elapsedMs, ok: true } + } catch (error) { + return { handle, error: String(error), ok: false } + } + }) + ) + const batchWall = performance.now() - batchStarted + maxBatchWallMs = Math.max(maxBatchWallMs, batchWall) + for (const item of batchResults) { + if (item.ok) { + maxSwitchMs = Math.max(maxSwitchMs, item.ms) + sumSwitchMs += item.ms + switchCount += 1 + timings.add({ op: 'terminal.switch', handle: item.handle, ms: item.ms, batchWall }) + if (item.ms >= softMs) { + console.warn(`[live-freeze] SOFT lag on switch ${item.handle}: ${item.ms.toFixed(0)}ms`) + } + if (item.ms >= hardMs) { + console.warn(`[live-freeze] HARD lag on switch ${item.handle}: ${item.ms.toFixed(0)}ms`) + } + } else { + timings.add({ op: 'terminal.switch', handle: item.handle, error: item.error }) + notes.push(`switch ${item.handle} failed: ${String(item.error).slice(0, 200)}`) + } + } + if (batchWall >= softMs) { + console.warn(`[live-freeze] SOFT batch wall=${batchWall.toFixed(0)}ms size=${batch.length}`) + } + if (batchWall >= hardMs) { + console.warn(`[live-freeze] HARD batch wall=${batchWall.toFixed(0)}ms size=${batch.length}`) + } + } + } + + const bulkWallMs = performance.now() - switchStarted + const avgSwitchMs = switchCount ? sumSwitchMs / switchCount : 0 + + const statusProbe = orcaJsonSync(['status'], { local: true }) + let memoryProbeMs = null + try { + const mem = orcaJsonSync(['diagnostics', 'memory'], { local: true, timeoutMs: 120_000 }) + memoryProbeMs = mem.elapsedMs + notes.push(`memory diagnostic ms=${mem.elapsedMs.toFixed(0)}`) + } catch (error) { + notes.push(`memory diagnostic failed: ${String(error).slice(0, 200)}`) + } + + const { peakLatencyMs, softFreeze, hardFreeze } = evaluateFreezeSignals({ + maxSwitchMs, + maxBatchWallMs, + statusProbeMs: statusProbe.elapsedMs, + memoryProbeMs, + softMs, + hardMs + }) + + let samplePath = null + if (softFreeze || hardFreeze) { + samplePath = sampleOrcaIfPossible() + if (samplePath) { + notes.push(`sample=${samplePath}`) + } else { + notes.push('sample unavailable') + } + } + + const report = { + topology: 'live-paired-remote', + environment: envName, + localVersion: local.result?.runtime?.appVersion, + remoteVersion: status.result?.runtime?.appVersion, + remoteWorktreeCount: wtList.length, + createdTerminals: created.length, + switchTargets: switchTargets.length, + switchPasses, + parallel, + maxSwitchMs, + maxBatchWallMs, + peakLatencyMs, + avgSwitchMs, + bulkWallMs, + statusProbeMs: statusProbe.elapsedMs, + memoryProbeMs, + softFreeze, + hardFreeze, + softMs, + hardMs, + amplificationSteps, + notes, + timingCount: timings.totalCount, + timings: timings.values() + } + + const outPath = path.join(reportDir, `live-bulk-open-freeze-${envName}.json`) + writeFileSync(outPath, `${JSON.stringify(report, null, 2)}\n`) + // Also write a stamped peak report so amplification runs don't overwrite history. + const stamped = path.join(reportDir, `live-bulk-open-freeze-${envName}-peak-${Date.now()}.json`) + writeFileSync(stamped, `${JSON.stringify(report, null, 2)}\n`) + console.log(`[live-freeze] report ${outPath}`) + console.log(`[live-freeze] stamped ${stamped}`) + console.log(JSON.stringify(report, null, 2)) + + if (scratchDir) { + try { + mkdirSync(scratchDir, { recursive: true }) + copyFileSync(outPath, path.join(scratchDir, 'live-bulk-open-freeze-report.json')) + writeFileSync( + path.join(scratchDir, 'live-freeze-amplify-summary.json'), + `${JSON.stringify( + { + peakLatencyMs, + hardFreeze, + softFreeze, + amplificationSteps, + stamped + }, + null, + 2 + )}\n` + ) + } catch (error) { + notes.push(`scratch copy failed: ${String(error).slice(0, 200)}`) + } + } + + if (hardFreeze) { + process.exitCode = 2 + console.error('[live-freeze] HARD FREEZE SIGNAL') + } else if (softFreeze) { + process.exitCode = 1 + console.error('[live-freeze] SOFT FREEZE SIGNAL') + } else { + console.log('[live-freeze] no freeze signal under thresholds') + } +} + +main().catch((error) => { + console.error('[live-freeze] failed', error) + process.exit(3) +}) diff --git a/config/scripts/live-remote-freeze-rpc.mjs b/config/scripts/live-remote-freeze-rpc.mjs new file mode 100644 index 00000000000..cb018147bbe --- /dev/null +++ b/config/scripts/live-remote-freeze-rpc.mjs @@ -0,0 +1,241 @@ +import { spawn, spawnSync } from 'node:child_process' +import path from 'node:path' + +export const MAX_ORCA_RPC_OUTPUT_BYTES = 20 * 1024 * 1024 + +export function appendOrcaRpcOutput(output, chunk, bytes, limit = MAX_ORCA_RPC_OUTPUT_BYTES) { + const nextBytes = bytes + Buffer.byteLength(chunk) + return { + output: nextBytes > limit ? output : output + chunk, + bytes: nextBytes, + exceeded: nextBytes > limit + } +} + +export function resolveOrcaCliCommand({ env = process.env, platform = process.platform } = {}) { + if (env.ORCA_CLI_COMMAND?.trim()) { + return env.ORCA_CLI_COMMAND.trim() + } + if (env.ORCA_DEV_REPO_ROOT) { + return 'orca-dev' + } + return platform === 'linux' ? 'orca-ide' : 'orca' +} + +export function resolveOrcaCliInvocation({ + env = process.env, + platform = process.platform, + nodeExecutable = process.execPath +} = {}) { + const command = resolveOrcaCliCommand({ env, platform }) + const commandName = platform === 'win32' ? path.win32.basename(command).toLowerCase() : command + if ( + platform === 'win32' && + env.ORCA_DEV_REPO_ROOT && + (commandName === 'orca-dev' || commandName === 'orca-dev.cmd') + ) { + const defaultUserDataPath = path.win32.join( + env.APPDATA ?? path.win32.join(env.USERPROFILE ?? '', 'AppData', 'Roaming'), + 'orca-dev' + ) + return { + command: nodeExecutable, + prefixArgs: [path.win32.join(env.ORCA_DEV_REPO_ROOT, 'out', 'cli', 'index.js')], + env: { + ...env, + ORCA_USER_DATA_PATH: + env.ORCA_USER_DATA_PATH ?? env.ORCA_DEV_USER_DATA_PATH ?? defaultUserDataPath, + ORCA_DEV_CLI_INVOCATION: '1', + ORCA_APP_EXECUTABLE: + env.ORCA_APP_EXECUTABLE ?? + path.win32.join( + env.ORCA_DEV_REPO_ROOT, + 'node_modules', + 'electron', + 'dist', + 'electron.exe' + ), + ORCA_APP_EXECUTABLE_NEEDS_APP_ROOT: '1' + } + } + } + return { command, prefixArgs: [] } +} + +export function createOrcaRpc({ + envName, + cliCommand, + env = process.env, + platform = process.platform +}) { + const cliInvocation = cliCommand + ? { command: cliCommand, prefixArgs: [] } + : resolveOrcaCliInvocation({ env, platform }) + const commandLabel = cliCommand ?? resolveOrcaCliCommand({ env, platform }) + const commandArgs = (args, local) => [ + ...cliInvocation.prefixArgs, + ...args, + ...(local ? [] : ['--environment', envName]), + '--json' + ] + + function orcaJsonSync(args, opts = {}) { + const started = performance.now() + const result = spawnSync(cliInvocation.command, commandArgs(args, opts.local), { + encoding: 'utf8', + env: cliInvocation.env, + maxBuffer: MAX_ORCA_RPC_OUTPUT_BYTES, + timeout: opts.timeoutMs ?? 120_000 + }) + const elapsedMs = performance.now() - started + if (result.error) { + throw new Error(`${commandLabel} ${args.join(' ')} failed to start: ${String(result.error)}`) + } + if (result.status !== 0) { + throw new Error( + `${commandLabel} ${args.join(' ')} failed (${result.status}): ${result.stderr || result.stdout}` + ) + } + const parsed = JSON.parse(result.stdout) + if (parsed.ok === false) { + throw new Error(`${commandLabel} ${args.join(' ')} ok=false: ${JSON.stringify(parsed)}`) + } + return { parsed, elapsedMs, result: parsed.result } + } + + function orcaJsonAsync(args, opts = {}) { + const started = performance.now() + return new Promise((resolve, reject) => { + const child = spawn(cliInvocation.command, commandArgs(args, opts.local), { + env: cliInvocation.env, + stdio: ['ignore', 'pipe', 'pipe'] + }) + let stdout = '' + let stderr = '' + let outputBytes = 0 + let settled = false + let timer + const fail = (error) => { + if (settled) { + return + } + settled = true + clearTimeout(timer) + reject(error) + } + const append = (stream, chunk) => { + if (settled) { + return stream + } + const appended = appendOrcaRpcOutput(stream, chunk, outputBytes) + outputBytes = appended.bytes + if (appended.exceeded) { + child.kill('SIGKILL') + fail(new Error(`${commandLabel} ${args.join(' ')} exceeded 20 MiB output limit`)) + return stream + } + return appended.output + } + timer = setTimeout(() => { + child.kill('SIGKILL') + fail( + new Error( + `${commandLabel} ${args.join(' ')} timed out after ${opts.timeoutMs ?? 120_000}ms` + ) + ) + }, opts.timeoutMs ?? 120_000) + child.stdout.setEncoding('utf8') + child.stderr.setEncoding('utf8') + child.stdout.on('data', (chunk) => { + stdout = append(stdout, chunk) + }) + child.stderr.on('data', (chunk) => { + stderr = append(stderr, chunk) + }) + child.on('error', fail) + child.on('close', (code) => { + if (settled) { + return + } + clearTimeout(timer) + const elapsedMs = performance.now() - started + if (code !== 0) { + fail( + new Error( + `${commandLabel} ${args.join(' ')} failed (${code}): ${stderr || stdout}`.slice( + 0, + 800 + ) + ) + ) + return + } + try { + const parsed = JSON.parse(stdout) + if (parsed.ok === false) { + fail( + new Error( + `${commandLabel} ${args.join(' ')} ok=false: ${JSON.stringify(parsed)}`.slice( + 0, + 800 + ) + ) + ) + return + } + settled = true + resolve({ parsed, elapsedMs, result: parsed.result }) + } catch (error) { + fail( + new Error( + `${commandLabel} parse failed: ${String(error)}; stdout=${stdout.slice(0, 400)}` + ) + ) + } + }) + }) + } + + async function runReconnectRefreshStorm(notes) { + const started = performance.now() + const jobs = [ + () => orcaJsonAsync(['status'], { timeoutMs: 90_000 }), + () => orcaJsonAsync(['worktree', 'list'], { timeoutMs: 120_000 }), + () => orcaJsonAsync(['terminal', 'list'], { timeoutMs: 120_000 }), + () => orcaJsonAsync(['status'], { local: true, timeoutMs: 60_000 }), + () => orcaJsonAsync(['worktree', 'list'], { timeoutMs: 120_000 }), + () => orcaJsonAsync(['terminal', 'list'], { timeoutMs: 120_000 }) + ] + const results = await Promise.all( + jobs.map(async (job, index) => { + try { + const result = await job() + return { index, ok: true, ms: result.elapsedMs } + } catch (error) { + notes.push(`reconnect-refresh job ${index} failed: ${String(error).slice(0, 200)}`) + return { index, ok: false, ms: null, error: String(error) } + } + }) + ) + const wallMs = performance.now() - started + const maxJobMs = Math.max(0, ...results.map((result) => result.ms || 0)) + notes.push( + `reconnect-refresh wall=${wallMs.toFixed(0)}ms maxJob=${maxJobMs.toFixed(0)}ms ok=${results.filter((result) => result.ok).length}/${results.length}` + ) + return { wallMs, maxJobMs, results } + } + + async function runRestartProxy(notes) { + const started = performance.now() + try { + const opened = await orcaJsonAsync(['open'], { local: true, timeoutMs: 120_000 }) + notes.push(`orca open ms=${opened.elapsedMs.toFixed(0)}`) + } catch (error) { + notes.push(`orca open failed: ${String(error).slice(0, 200)}`) + } + const storm = await runReconnectRefreshStorm(notes) + return { wallMs: performance.now() - started, storm } + } + + return { orcaJsonSync, orcaJsonAsync, runReconnectRefreshStorm, runRestartProxy } +} diff --git a/config/scripts/live-remote-freeze-rpc.test.mjs b/config/scripts/live-remote-freeze-rpc.test.mjs new file mode 100644 index 00000000000..e68bd09dfb5 --- /dev/null +++ b/config/scripts/live-remote-freeze-rpc.test.mjs @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest' +import { + appendOrcaRpcOutput, + resolveOrcaCliCommand, + resolveOrcaCliInvocation +} from './live-remote-freeze-rpc.mjs' + +describe('live remote freeze RPC', () => { + it('resolves the Orca CLI for managed, dev, Linux, and default runtimes', () => { + expect(resolveOrcaCliCommand({ env: { ORCA_CLI_COMMAND: 'custom-orca' } })).toBe('custom-orca') + expect(resolveOrcaCliCommand({ env: { ORCA_DEV_REPO_ROOT: '/repo' } })).toBe('orca-dev') + expect(resolveOrcaCliCommand({ env: {}, platform: 'linux' })).toBe('orca-ide') + expect(resolveOrcaCliCommand({ env: {}, platform: 'win32' })).toBe('orca') + }) + + it('bypasses the Windows dev cmd shim with the built Node CLI', () => { + const invocation = resolveOrcaCliInvocation({ + env: { + APPDATA: 'C:\\Users\\dev\\AppData\\Roaming', + ORCA_CLI_COMMAND: 'C:\\repo\\out\\bin\\orca-dev.cmd', + ORCA_DEV_REPO_ROOT: 'C:\\repo' + }, + platform: 'win32', + nodeExecutable: 'C:\\Program Files\\nodejs\\node.exe' + }) + + expect(invocation).toMatchObject({ + command: 'C:\\Program Files\\nodejs\\node.exe', + prefixArgs: ['C:\\repo\\out\\cli\\index.js'], + env: { + ORCA_USER_DATA_PATH: 'C:\\Users\\dev\\AppData\\Roaming\\orca-dev', + ORCA_DEV_CLI_INVOCATION: '1', + ORCA_APP_EXECUTABLE: 'C:\\repo\\node_modules\\electron\\dist\\electron.exe', + ORCA_APP_EXECUTABLE_NEEDS_APP_ROOT: '1' + } + }) + }) + + it('caps combined asynchronous output before retaining the overflow chunk', () => { + const first = appendOrcaRpcOutput('', '1234', 0, 5) + expect(first).toEqual({ output: '1234', bytes: 4, exceeded: false }) + + const overflow = appendOrcaRpcOutput(first.output, '67', first.bytes, 5) + expect(overflow).toEqual({ output: '1234', bytes: 6, exceeded: true }) + }) +}) diff --git a/config/scripts/live-remote-realistic-freeze-repro.mjs b/config/scripts/live-remote-realistic-freeze-repro.mjs new file mode 100644 index 00000000000..40820f48a4d --- /dev/null +++ b/config/scripts/live-remote-realistic-freeze-repro.mjs @@ -0,0 +1,645 @@ +#!/usr/bin/env node +/** + * Naturalistic freeze repro — idle/reconnect recovery stories on large remotes. + * + * Unlike the bulk parallel-switch amplifier, this models: + * 1) agents streaming on remote while user is idle (backlog builds) + * 2) user returns and opens sessions one-by-one (or after reconnect refresh) + * + * Scenarios: + * idle-backlog-open — idle with flood, then human-paced sequential open + * idle-backlog-reconnect-open — same + wake-like metadata refresh storm, then open + * restart-proxy — idle, then orca open + status/list storm + open + * (does NOT kill the desktop; proxies restore work) + * + * Usage: + * ORCA_FREEZE_ENV=paired-remote ORCA_FREEZE_SCENARIO=idle-backlog-open \ + * node config/scripts/live-remote-realistic-freeze-repro.mjs + * + * pnpm run repro:live-remote-realistic-freeze + */ +import { spawnSync } from 'node:child_process' +import { copyFileSync, mkdirSync, writeFileSync } from 'node:fs' +import path from 'node:path' +import { createOrcaRpc } from './live-remote-freeze-rpc.mjs' +import { startStatusWatchdog } from './live-remote-status-watchdog.mjs' +import { BoundedLiveFreezeHistory } from './live-freeze-bounded-history.mjs' +import { + DEFAULT_FOREVER_WINDOW_MS, + DEFAULT_HARD_MS, + DEFAULT_SOFT_MS, + DEFAULT_STATUS_SLOW_MS, + evaluateFullAppFreeze, + evaluatePermanentLockup, + evaluateRealisticFreezeSignals, + extractTerminalHandle, + humanPaceDelayMs, + readFreezeNumberEnv, + REALISTIC_SCENARIOS, + worktreeSelector +} from './live-remote-bulk-open-freeze-metrics.mjs' + +const root = path.resolve(import.meta.dirname, '../..') +const reportDir = path.join(root, 'test-results', 'freeze-repro') +const envName = process.env.ORCA_FREEZE_ENV || 'paired-remote' +const scenario = process.env.ORCA_FREEZE_SCENARIO || 'idle-backlog-open' +const createCount = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_CREATE', 0)) +const openCount = Math.max(2, readFreezeNumberEnv('ORCA_FREEZE_OPEN_COUNT', 20)) +const idleMs = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_IDLE_MS', 45_000)) +const paceMs = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_PACE_MS', 250)) +const paceJitterMs = Math.max(0, readFreezeNumberEnv('ORCA_FREEZE_PACE_JITTER_MS', 150)) +const createWorktreeSpan = Math.max(1, readFreezeNumberEnv('ORCA_FREEZE_CREATE_WT_SPAN', 12)) +const softMs = readFreezeNumberEnv('ORCA_FREEZE_SOFT_MS', DEFAULT_SOFT_MS) +const hardMs = readFreezeNumberEnv('ORCA_FREEZE_HARD_MS', DEFAULT_HARD_MS) +/** Concurrent opens during lockup-storm (wake refresh overlaps fan-out). */ +const stormParallel = Math.max(1, readFreezeNumberEnv('ORCA_FREEZE_STORM_PARALLEL', 16)) +/** Kill a switch if it exceeds this — counts toward permanent lockup. */ +const opTimeoutMs = Math.max(10_000, readFreezeNumberEnv('ORCA_FREEZE_OP_TIMEOUT_MS', 60_000)) +const permanentTimeoutMs = Math.max(15_000, readFreezeNumberEnv('ORCA_FREEZE_PERMANENT_MS', 60_000)) +const foreverWindowMs = Math.max( + 10_000, + readFreezeNumberEnv('ORCA_FREEZE_FOREVER_WINDOW_MS', DEFAULT_FOREVER_WINDOW_MS) +) +const statusSlowMs = Math.max( + 5_000, + readFreezeNumberEnv('ORCA_FREEZE_STATUS_SLOW_MS', DEFAULT_STATUS_SLOW_MS) +) +const watchdogIntervalMs = Math.max( + 500, + readFreezeNumberEnv('ORCA_FREEZE_WATCHDOG_INTERVAL_MS', 1500) +) +const scratchDir = process.env.ORCA_FREEZE_SCRATCH || '' + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +const rpc = createOrcaRpc({ envName }) +const { orcaJsonSync, orcaJsonAsync, runReconnectRefreshStorm, runRestartProxy } = rpc + +async function mapPool(items, concurrency, worker) { + const results = Array.from({ length: items.length }) + let next = 0 + async function run() { + while (next < items.length) { + const index = next + next += 1 + results[index] = await worker(items[index], index) + } + } + await Promise.all( + Array.from({ length: Math.min(concurrency, Math.max(items.length, 1)) }, () => run()) + ) + return results +} + +function floodCommand(marker) { + const script = + "const m=process.argv[1];process.stdout.write('READY:'+m+'\n');let f=0;const c='A'.repeat(2048);setInterval(()=>{f++;process.stdout.write('BG:'+m+':'+f+':'+c+'\n')},8);process.stdin.resume()" + return `node -e ${JSON.stringify(script)} ${JSON.stringify(marker)}` +} + +function sampleOrcaIfPossible() { + if (process.platform !== 'darwin') { + return null + } + try { + const status = orcaJsonSync(['status'], { local: true }).result + const pid = status?.app?.pid + if (!pid) { + return null + } + const out = path.join(reportDir, `orca-sample-realistic-${Date.now()}.txt`) + const sampled = spawnSync('sample', [String(pid), '5', '-file', out], { + timeout: 20_000, + stdio: 'ignore' + }) + return sampled.status === 0 ? out : null + } catch { + return null + } +} + +function listLiveTerminalHandles() { + const listed = orcaJsonSync(['terminal', 'list']) + const terms = listed.result?.terminals || [] + return terms + .filter((t) => typeof t.handle === 'string' && t.handle.startsWith('term_')) + .map((t) => ({ + handle: t.handle, + title: t.title, + worktreeId: t.worktreeId, + connected: t.connected + })) +} + +async function main() { + if (!REALISTIC_SCENARIOS.includes(scenario)) { + throw new Error( + `Unknown ORCA_FREEZE_SCENARIO=${scenario}. Expected one of: ${REALISTIC_SCENARIOS.join(', ')}` + ) + } + + mkdirSync(reportDir, { recursive: true }) + const notes = [] + const phases = [] + const openTimings = new BoundedLiveFreezeHistory(100) + + console.log( + `[realistic-freeze] scenario=${scenario} env=${envName} create=${createCount} idleMs=${idleMs} openCount=${openCount} paceMs=${paceMs}` + ) + + const local = orcaJsonSync(['status'], { local: true }) + const remote = orcaJsonSync(['status']) + notes.push( + `local version=${local.result?.runtime?.appVersion} pid=${local.result?.app?.pid}`, + `remote version=${remote.result?.runtime?.appVersion} state=${remote.result?.runtime?.state}` + ) + + const worktrees = orcaJsonSync(['worktree', 'list']).result + const wtList = worktrees?.worktrees || worktrees?.items || worktrees || [] + if (!Array.isArray(wtList) || wtList.length === 0) { + throw new Error(`No worktrees on environment ${envName}`) + } + notes.push(`remote worktrees=${wtList.length}`) + phases.push({ phase: 'baseline', worktrees: wtList.length }) + + // --- Phase: seed flood terminals (agent-like backlog sources) --- + const created = [] + if (createCount > 0) { + const targets = wtList.slice(0, Math.min(createWorktreeSpan, wtList.length)) + await mapPool( + Array.from({ length: createCount }, (_, i) => i), + Math.min(4, createCount), + async (i) => { + const wt = targets[i % targets.length] + const selector = worktreeSelector(wt) + if (!selector) { + return + } + const marker = `REALISTIC_${Date.now()}_${i}` + try { + const createdTerm = await orcaJsonAsync( + [ + 'terminal', + 'create', + '--worktree', + selector, + '--title', + `realistic-freeze-${i}`, + '--command', + floodCommand(marker) + ], + { timeoutMs: 180_000 } + ) + const handle = extractTerminalHandle(createdTerm.result) + if (handle) { + created.push({ handle, marker, worktree: selector }) + console.log( + `[realistic-freeze] flood terminal ${handle} (${createdTerm.elapsedMs.toFixed(0)}ms)` + ) + } else { + notes.push( + `create ${i} missing handle: ${JSON.stringify(createdTerm.result).slice(0, 300)}` + ) + } + } catch (error) { + notes.push(`create ${i} failed: ${String(error).slice(0, 250)}`) + console.warn(`[realistic-freeze] create failed: ${String(error)}`) + } + } + ) + phases.push({ phase: 'seed-flood', created: created.length }) + } + + // Prefer created floods for open pass; fill with existing live terminals. + let live = [] + try { + live = listLiveTerminalHandles() + notes.push(`live terminals listed=${live.length}`) + } catch (error) { + notes.push(`terminal list failed: ${String(error).slice(0, 200)}`) + } + + const openTargets = [...created.map((c) => c.handle), ...live.map((t) => t.handle)].filter( + (v, i, a) => typeof v === 'string' && a.indexOf(v) === i + ) + + if (openTargets.length < 2) { + throw new Error(`Need ≥2 terminals; got ${openTargets.length}. ${notes.join('; ')}`) + } + + const openList = openTargets.slice(0, Math.min(openCount, openTargets.length)) + + // --- Phase: park — leave one session focused, rest accumulate flood while "away" --- + try { + const parkHandle = openList[0] + const parked = await orcaJsonAsync(['terminal', 'switch', '--terminal', parkHandle], { + timeoutMs: 60_000 + }) + notes.push(`park switch ms=${parked.elapsedMs.toFixed(0)} handle=${parkHandle}`) + } catch (error) { + notes.push(`park switch failed: ${String(error).slice(0, 200)}`) + } + + console.log(`[realistic-freeze] idle ${idleMs}ms while remotes stream (user away / asleep)`) + const idleStarted = performance.now() + await sleep(idleMs) + phases.push({ phase: 'idle', idleMs, actualMs: performance.now() - idleStarted }) + + // --- Phase: recovery trigger --- + let reconnectRefreshMs = 0 + let timedOutOps = 0 + let consecutiveSwitchFailures = 0 + let maxConsecutiveSwitchFailures = 0 + + if (scenario === 'idle-backlog-reconnect-open' || scenario === 'lockup-storm') { + console.log( + '[realistic-freeze] wake/reconnect proxy: parallel status/worktree/terminal refresh' + ) + const storm = await runReconnectRefreshStorm(notes) + reconnectRefreshMs = Math.max(storm.wallMs, storm.maxJobMs) + phases.push({ + phase: 'reconnect-refresh', + wallMs: storm.wallMs, + maxJobMs: storm.maxJobMs + }) + } else if (scenario === 'restart-proxy') { + console.log('[realistic-freeze] restart proxy: orca open + refresh storm (no process kill)') + const restart = await runRestartProxy(notes) + reconnectRefreshMs = Math.max(restart.wallMs, restart.storm.wallMs, restart.storm.maxJobMs) + phases.push({ + phase: 'restart-proxy', + wallMs: restart.wallMs, + reconnectWallMs: restart.storm.wallMs + }) + } + + // --- Phase: open sessions --- + // lockup-storm: overlap a second reconnect storm with concurrent switch fan-out + // (models wake + bulk session restore, not human serial clicks). + let maxOpenMs = 0 + let firstOpenMs = 0 + let sumOpenMs = 0 + let openOk = 0 + let maxBatchWallMs = 0 + const openStarted = performance.now() + + let statusWatch = null + if (scenario === 'lockup-storm') { + console.log( + `[realistic-freeze] LOCKUP STORM: concurrent open parallel=${stormParallel} + overlapping reconnect refresh (timeout=${opTimeoutMs}ms); mid-storm status watchdog every ${watchdogIntervalMs}ms` + ) + statusWatch = startStatusWatchdog({ + intervalMs: watchdogIntervalMs, + timeoutMs: Math.min(permanentTimeoutMs, foreverWindowMs), + statusSlowMs + }) + // Fire reconnect storm again concurrently with first open wave. + const overlapStormPromise = runReconnectRefreshStorm(notes) + for (let offset = 0; offset < openList.length; offset += stormParallel) { + const batch = openList.slice(offset, offset + stormParallel) + const batchStarted = performance.now() + const batchResults = await Promise.all( + batch.map(async (handle, batchIndex) => { + const index = offset + batchIndex + try { + const sw = await orcaJsonAsync(['terminal', 'switch', '--terminal', handle], { + timeoutMs: opTimeoutMs + }) + return { handle, index, ms: sw.elapsedMs, ok: true, timedOut: false } + } catch (error) { + const msg = String(error) + const timedOut = /timed out/i.test(msg) + return { handle, index, error: msg, ok: false, timedOut } + } + }) + ) + const batchWall = performance.now() - batchStarted + maxBatchWallMs = Math.max(maxBatchWallMs, batchWall) + for (const item of batchResults) { + if (item.ok) { + openOk += 1 + sumOpenMs += item.ms + maxOpenMs = Math.max(maxOpenMs, item.ms) + if (item.index === 0 || firstOpenMs === 0) { + firstOpenMs = item.ms + } + consecutiveSwitchFailures = 0 + openTimings.add({ + handle: item.handle, + ms: item.ms, + index: item.index, + batchWall + }) + if (item.ms >= hardMs) { + console.warn( + `[realistic-freeze] HARD open #${item.index} ${item.handle}: ${item.ms.toFixed(0)}ms` + ) + } + } else { + if (item.timedOut) { + timedOutOps += 1 + } + consecutiveSwitchFailures += 1 + maxConsecutiveSwitchFailures = Math.max( + maxConsecutiveSwitchFailures, + consecutiveSwitchFailures + ) + openTimings.add({ + handle: item.handle, + error: item.error, + index: item.index, + timedOut: item.timedOut + }) + notes.push( + `open ${item.handle} failed${item.timedOut ? ' (TIMEOUT)' : ''}: ${String(item.error).slice(0, 160)}` + ) + console.warn( + `[realistic-freeze] open FAIL #${item.index}${item.timedOut ? ' TIMEOUT' : ''}: ${item.handle}` + ) + } + } + if (batchWall >= hardMs) { + console.warn( + `[realistic-freeze] HARD batch wall=${batchWall.toFixed(0)}ms size=${batch.length}` + ) + } + } + try { + const overlap = await overlapStormPromise + reconnectRefreshMs = Math.max(reconnectRefreshMs, overlap.wallMs, overlap.maxJobMs) + phases.push({ + phase: 'overlap-reconnect-refresh', + wallMs: overlap.wallMs, + maxJobMs: overlap.maxJobMs + }) + } catch (error) { + notes.push(`overlap reconnect failed: ${String(error).slice(0, 200)}`) + } + phases.push({ + phase: 'lockup-storm-open', + count: openList.length, + ok: openOk, + maxOpenMs, + firstOpenMs, + maxBatchWallMs, + timedOutOps, + parallel: stormParallel + }) + } else { + console.log( + `[realistic-freeze] human-paced open of ${openList.length} sessions (pace≈${paceMs}ms + jitter)` + ) + for (let i = 0; i < openList.length; i += 1) { + const handle = openList[i] + try { + const sw = await orcaJsonAsync(['terminal', 'switch', '--terminal', handle], { + timeoutMs: opTimeoutMs + }) + openOk += 1 + sumOpenMs += sw.elapsedMs + maxOpenMs = Math.max(maxOpenMs, sw.elapsedMs) + if (i === 0) { + firstOpenMs = sw.elapsedMs + } + consecutiveSwitchFailures = 0 + openTimings.add({ handle, ms: sw.elapsedMs, index: i }) + if (sw.elapsedMs >= softMs) { + console.warn(`[realistic-freeze] SOFT open #${i} ${handle}: ${sw.elapsedMs.toFixed(0)}ms`) + } + if (sw.elapsedMs >= hardMs) { + console.warn(`[realistic-freeze] HARD open #${i} ${handle}: ${sw.elapsedMs.toFixed(0)}ms`) + } + } catch (error) { + const msg = String(error) + const timedOut = /timed out/i.test(msg) + if (timedOut) { + timedOutOps += 1 + } + consecutiveSwitchFailures += 1 + maxConsecutiveSwitchFailures = Math.max( + maxConsecutiveSwitchFailures, + consecutiveSwitchFailures + ) + openTimings.add({ handle, error: msg, index: i, timedOut }) + notes.push(`open ${handle} failed${timedOut ? ' (TIMEOUT)' : ''}: ${msg.slice(0, 200)}`) + } + if (i < openList.length - 1) { + await sleep(humanPaceDelayMs(paceMs, paceJitterMs)) + } + } + phases.push({ + phase: 'human-paced-open', + count: openList.length, + ok: openOk, + maxOpenMs, + firstOpenMs, + openWallMs: performance.now() - openStarted + }) + } + + const openWallMs = performance.now() - openStarted + + let midStormWatch = { + samples: [], + durationMs: 0, + sampleCount: 0, + maxStatusMs: 0, + unhealthySampleCount: 0, + infrastructureErrorCount: 0, + longestUnhealthyWindowMs: 0 + } + if (statusWatch) { + midStormWatch = await statusWatch.stop() + notes.push( + `mid-storm status samples=${midStormWatch.sampleCount} durationMs=${midStormWatch.durationMs.toFixed(0)}` + ) + phases.push({ + phase: 'mid-storm-status-watchdog', + samples: midStormWatch.sampleCount, + durationMs: midStormWatch.durationMs, + maxStatusMs: midStormWatch.maxStatusMs + }) + } + + // Post-storm health: does local status still answer? + let statusProbeMs = null + let statusHangMs = 0 + const statusStarted = performance.now() + try { + const statusProbe = await orcaJsonAsync(['status'], { + local: true, + timeoutMs: permanentTimeoutMs + }) + statusProbeMs = statusProbe.elapsedMs + } catch (error) { + statusHangMs = performance.now() - statusStarted + notes.push( + `status probe FAILED after ${statusHangMs.toFixed(0)}ms: ${String(error).slice(0, 200)}` + ) + console.error(`[realistic-freeze] status probe failed — possible permanent lockup`) + } + + let memoryProbeMs = null + try { + const mem = await orcaJsonAsync(['diagnostics', 'memory'], { + local: true, + timeoutMs: permanentTimeoutMs + }) + memoryProbeMs = mem.elapsedMs + notes.push(`memory diagnostic ms=${mem.elapsedMs.toFixed(0)}`) + } catch (error) { + notes.push(`memory diagnostic failed: ${String(error).slice(0, 200)}`) + } + + const peakForSignals = Math.max(maxOpenMs, firstOpenMs, maxBatchWallMs) + const signals = evaluateRealisticFreezeSignals({ + maxOpenMs: peakForSignals, + firstOpenMs, + reconnectRefreshMs, + statusProbeMs: statusProbeMs ?? 0, + memoryProbeMs, + softMs, + hardMs + }) + + const lockup = evaluatePermanentLockup({ + timedOutOps, + statusHangMs, + consecutiveSwitchFailures: maxConsecutiveSwitchFailures, + openFailed: openList.length - openOk, + openTotal: openList.length, + permanentTimeoutMs + }) + + const fullApp = evaluateFullAppFreeze({ + statusSamples: midStormWatch.samples, + statusSummary: midStormWatch, + foreverWindowMs, + statusSlowMs + }) + const watchdogInfrastructureErrorCount = midStormWatch.infrastructureErrorCount + if (statusHangMs >= foreverWindowMs) { + fullApp.foreverUiLockupObserved = true + fullApp.longestUnhealthyWindowMs = Math.max(fullApp.longestUnhealthyWindowMs, statusHangMs) + fullApp.reason = `post-storm status hang ${statusHangMs.toFixed(0)}ms` + } + + const recoveredHardStall = signals.hardFreeze && !fullApp.foreverUiLockupObserved && openOk > 0 + + let samplePath = null + if (signals.softFreeze || signals.hardFreeze || fullApp.foreverUiLockupObserved) { + samplePath = sampleOrcaIfPossible() + if (samplePath) { + notes.push(`sample=${samplePath}`) + } else { + notes.push('sample unavailable') + } + } + + const storyByScenario = { + 'idle-backlog-open': 'User away while remotes stream; returns and opens sessions one-by-one.', + 'idle-backlog-reconnect-open': + 'User away; wake-like reconnect metadata storm; then opens sessions.', + 'restart-proxy': 'User away; restart-proxy discovery; then opens sessions.', + 'lockup-storm': + 'Idle flood + reconnect refresh + concurrent open + mid-storm status watchdog (full-app freeze bar).' + } + + const report = { + topology: 'live-paired-remote-realistic', + scenario, + story: storyByScenario[scenario] || scenario, + environment: envName, + localVersion: local.result?.runtime?.appVersion, + remoteVersion: remote.result?.runtime?.appVersion, + remoteWorktreeCount: wtList.length, + createdFloodTerminals: created.length, + openTargets: openList.length, + idleMs, + paceMs, + paceJitterMs, + stormParallel: scenario === 'lockup-storm' ? stormParallel : 1, + firstOpenMs, + maxOpenMs, + maxBatchWallMs, + avgOpenMs: openOk ? sumOpenMs / openOk : 0, + openWallMs, + openOk, + openFailed: openList.length - openOk, + reconnectRefreshMs, + peakLatencyMs: Math.max(signals.peakLatencyMs, maxBatchWallMs), + statusProbeMs, + statusHangMs, + memoryProbeMs, + softFreeze: signals.softFreeze, + hardFreeze: signals.hardFreeze, + recoveredHardStall, + permanentLockup: lockup.permanentLockup, + foreverUiLockupObserved: fullApp.foreverUiLockupObserved, + foreverFreeze: fullApp, + midStormStatusSamples: midStormWatch.samples, + midStormStatusSampleCount: midStormWatch.sampleCount, + watchdogInfrastructureErrorCount, + timedOutOps, + maxConsecutiveSwitchFailures, + softMs, + hardMs, + foreverWindowMs, + statusSlowMs, + permanentTimeoutMs, + opTimeoutMs, + phases, + notes, + openTimingCount: openTimings.totalCount, + openTimings: openTimings.values() + } + + const outPath = path.join(reportDir, `live-realistic-freeze-${envName}-${scenario}.json`) + const stamped = path.join( + reportDir, + `live-realistic-freeze-${envName}-${scenario}-peak-${Date.now()}.json` + ) + writeFileSync(outPath, `${JSON.stringify(report, null, 2)}\n`) + writeFileSync(stamped, `${JSON.stringify(report, null, 2)}\n`) + console.log(`[realistic-freeze] report ${outPath}`) + console.log(JSON.stringify(report, null, 2)) + + if (scratchDir) { + try { + mkdirSync(scratchDir, { recursive: true }) + copyFileSync(outPath, path.join(scratchDir, 'live-realistic-freeze-report.json')) + } catch (error) { + console.warn(`[realistic-freeze] scratch copy failed: ${String(error)}`) + } + } + + if (watchdogInfrastructureErrorCount > 0) { + process.exitCode = 3 + console.error('[realistic-freeze] WATCHDOG INFRASTRUCTURE FAILURE') + } else if (fullApp.foreverUiLockupObserved) { + process.exitCode = 5 + console.error('[realistic-freeze] FULL-APP FOREVER FREEZE (status unhealthy ≥ forever window)') + } else if (lockup.permanentLockup) { + process.exitCode = 4 + console.error( + '[realistic-freeze] PERMANENT LOCKUP HEURISTIC (timeouts/fail-rate) — check foreverUiLockupObserved' + ) + } else if (signals.hardFreeze) { + process.exitCode = 2 + console.error( + '[realistic-freeze] HARD FREEZE SIGNAL (recovered multi-second stall — not forever lockup)' + ) + } else if (signals.softFreeze) { + process.exitCode = 1 + console.error('[realistic-freeze] SOFT FREEZE SIGNAL') + } else { + console.log('[realistic-freeze] no freeze signal under thresholds') + } +} + +main().catch((error) => { + console.error('[realistic-freeze] failed', error) + process.exit(3) +}) diff --git a/config/scripts/live-remote-status-watchdog.mjs b/config/scripts/live-remote-status-watchdog.mjs new file mode 100644 index 00000000000..9e3951437fd --- /dev/null +++ b/config/scripts/live-remote-status-watchdog.mjs @@ -0,0 +1,147 @@ +/** + * Mid-storm host health samples for forever-freeze detection. + * Polls `orca status --json` on an interval while a load storm runs. + */ +import { spawn } from 'node:child_process' +import { BoundedLiveFreezeHistory } from './live-freeze-bounded-history.mjs' +import { resolveOrcaCliInvocation } from './live-remote-freeze-rpc.mjs' + +/** + * @param {{ intervalMs?: number, timeoutMs?: number, cliCommand?: string, sampleHistoryLimit?: number, statusSlowMs?: number }} opts + */ +export function startStatusWatchdog(opts = {}) { + const intervalMs = opts.intervalMs ?? 2000 + const timeoutMs = opts.timeoutMs ?? 30_000 + const cliInvocation = opts.cliCommand + ? { command: opts.cliCommand, prefixArgs: [] } + : resolveOrcaCliInvocation() + const samples = new BoundedLiveFreezeHistory(opts.sampleHistoryLimit ?? 240) + const statusSlowMs = opts.statusSlowMs ?? 15_000 + let stopped = false + let inFlight = false + let infrastructureErrorCount = 0 + let longestUnhealthyWindowMs = 0 + let maxStatusMs = 0 + let runStartMs = null + let unhealthySampleCount = 0 + const startedAt = performance.now() + + const record = (sample) => { + samples.add(sample) + maxStatusMs = Math.max(maxStatusMs, sample.ms || 0) + if (sample.infrastructureError) { + infrastructureErrorCount += 1 + } + const unhealthy = + !sample.infrastructureError && + (Boolean(sample.hang) || sample.ok === false || (sample.ms || 0) >= statusSlowMs) + if (!unhealthy) { + runStartMs = null + return + } + unhealthySampleCount += 1 + runStartMs ??= sample.tMs ?? 0 + longestUnhealthyWindowMs = Math.max( + longestUnhealthyWindowMs, + (sample.tMs ?? 0) + (sample.ms || 0) - runStartMs + ) + } + + const summary = () => ({ + sampleCount: samples.totalCount, + maxStatusMs, + unhealthySampleCount, + infrastructureErrorCount, + longestUnhealthyWindowMs + }) + + const probe = () => + new Promise((resolve) => { + const t0 = performance.now() + const child = spawn( + cliInvocation.command, + [...cliInvocation.prefixArgs, 'status', '--json'], + { + env: cliInvocation.env, + stdio: ['ignore', 'pipe', 'pipe'] + } + ) + let settled = false + const finish = (result) => { + if (settled) { + return + } + settled = true + resolve(result) + } + const timer = setTimeout(() => { + child.kill('SIGKILL') + finish({ + tMs: t0 - startedAt, + ms: performance.now() - t0, + ok: false, + hang: true + }) + }, timeoutMs) + child.stdout.on('data', () => {}) + child.stderr.on('data', () => {}) + child.on('error', (error) => { + clearTimeout(timer) + finish({ + tMs: t0 - startedAt, + ms: performance.now() - t0, + ok: false, + hang: false, + infrastructureError: true, + error: String(error) + }) + }) + child.on('close', (code) => { + clearTimeout(timer) + finish({ + tMs: t0 - startedAt, + ms: performance.now() - t0, + ok: code === 0, + hang: false + }) + }) + }) + + const tick = async ({ force = false } = {}) => { + if ((!force && stopped) || inFlight) { + return + } + inFlight = true + try { + const sample = await probe() + record(sample) + } finally { + inFlight = false + } + } + + const interval = setInterval(() => { + void tick() + }, intervalMs) + void tick() + + return { + stop: async () => { + stopped = true + clearInterval(interval) + // Wait for in-flight probe, then force one final sample. + const deadline = performance.now() + timeoutMs + 1000 + while (inFlight && performance.now() < deadline) { + await new Promise((r) => setTimeout(r, 20)) + } + await tick({ force: true }) + return { + samples: samples.values(), + ...summary(), + durationMs: performance.now() - startedAt + } + }, + getSamples: () => samples.values(), + getSummary: summary + } +} diff --git a/config/scripts/live-remote-status-watchdog.test.mjs b/config/scripts/live-remote-status-watchdog.test.mjs new file mode 100644 index 00000000000..570750aad3b --- /dev/null +++ b/config/scripts/live-remote-status-watchdog.test.mjs @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest' +import { startStatusWatchdog } from './live-remote-status-watchdog.mjs' + +describe('startStatusWatchdog', () => { + it('collects status samples and stops cleanly', async () => { + // Real path: actually invokes `orca status --json` (must be available in CI/dev with Orca or fail soft). + const watch = startStatusWatchdog({ intervalMs: 50, timeoutMs: 5_000 }) + await new Promise((r) => setTimeout(r, 180)) + const result = await watch.stop() + expect(result.samples.length).toBeGreaterThanOrEqual(1) + expect(result.durationMs).toBeGreaterThan(0) + for (const s of result.samples) { + expect(typeof s.ms).toBe('number') + expect(typeof s.ok).toBe('boolean') + expect(typeof s.hang).toBe('boolean') + } + }) + + it('marks CLI spawn failures as infrastructure errors', async () => { + const watch = startStatusWatchdog({ + intervalMs: 50, + timeoutMs: 1000, + cliCommand: 'orca-freeze-watchdog-missing-command' + }) + const result = await watch.stop() + + expect(result.samples.length).toBeGreaterThanOrEqual(1) + expect(result.samples.every((sample) => sample.infrastructureError === true)).toBe(true) + expect(result.samples.every((sample) => sample.hang === false)).toBe(true) + }) + + it('bounds retained samples while preserving full-run counters', async () => { + const watch = startStatusWatchdog({ + intervalMs: 50, + timeoutMs: 1000, + cliCommand: 'orca-freeze-watchdog-missing-command', + sampleHistoryLimit: 1 + }) + const result = await watch.stop() + + expect(result.samples).toHaveLength(1) + expect(result.sampleCount).toBeGreaterThan(result.samples.length) + expect(result.infrastructureErrorCount).toBe(result.sampleCount) + expect(result.maxStatusMs).toBeGreaterThanOrEqual(0) + }) +}) diff --git a/config/scripts/locale-ko-key-overrides.json b/config/scripts/locale-ko-key-overrides.json index 4618f052f1e..9b40ad61f50 100644 --- a/config/scripts/locale-ko-key-overrides.json +++ b/config/scripts/locale-ko-key-overrides.json @@ -5038,5 +5038,14 @@ }, "settings.appearance.statusBar.sshToggleDescription": { "ko": "사용 가능한 SSH 및 원격 Orca 호스트가 있으면 표시합니다." + }, + "auto.components.right.sidebar.AiVaultPanelControls.selectAllAgents": { + "ko": "모두 선택" + }, + "auto.components.right.sidebar.AiVaultPanelControls.clearAgents": { + "ko": "모두 해제" + }, + "auto.components.right.sidebar.AiVaultPanel.noAgentsSelected": { + "ko": "선택된 에이전트가 없습니다" } } diff --git a/config/scripts/orchestration-skill-guidance.test.mjs b/config/scripts/orchestration-skill-guidance.test.mjs index 849fe784b46..e869f652e40 100644 --- a/config/scripts/orchestration-skill-guidance.test.mjs +++ b/config/scripts/orchestration-skill-guidance.test.mjs @@ -227,12 +227,79 @@ describe('orchestration skill guidance', () => { expect(agentGuidance).toContain('After sending `worker_done`, end your turn') expect(agentGuidance).toContain('idle at the agent prompt') - expect(agentGuidance).toContain('Do not poll or keep calling `orca orchestration check`') + expect(agentGuidance).toContain( + 'do not start more work, poll, or attempt to close the terminal yourself' + ) expect(agentGuidance).toContain('fresh preamble + TASK block delivered as new terminal input') expect(skill).not.toContain('post-completion polling messages') expect(skill).not.toContain('every 2 minutes') }) + it('makes settled worker terminal release an explicit coordinator step', () => { + const skill = readSkill() + const workerLoop = getSection(skill, 'Preferred Supervised Worker Loop') + const agentGuidance = getSection(skill, 'Agent Guidance') + const nextAction = getSection(skill, 'Next Action') + + expect(workerLoop).toContain( + '# Process every message. For each accepted worker_done that is not immediately reused:\n' + + 'orca orchestration worker-release --dispatch --json' + ) + expect(workerLoop).toContain( + 'Acknowledge only after every message and required release decision is handled' + ) + expect(workerLoop).toContain( + 'read the `worker.agent_terminal_handle` field of `worker-show --dispatch --json`' + ) + expect(workerLoop).toContain( + 'orca orchestration worker-start --task --terminal --json` so Orca ' + + 'transfers cleanup ownership to the new Dispatch' + ) + expect(workerLoop).toContain( + 'Run `worker-release` after both succeeded and failed `worker_done` reports unless the user ' + + 'explicitly asked to keep that worker live.' + ) + expect(workerLoop).toContain('Release is post-completion cleanup, not cancellation') + expect(workerLoop).toContain('orca orchestration worker-retain --dispatch --json') + expect(workerLoop).toContain( + 'the same Dispatch can be passed to `worker-release`, which clears the requested retention' + ) + expect(agentGuidance).toContain( + 'Coordinators must account for every settled worker terminal before waiting again or ending ' + + 'the turn' + ) + expect(agentGuidance).toContain('released workers remain readable through `worker-read`') + expect(nextAction).toContain( + 'After every accepted `worker_done`, either transfer the exact terminal to an immediate ' + + 'follow-up Dispatch or run `worker-release` before the next wait.' + ) + }) + + it('never authorizes release from idle, timeout, or worker-side triggers', () => { + const skill = readSkill() + const workerLoop = getSection(skill, 'Preferred Supervised Worker Loop') + const agentGuidance = getSection(skill, 'Agent Guidance') + + // The prohibition sentence is the guard the negative patterns below rely on. + expect(workerLoop).toContain( + 'Do not release a worker because of a timeout, TUI idle state, heartbeat, status, question, ' + + 'escalation, or rejected/stale `worker_done`.' + ) + expect(workerLoop).toContain( + 'do not substitute `terminal close`; follow the exact recovery action in the receipt' + ) + expect(skill).not.toMatch( + /release[^.]*\bon (?:a |the )?(?:tui-?idle|idle|timeout|heartbeat|question|escalation)\b/iu + ) + expect(skill).not.toMatch( + /\b(?:after|on|upon) (?:a |the )?(?:tui-?idle|idle state|timeout|heartbeat)\b[^.]*\brelease/iu + ) + expect(agentGuidance).toContain( + 'do not start more work, poll, or attempt to close the terminal yourself' + ) + expect(agentGuidance).not.toMatch(/worker-release[^.]*\byourself\b/iu) + }) + it('documents @grok in the Messaging group address list', () => { const skill = readSkill() const messaging = getSection(skill, 'Messaging') diff --git a/config/scripts/run-internal-dev-setup.mjs b/config/scripts/run-internal-dev-setup.mjs index e585e4a775d..5076017339e 100644 --- a/config/scripts/run-internal-dev-setup.mjs +++ b/config/scripts/run-internal-dev-setup.mjs @@ -20,11 +20,27 @@ function quoteWindowsArg(value) { return `"${value.replace(/"/g, '""')}"` } +// Why: under a Git Bash setup runner, Orca exports ORCA_WORKTREE_PATH in MSYS form (/c/...), which +// cmd.exe cannot resolve. This is the migration pattern for any setup script feeding a native exe. +function posixShellPathToNativeWindowsPath(value) { + const driveMatch = value.match(/^\/([A-Za-z])\/(.*)$/) + if (driveMatch) { + return `${driveMatch[1].toUpperCase()}:\\${driveMatch[2].replace(/\//g, '\\')}` + } + return value +} + function spawnOptionalSetup(spawn, setupPath, worktreePath, platform, env) { if (platform === 'win32') { + const nativeWorktreePath = posixShellPathToNativeWindowsPath(worktreePath) spawn( env.ComSpec || 'cmd.exe', - ['/d', '/s', '/c', `call ${quoteWindowsArg(setupPath)} ${quoteWindowsArg(worktreePath)}`], + [ + '/d', + '/s', + '/c', + `call ${quoteWindowsArg(setupPath)} ${quoteWindowsArg(nativeWorktreePath)}` + ], { stdio: 'inherit', windowsVerbatimArguments: true diff --git a/config/scripts/run-ssh-docker-bulk-open-freeze-e2e.mjs b/config/scripts/run-ssh-docker-bulk-open-freeze-e2e.mjs new file mode 100644 index 00000000000..36fbbf91500 --- /dev/null +++ b/config/scripts/run-ssh-docker-bulk-open-freeze-e2e.mjs @@ -0,0 +1,43 @@ +import { spawnSync } from 'node:child_process' + +const extraArgs = process.argv.slice(2) +const pnpmEntry = process.env.npm_execpath +if (!pnpmEntry) { + throw new Error('npm_execpath is required; run this harness through pnpm') +} +const env = { + ...process.env, + ORCA_E2E_SSH_DOCKER: '1' +} + +const runtime = spawnSync(process.execPath, [pnpmEntry, 'run', 'ensure:electron-runtime'], { + stdio: 'inherit', + env +}) + +if (runtime.status !== 0) { + process.exit(runtime.status ?? 1) +} + +const result = spawnSync( + process.execPath, + [ + pnpmEntry, + 'exec', + 'playwright', + 'test', + 'tests/e2e/ssh-docker-bulk-open-freeze-repro.spec.ts', + '--config', + 'tests/playwright.config.ts', + '--project', + 'electron-headless', + '--workers=1', + ...extraArgs + ], + { + stdio: 'inherit', + env + } +) + +process.exit(result.status ?? 1) diff --git a/config/scripts/setup-adhoc-release-repo.sh b/config/scripts/setup-adhoc-release-repo.sh index d239d930717..3e232c5fce8 100755 --- a/config/scripts/setup-adhoc-release-repo.sh +++ b/config/scripts/setup-adhoc-release-repo.sh @@ -39,14 +39,23 @@ else # Why the features are off: this repo holds releases and nothing else. Leaving # issues open invites bug reports against a branch build in a repo nobody # watches, where they are simply lost. + # + # Why --add-readme in a repo with no source: publishing a release creates a tag, + # and a tag needs a commit. Empty repo = "Repository is empty" 25 minutes in. gh repo create "$ADHOC_REPO" \ --public \ --description "Adhoc macOS dev builds of Orca, cut from unlanded branches. Not a source repo." \ + --add-readme \ --disable-issues \ --disable-wiki || fail "Could not create $ADHOC_REPO." fi +# Also checked outside the create branch: a repo made before --add-readme is here. +if ! gh api "repos/$ADHOC_REPO/commits" --jq 'length' >/dev/null 2>&1; then + fail "$ADHOC_REPO has no commits — releases cannot be tagged. Add any file to it first." +fi + echo echo "Granting $APP_SLUG access to $ADHOC_REPO..." diff --git a/docs/assets/wechat-qr-group6.jpg b/docs/assets/wechat-qr-group6.jpg deleted file mode 100644 index 6032ba2f8a3..00000000000 Binary files a/docs/assets/wechat-qr-group6.jpg and /dev/null differ diff --git a/docs/assets/wechat-qr-group7.jpg b/docs/assets/wechat-qr-group7.jpg new file mode 100644 index 00000000000..02bed43637d Binary files /dev/null and b/docs/assets/wechat-qr-group7.jpg differ diff --git a/docs/assets/wechat-qr.jpg b/docs/assets/wechat-qr.jpg deleted file mode 100644 index 7b02a4d72c9..00000000000 Binary files a/docs/assets/wechat-qr.jpg and /dev/null differ diff --git a/docs/readme/README.fr.md b/docs/readme/README.fr.md index ddbf633b321..f11b25acca7 100644 --- a/docs/readme/README.fr.md +++ b/docs/readme/README.fr.md @@ -243,10 +243,9 @@ Associez-la à l'app de bureau pour surveiller et piloter vos agents depuis votr - **Discord :** Rejoignez la communauté sur **[Discord](https://discord.gg/fzjDKHxv8Q)**. - **Twitter / X :** Suivez **[@orca_build](https://x.com/orca_build)** pour les news et annonces. -- **WeChat :** Si le groupe 5 est complet, vous pouvez rejoindre le groupe 6. +- **WeChat :** Scannez pour rejoindre le groupe WeChat 7 de la communauté Orca. - QR code WeChat groupe 5 de la communauté Orca - QR code WeChat groupe 6 de la communauté Orca + QR code WeChat groupe 7 de la communauté Orca - **Feedback & idées :** On ship vite. Il manque quelque chose ? [Demandez une feature](https://github.com/stablyai/orca/issues). - **Confidentialité :** Voir la [doc confidentialité & télémétrie](https://www.onorca.dev/docs/telemetry) pour ce qu'Orca collecte en anonyme et comment désactiver la télémétrie. diff --git a/docs/readme/README.zh-CN.md b/docs/readme/README.zh-CN.md index 0a68d205665..818b689ef2e 100644 --- a/docs/readme/README.zh-CN.md +++ b/docs/readme/README.zh-CN.md @@ -235,10 +235,9 @@ yay -S stably-orca-bin - **Discord:** 加入 **[Discord](https://discord.gg/fzjDKHxv8Q)** 社区。 - **Twitter / X:** 关注 **[@orca_build](https://x.com/orca_build)** 获取更新和公告。 -- **微信:** 如果第 5 群已满,可加入第 6 群。 +- **微信:** 扫码加入 Orca 社区微信第 7 群。 - Orca 社区微信第 5 群二维码 - Orca 社区微信第 6 群二维码 + Orca 社区微信第 7 群二维码 - **反馈与想法:** 我们发布很快。缺少什么功能?[提交功能请求](https://github.com/stablyai/orca/issues)。 - **隐私:** 查看[隐私与遥测文档](https://www.onorca.dev/docs/telemetry),了解 Orca 收集哪些匿名使用数据以及如何退出。 diff --git a/mobile/.gitignore b/mobile/.gitignore index 449fa3f2439..0428cbb65a9 100644 --- a/mobile/.gitignore +++ b/mobile/.gitignore @@ -1,5 +1,6 @@ node_modules/ src/terminal/terminal-webview-engine.generated.ts +src/components/pr-sidebar/mermaid-webview-engine.generated.ts .expo/ dist/ /android/ diff --git a/mobile/app/h/[hostId]/accounts.tsx b/mobile/app/h/[hostId]/accounts.tsx index 1a07a0d6ecc..b107f34da97 100644 --- a/mobile/app/h/[hostId]/accounts.tsx +++ b/mobile/app/h/[hostId]/accounts.tsx @@ -14,7 +14,7 @@ import { ChevronLeft, Check, RefreshCw, User } from 'lucide-react-native' import { loadHosts } from '../../../src/transport/host-store' import { useHostClient } from '../../../src/transport/client-context' import { colors, spacing } from '../../../src/theme/mobile-theme' -import { styles } from './accounts-screen-styles' +import { styles } from '../../../src/accounts/mobile-accounts-screen-styles' import { useNow } from '../../../src/hooks/use-now' import { ClaudeIcon, OpenAIIcon } from '../../../src/components/AgentIcons' import { diff --git a/mobile/app/h/[hostId]/index.tsx b/mobile/app/h/[hostId]/index.tsx index c7052a39777..24da552eafe 100644 --- a/mobile/app/h/[hostId]/index.tsx +++ b/mobile/app/h/[hostId]/index.tsx @@ -1,14 +1,5 @@ import { useState, useEffect, useCallback, useMemo, useRef } from 'react' -import { - View, - Text, - StyleSheet, - SectionList, - Pressable, - ActivityIndicator, - Alert, - RefreshControl -} from 'react-native' +import { View, Text, StyleSheet, SectionList, Pressable, Alert, RefreshControl } from 'react-native' import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' import { useFocusEffect, useLocalSearchParams, usePathname, useRouter } from 'expo-router' import { @@ -95,6 +86,7 @@ import { useWorkspaceSections } from '../../../src/worktree/use-workspace-sectio import { getMobileWorkspaceLineageGroupKey } from '../../../src/worktree/mobile-workspace-lineage' import { areWorktreeListsEqual } from '../../../src/worktree/worktree-list-snapshot' import { WorktreeCatalogSnapshotClient } from '../../../src/worktree/worktree-catalog-snapshot-client' +import { HostWorkspaceListStates } from '../../../src/worktree/host-workspace-list-states' import { repoColor } from '../../../src/worktree/repo-color' import { WORKSPACE_GROUP_OPTIONS as GROUP_OPTIONS, @@ -154,6 +146,9 @@ export function HostScreen({ const forceReconnectHost = useForceReconnect() const [worktrees, setWorktrees] = useState(initialCache ?? []) const [worktreesLoaded, setWorktreesLoaded] = useState(initialCache != null) + // Why (STA-3123): error code of the last failed worktree.ps, so a broken catalog + // path renders as a failure instead of an empty host. Cleared on the next success. + const [catalogError, setCatalogError] = useState(null) // Why: track the locally-opened worktree so the active-row highlight moves instantly instead of waiting for the next poll. const [optimisticActiveWorktreeId, setOptimisticActiveWorktreeId] = useState(null) // One tick drives every visible agent row's relative timestamp. @@ -326,6 +321,7 @@ export function HostScreen({ repoMetadataFetchedAtRef.current = 0 // Why: useState initializer runs only on first mount, so re-seed the cache when Expo Router reuses this screen for a new hostId. const freshCache = hostId ? (getCachedWorktrees(hostId) as Worktree[] | null) : null + setCatalogError(null) if (freshCache) { setWorktrees(freshCache) setLastKnownWorktrees(freshCache) @@ -427,17 +423,27 @@ export function HostScreen({ const requestHostId = hostId try { - const pendingCatalog = await worktreeCatalogRef.current.fetch(requestClient, requestHostId) + const fetched = await worktreeCatalogRef.current.fetch(requestClient, requestHostId) if (clientRef.current !== requestClient || hostId !== requestHostId) { return } if (!options.allowDuringModal && newWorktreeModalVisibleRef.current) { return } + // Why (STA-3123): a failed catalog request must not pass for "0 worktrees"; + // surface it so a broken remote host is diagnosable instead of looking empty. + if (fetched.kind === 'request_failed') { + setCatalogError(fetched.code) + return + } + if (fetched.pending.admission.kind === 'invalid') { + setCatalogError('invalid_response') + } // Why: unchanged responses still yield the confirmed rows, so every poll reasserts // host truth over optimistic local edits regardless of payload size. - const confirmed = worktreeCatalogRef.current.admit(pendingCatalog) + const confirmed = worktreeCatalogRef.current.admit(fetched.pending) if (confirmed) { + setCatalogError(null) // Why: reuse the existing array on identical snapshots to keep SectionList/sort rebuilds off the tap path. setWorktrees((current) => areWorktreeListsEqual(current, confirmed) ? current : confirmed @@ -486,6 +492,9 @@ export function HostScreen({ } } catch { // Will retry on reconnect + if (clientRef.current === requestClient && hostId === requestHostId) { + setCatalogError('network_error') + } } finally { fetchWorktreesInFlightRef.current = false } @@ -1099,27 +1108,15 @@ export function HostScreen({ )} - {/* Loading state */} - {((connState === 'connecting' || connState === 'reconnecting') && - displayWorktrees.length === 0) || - (connState === 'connected' && !worktreesLoaded && displayWorktrees.length === 0) ? ( - - - - ) : null} - - {/* Empty state */} - {connState === 'connected' && worktreesLoaded && sections.length === 0 && ( - - - {search - ? 'No matching worktrees' - : activeFilterCount > 0 - ? 'No worktrees match filters' - : 'No worktrees'} - - - )} + {sections.length > 0 && ( >(new Set()) const initializedHandlesRef = useRef>(new Set()) const terminalDiagnosticsRef = useRef(new MobileTerminalDiagnostics()) + // Why: bounds the scrollback→resubscribe fit loop per handle (STA-3337). + const viewportResubscribeBudgetRef = useRef(new TerminalViewportResubscribeBudget()) // Why: don't subscribe until the WebView fires web-ready — iOS may defer JS in hidden WebViews and init() messages would queue unrendered. const webReadyHandlesRef = useRef>(new Set()) const activeHandleRef = useRef(null) @@ -1376,6 +1384,7 @@ export default function SessionScreen() { subscribingHandlesRef.current.clear() initializedHandlesRef.current.clear() terminalDiagnosticsRef.current.clearTerminalCache() + viewportResubscribeBudgetRef.current.clear() webReadyHandlesRef.current.clear() subscribeSeqRef.current.clear() layoutSeqRef.current.clear() @@ -1505,10 +1514,11 @@ export default function SessionScreen() { return } updateTerminalCwdFromStreamEvent(handle, data, terminalCwdRef.current) - const cols = (data.cols as number) || 80 - const rows = (data.rows as number) || 24 - const scrollbackCols = cols - const scrollbackRows = rows + const { hostCols, hostRows } = readTerminalViewportDims(data) + // Why: absent host dims must not be coerced into a comparable size — 80x24 + // never equals a phone viewport and armed a zero-delay resubscribe loop (STA-3337). + const cols = hostCols ?? viewportRef.current?.cols ?? 80 + const rows = hostRows ?? viewportRef.current?.rows ?? 24 const initialData = typeof data.serialized === 'string' && data.serialized.length > 0 ? data.serialized @@ -1527,46 +1537,36 @@ export default function SessionScreen() { ref.init(cols, rows, initialData, false, oscLinks) initializedHandlesRef.current.add(handle) if (data.displayMode) { + const displayMode = data.displayMode as MobileDisplayMode + // Why: same-mode frames must keep the Map identity, or every stream pass re-renders the whole route. setTerminalModes((prev) => - new Map(prev).set(handle, data.displayMode as MobileDisplayMode) + prev.get(handle) === displayMode ? prev : new Map(prev).set(handle, displayMode) ) } // Why: cold-start refit — init()'s fit can run against a transient scrollWidth, so re-fire against a settled DOM. scheduleDelayedAction(() => getTerminalRef(handle)?.resetZoom(), 200) - // Why: first subscribe has no viewport (xterm not loaded yet), so measure after init and resubscribe so the server can phone-fit. - const needsResubscribe = - !viewportMeasuredRef.current || - (viewportRef.current != null && - (scrollbackCols !== viewportRef.current.cols || - scrollbackRows !== viewportRef.current.rows)) - if (needsResubscribe) { - void (async () => { - // Why: wait for init()'s rAF chain before measuring, else the measure races ahead and returns null (log dump 2026-05-06). - await getTerminalRef(handle)?.awaitReady() - if (subscribeSeqRef.current.get(handle) !== seq) { - return - } - const dims = await getTerminalRef(handle)?.measureFitDimensions( - terminalFrameHeightRef.current || undefined - ) - // Why: re-check seq — the awaits may have let a newer subscribe cycle arm; tearing it down would resubscribe a stale generation. - if (subscribeSeqRef.current.get(handle) !== seq) { - return - } - if (!getTerminalRef(handle)) { - return - } - // Why: scrollback came back at cols=80 (server's null-viewport fallback), so this subscriber record has no viewport — resubscribe so the server stores it. - if (dims) { - diagnostics.streamResubscribing(handle, seq, dims) - viewportRef.current = dims - viewportMeasuredRef.current = true - unsubscribeTerminal(handle) - initializedHandlesRef.current.delete(handle) - subscribeToTerminal(handle) - } - })() - } + // Why: first subscribe has no viewport (xterm not loaded yet), so measure after init + // and resubscribe so the server can phone-fit — bounded per handle so a + // non-converging host degrades visibly instead of hot-looping (STA-3337). + runTerminalViewportFitPass({ + handle, + seq, + hostCols, + hostRows, + budget: viewportResubscribeBudgetRef.current, + diagnostics, + viewportRef, + viewportMeasuredRef, + subscribeSeqRef, + initializedHandlesRef, + terminalUnsubsRef, + terminalFrameHeightRef, + getTerminalRef, + unsubscribeTerminal, + subscribeToTerminal, + scheduleDelayedAction, + showToast + }) } else if (data.type === 'metadata') { updateTerminalCwdFromStreamEvent(handle, data, terminalCwdRef.current) } else if (data.type === 'data') { @@ -1591,8 +1591,12 @@ export default function SessionScreen() { } else if (data.type === 'resized') { updateTerminalCwdFromStreamEvent(handle, data, terminalCwdRef.current) // Server resize: reinit xterm on a full-buffer snapshot (width reflow rewraps scrollback), else just resize geometry. - const cols = (data.cols as number) || 80 - const rows = (data.rows as number) || 24 + const viewport = viewportMeasuredRef.current ? viewportRef.current : null + const [cols, rows] = viewportResubscribeBudgetRef.current.observeResize( + handle, + data, + viewport + ) const serialized = typeof data.serialized === 'string' ? data.serialized : null diagnostics.streamResized(handle, seq, eventSeq, data, getTerminalRef(handle) != null) const oscLinks = isTerminalOscLinkRanges(data.oscLinks) ? data.oscLinks : undefined @@ -1602,8 +1606,10 @@ export default function SessionScreen() { getTerminalRef(handle)?.resize(cols, rows) } if (data.displayMode) { + const displayMode = data.displayMode as MobileDisplayMode + // Why: same-mode frames must keep the Map identity, or every stream pass re-renders the whole route. setTerminalModes((prev) => - new Map(prev).set(handle, data.displayMode as MobileDisplayMode) + prev.get(handle) === displayMode ? prev : new Map(prev).set(handle, displayMode) ) } scheduleDelayedAction(() => getTerminalRef(handle)?.resetZoom(), 200) @@ -1619,7 +1625,7 @@ export default function SessionScreen() { } subscribingHandlesRef.current.delete(handle) }, - [client, getTerminalRef, markNativeChatInputLeaseReady, scheduleDelayedAction] + [client, getTerminalRef, markNativeChatInputLeaseReady, scheduleDelayedAction, showToast] ) const nativeChatStream = useMobileNativeChatTerminalStream({ @@ -1720,12 +1726,16 @@ export default function SessionScreen() { unsubscribeTerminal(handle) terminalRefs.current.delete(handle) initializedHandlesRef.current.delete(handle) + viewportResubscribeBudgetRef.current.forget(handle) clearTerminalLiveInputDefault(handle) } setTerminalKeyboardMetrics((prev) => pruneTerminalKeyboardMetrics(prev, shouldPrune)) // Why: a chat-covered handle the host reports again refills its rearm budget, // so an exhausted rearm can't lock the composer until leave-chat. nativeChatStream.notifyListedHandles(liveHandles) + // Why: same absence-gated refill for the viewport-fit budget — a handle that + // left the list and returned may converge now, so it earns fresh attempts. + viewportResubscribeBudgetRef.current.notifyListedHandles(liveHandles) lastKnownTerminalCountRef.current = result.terminals.length // Why: dedupe duplicate handles (rename/split race) to avoid a React duplicate-key throw; keep first for tab-strip order. const seen = new Set() @@ -3590,6 +3600,7 @@ export default function SessionScreen() { if ( current && current.cursorY === metrics.cursorY && + current.contentBottomRow === metrics.contentBottomRow && current.rows === metrics.rows && current.altScreen === metrics.altScreen ) { @@ -4271,24 +4282,11 @@ export default function SessionScreen() { ? Math.max(0, keyboardHeight - insets.bottom) : keyboardHeight : 0 - const activeTerminalKeyboardLift = (() => { - if (keyboardLift <= 0 || !activeHandle) { - return 0 - } - const metrics = terminalKeyboardMetrics.get(activeHandle) - if (!metrics || metrics.rows <= 0 || terminalFrameHeightRef.current <= 0) { - return keyboardLift - } - if (metrics.altScreen) { - return keyboardLift - } - const rowHeight = terminalFrameHeightRef.current / metrics.rows - const cursorBottom = (metrics.cursorY + 1) * rowHeight - const dockTop = terminalFrameHeightRef.current - keyboardLift - const margin = rowHeight - // Why: only move the terminal when the cursor would sit under the raised input dock; short top output stays put. - return Math.min(keyboardLift, Math.max(0, cursorBottom + margin - dockTop)) - })() + const activeTerminalKeyboardLift = computeActiveTerminalKeyboardLift({ + keyboardLift, + metrics: activeHandle ? terminalKeyboardMetrics.get(activeHandle) : undefined, + terminalFrameHeight: terminalFrameHeightRef.current + }) const toastAnimatedStyle = { opacity: toastOpacityRef.current, transform: [{ translateY: -keyboardLift }] diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx index 0962550f58b..907f50ed974 100644 --- a/mobile/app/index.tsx +++ b/mobile/app/index.tsx @@ -20,6 +20,11 @@ import { navigateToMobileHostEdit } from '../src/transport/host-edit-navigation' import { removeHostAndCloseClient } from '../src/transport/host-removal-lifecycle' import { pickResumeWorktree } from '../src/worktree/resume-worktree' import { WORKTREE_PS_FULL_LIMIT } from '../src/worktree/worktree-catalog-snapshot-client' +import { + markHomeWorktreeCatalogUnavailable, + type HomeWorktreeSummary, + type HostWorktreeInfo +} from '../src/worktree/home-worktree-info' import type { RpcClient } from '../src/transport/rpc-client' import { sendSingleFlightRequest } from '../src/transport/request-single-flight' import { @@ -70,26 +75,6 @@ type StatsSummary = { firstEventAt: number | null } -type WorktreeSummary = { - worktreeId: string - repo: string - branch: string - displayName: string - liveTerminalCount: number - status?: 'working' | 'active' | 'permission' | 'done' | 'inactive' - // The worktree the desktop currently has focused (exactly one is true). - isActive?: boolean - // Last terminal-output time (ms); breaks ties when nothing is focused. - lastOutputAt?: number -} - -type HostWorktreeInfo = { - hostId: string - totalWorktrees: number - activeCount: number - lastActiveWorktree: WorktreeSummary | null -} - type HomeTaskSettings = { visibleTaskProviders?: unknown } @@ -161,21 +146,11 @@ function fetchWorktreeInfo( ) => void, disposed: () => boolean ) { - // Why: only seed a zeroed entry when the host has no prior info; keep cached data on transient failure so counts don't flip to 0 during reconnects. - const markLoadedIfMissing = () => { + const markUnavailable = () => { setInfo((prev) => { - if (prev[hostId]) { - return prev - } - return { - ...prev, - [hostId]: { - hostId, - totalWorktrees: 0, - activeCount: 0, - lastActiveWorktree: null - } - } + const current = prev[hostId] + const next = markHomeWorktreeCatalogUnavailable(current, hostId) + return next === current ? prev : { ...prev, [hostId]: next } }) } @@ -185,7 +160,7 @@ function fetchWorktreeInfo( return } if (response.ok) { - const result = response.result as { worktrees: WorktreeSummary[] } + const result = response.result as { worktrees: HomeWorktreeSummary[] } const worktrees = result.worktrees ?? [] setCachedWorktrees(hostId, worktrees) const activeStatuses = new Set(['working', 'active', 'permission']) @@ -202,12 +177,12 @@ function fetchWorktreeInfo( } })) } else { - markLoadedIfMissing() + markUnavailable() } }) .catch(() => { if (!disposed()) { - markLoadedIfMissing() + markUnavailable() } }) } @@ -554,7 +529,7 @@ export default function HomeScreen() { const resumeWorktree = useMemo(() => { // Why: only surface Resume for connected hosts; a stale worktree taps into a route that can't load. if (lastVisited && hostStates[lastVisited.hostId] === 'connected') { - const cached = getCachedWorktrees(lastVisited.hostId) as WorktreeSummary[] | null + const cached = getCachedWorktrees(lastVisited.hostId) as HomeWorktreeSummary[] | null const match = cached?.find((w) => w.worktreeId === lastVisited.worktreeId) if (match) { return { hostId: lastVisited.hostId, worktree: match } @@ -789,8 +764,11 @@ export default function HomeScreen() { verdict={verdict} path={hostPaths[item.id] ?? 'lan'} worktreeCounts={ - info ? { total: info.totalWorktrees, active: info.activeCount } : undefined + info && !info.catalogUnavailable + ? { total: info.totalWorktrees, active: info.activeCount } + : undefined } + worktreeCountsUnavailable={info?.catalogUnavailable === true} onPress={() => router.push(`/h/${item.id}`)} onLongPress={() => { triggerMediumImpact() diff --git a/mobile/package.json b/mobile/package.json index 1041b422a34..44feca5f4c5 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -7,7 +7,7 @@ "start": "node scripts/start-expo.mjs", "android": "expo run:android", "ios": "expo run:ios", - "postinstall": "node scripts/build-terminal-webview-engine.mjs", + "postinstall": "node scripts/build-terminal-webview-engine.mjs && node scripts/build-mermaid-webview-engine.mjs", "test": "vitest run", "typecheck": "tsc --noEmit", "lint": "oxlint", @@ -48,6 +48,7 @@ "expo-status-bar": "^55.0.6", "lowlight": "^3.3.0", "lucide-react-native": "^1.14.0", + "mermaid": "11.16.0", "react": "^19.2.6", "react-dom": "19.2.6", "react-native": "^0.83.9", diff --git a/mobile/pnpm-lock.yaml b/mobile/pnpm-lock.yaml index 9788413f925..5530acb4da1 100644 --- a/mobile/pnpm-lock.yaml +++ b/mobile/pnpm-lock.yaml @@ -101,6 +101,9 @@ importers: lucide-react-native: specifier: ^1.14.0 version: 1.14.0(react-native-svg@15.15.4(react-native@0.83.9(@babel/core@7.29.7)(@react-native/metro-config@0.85.2(@babel/core@7.29.7))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6))(react-native@0.83.9(@babel/core@7.29.7)(@react-native/metro-config@0.85.2(@babel/core@7.29.7))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6) + mermaid: + specifier: 11.16.0 + version: 11.16.0 react: specifier: ^19.2.6 version: 19.2.6 @@ -195,6 +198,9 @@ importers: packages: + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@babel/cli@7.28.6': resolution: {integrity: sha512-6EUNcuBbNkj08Oj4gAZ+BUU8yLCgKzgVX4gaTh09Ya2C8ICM4P+G30g4m3akRxSYAp3A/gnWchrNst7px4/nUQ==} engines: {node: '>=6.9.0'} @@ -1178,6 +1184,12 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + '@egjs/hammerjs@2.0.17': resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==} engines: {node: '>=0.8.0'} @@ -1768,6 +1780,12 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.4': + resolution: {integrity: sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==} + '@isaacs/ttlcache@1.4.1': resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} engines: {node: '>=12'} @@ -1881,6 +1899,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@mermaid-js/parser@1.2.0': + resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==} + '@napi-rs/wasm-runtime@1.1.6': resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: @@ -2680,6 +2701,99 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.1': + resolution: {integrity: sha512-65Emv9fQiQQqphLlRkuQ5ypPsOmWPhtBGCMv61JDPEPMvsx+gzhGf74yw1a78xFKPj6zw4AgQICJoQv0vK9M2w==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.4': + resolution: {integrity: sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -2689,6 +2803,9 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -2741,6 +2858,9 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -2818,6 +2938,9 @@ packages: '@ungap/structured-clone@1.3.1': resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + '@vitest/expect@4.1.9': resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} @@ -3332,6 +3455,10 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -3353,6 +3480,12 @@ packages: core-js-compat@3.49.0: resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3392,6 +3525,162 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.34.0: + resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -3408,6 +3697,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dayjs@1.11.21: + resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3470,6 +3762,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -3526,6 +3821,9 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + dompurify@3.4.12: + resolution: {integrity: sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -3611,6 +3909,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.50.0: + resolution: {integrity: sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==} + esbuild@0.25.4: resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} engines: {node: '>=18'} @@ -4304,6 +4605,9 @@ packages: resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -4436,6 +4740,9 @@ packages: engines: {node: '>=8'} hasBin: true + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -4458,6 +4765,13 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -4855,9 +5169,16 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -4866,6 +5187,12 @@ packages: resolution: {integrity: sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==} hasBin: true + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -4958,6 +5285,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -5018,6 +5348,11 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + marky@1.3.0: resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} @@ -5041,6 +5376,9 @@ packages: merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + mermaid@11.16.0: + resolution: {integrity: sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA==} + metro-babel-transformer@0.83.7: resolution: {integrity: sha512-sBqBkt6kNut/88bv+Ucvm4yqdPetbvAEsHzi3MAgJEifOSYYzX5Z5Kgw3TFOrwf/mHJTOBG2ONlaMHoyfP15TA==} engines: {node: '>=20.19.4'} @@ -5418,6 +5756,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-manager-detector@1.8.0: + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -5437,6 +5778,9 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -5490,6 +5834,12 @@ packages: resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} engines: {node: '>=4.0.0'} + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -5798,11 +6148,20 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + rolldown@1.1.3: resolution: {integrity: sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-array-concat@1.1.4: resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} @@ -6103,6 +6462,9 @@ packages: styleq@0.1.3: resolution: {integrity: sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==} + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -6214,6 +6576,10 @@ packages: peerDependencies: typescript: '>=4.0.0' + ts-dedent@2.3.0: + resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==} + engines: {node: '>=6.10'} + ts-jest@29.0.5: resolution: {integrity: sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6694,6 +7060,11 @@ packages: snapshots: + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.1.2 + '@babel/cli@7.28.6(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -7935,6 +8306,10 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@braintree/sanitize-url@7.1.2': {} + + '@chevrotain/types@11.1.2': {} + '@egjs/hammerjs@2.0.17': dependencies: '@types/hammerjs': 2.0.46 @@ -8637,6 +9012,14 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.4': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + import-meta-resolve: 4.2.0 + '@isaacs/ttlcache@1.4.1': {} '@istanbuljs/load-nyc-config@1.1.0': @@ -8847,6 +9230,10 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@mermaid-js/parser@1.2.0': + dependencies: + '@chevrotain/types': 11.1.2 + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: '@emnapi/core': 1.11.1 @@ -9603,12 +9990,131 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.1': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.4': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.1 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + '@types/deep-eql@4.0.2': {} '@types/emscripten@1.41.5': {} '@types/estree@1.0.9': {} + '@types/geojson@7946.0.16': {} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 26.1.1 @@ -9677,6 +10183,9 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/trusted-types@2.0.7': + optional: true + '@types/unist@3.0.3': {} '@types/whatwg-mimetype@3.0.2': {} @@ -9784,6 +10293,11 @@ snapshots: '@ungap/structured-clone@1.3.1': {} + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + '@vitest/expect@4.1.9': dependencies: '@standard-schema/spec': 1.1.0 @@ -10407,6 +10921,8 @@ snapshots: commander@7.2.0: {} + commander@8.3.0: {} + compressible@2.0.18: dependencies: mime-db: 1.54.0 @@ -10440,6 +10956,14 @@ snapshots: dependencies: browserslist: 4.28.2 + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + create-jest@29.7.0(@types/node@26.1.1): dependencies: '@jest/types': 29.6.3 @@ -10496,6 +11020,190 @@ snapshots: csstype@3.2.3: {} + cytoscape-cose-bilkent@4.1.0(cytoscape@3.34.0): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.34.0 + + cytoscape-fcose@2.2.0(cytoscape@3.34.0): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.34.0 + + cytoscape@3.34.0: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.18.1 + data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -10520,6 +11228,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dayjs@1.11.21: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -10560,6 +11270,10 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + delayed-stream@1.0.0: {} depd@2.0.0: {} @@ -10602,6 +11316,10 @@ snapshots: dependencies: domelementtype: 2.3.0 + dompurify@3.4.12: + optionalDependencies: + '@types/trusted-types': 2.0.7 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -10748,6 +11466,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.50.0: {} + esbuild@0.25.4: optionalDependencies: '@esbuild/aix-ppc64': 0.25.4 @@ -11653,6 +12373,8 @@ snapshots: - bufferutil - utf-8-validate + hachure-fill@0.5.2: {} + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -11781,6 +12503,8 @@ snapshots: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -11802,6 +12526,10 @@ snapshots: hasown: 2.0.3 side-channel: 1.1.0 + internmap@1.0.1: {} + + internmap@2.0.3: {} + invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -12446,14 +13174,24 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + katex@0.16.47: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + khroma@2.1.0: {} + kleur@3.0.3: {} lan-network@0.2.1: {} + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + leven@3.1.0: {} levn@0.4.1: @@ -12527,6 +13265,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.18.1: {} + lodash.debounce@4.0.8: {} lodash.memoize@4.1.2: {} @@ -12584,6 +13324,8 @@ snapshots: dependencies: tmpl: 1.0.5 + marked@16.4.2: {} + marky@1.3.0: {} math-intrinsics@1.1.0: {} @@ -12600,6 +13342,30 @@ snapshots: merge-stream@2.0.0: {} + mermaid@11.16.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.4 + '@mermaid-js/parser': 1.2.0 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.34.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.34.0) + cytoscape-fcose: 2.2.0(cytoscape@3.34.0) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.21 + dompurify: 3.4.12 + es-toolkit: 1.50.0 + katex: 0.16.47 + khroma: 2.1.0 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.4.0 + ts-dedent: 2.3.0 + uuid: 11.1.1 + metro-babel-transformer@0.83.7: dependencies: '@babel/core': 7.29.7 @@ -13214,6 +13980,8 @@ snapshots: p-try@2.2.0: {} + package-manager-detector@1.8.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -13235,6 +14003,8 @@ snapshots: parseurl@1.3.3: {} + path-data-parser@0.1.0: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -13272,6 +14042,13 @@ snapshots: pngjs@3.4.0: {} + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + possible-typed-array-names@1.1.0: {} postcss-value-parser@4.2.0: {} @@ -13646,6 +14423,8 @@ snapshots: dependencies: glob: 7.2.3 + robust-predicates@3.0.3: {} + rolldown@1.1.3: dependencies: '@oxc-project/types': 0.137.0 @@ -13667,6 +14446,15 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.1.3 '@rolldown/binding-win32-x64-msvc': 1.1.3 + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rw@1.3.3: {} + safe-array-concat@1.1.4: dependencies: call-bind: 1.0.9 @@ -13983,6 +14771,8 @@ snapshots: styleq@0.1.3: {} + stylis@4.4.0: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -14084,6 +14874,8 @@ snapshots: picomatch: 4.0.4 typescript: 5.9.3 + ts-dedent@2.3.0: {} + ts-jest@29.0.5(@babel/core@7.29.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(esbuild@0.25.4)(jest@29.7.0(@types/node@26.1.1))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 diff --git a/mobile/scripts/build-mermaid-webview-engine.mjs b/mobile/scripts/build-mermaid-webview-engine.mjs new file mode 100644 index 00000000000..bf53ae2f4b8 --- /dev/null +++ b/mobile/scripts/build-mermaid-webview-engine.mjs @@ -0,0 +1,42 @@ +import { readFile, writeFile } from 'node:fs/promises' +import path from 'node:path' +import { createRequire } from 'node:module' + +const require = createRequire(import.meta.url) +const scriptDir = import.meta.dirname +const mobileRoot = path.resolve(scriptDir, '..') +const outputPath = path.join( + mobileRoot, + 'src', + 'components', + 'pr-sidebar', + 'mermaid-webview-engine.generated.ts' +) + +// Why: unlike the terminal engine (esbuilt from source for old-WebView shims), +// mermaid's prebuilt UMD bundle is embedded verbatim — it is the exact artifact +// the diagram WebView previously fetched from a CDN, now pinned and +// integrity-checked through the lockfile and available offline. +async function main() { + const packageJsonPath = require.resolve('mermaid/package.json') + const [packageJson, bundleJs] = await Promise.all([ + readFile(packageJsonPath, 'utf8').then(JSON.parse), + readFile(path.join(path.dirname(packageJsonPath), 'dist', 'mermaid.min.js'), 'utf8') + ]) + + // A literal inside the bundle would close the inline script tag it + // is embedded in; \/ is identical to / in JS strings, regexes, and comments. + const inlineSafeJs = bundleJs.replace(/<\/script/gi, '<\\/script') + + const source = [ + '// Generated by scripts/build-mermaid-webview-engine.mjs.', + `// Package: mermaid@${packageJson.version} (dist/mermaid.min.js, embedded verbatim).`, + '// Do not edit by hand; regenerate via pnpm postinstall.', + `export const MERMAID_ENGINE_JS = ${JSON.stringify(inlineSafeJs)}`, + '' + ].join('\n') + + await writeFile(outputPath, source) +} + +await main() diff --git a/mobile/scripts/repro-mobile-foreground-stall.sh b/mobile/scripts/repro-mobile-foreground-stall.sh new file mode 100755 index 00000000000..5fc0e05cc63 --- /dev/null +++ b/mobile/scripts/repro-mobile-foreground-stall.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Repro driver for "mobile sits on Connecting… after leaving and re-entering the +# app" (Slack P0, iOS 0.0.39(2)). +# +# Two things the iOS Simulator will not do on its own, and how this works around +# them: +# +# * It never suspends an app the way a device does, so the JS runtime keeps +# servicing timers while backgrounded and the bug hides. SIGSTOP on the app +# process reproduces real suspension: timers frozen, socket left dangling. +# * SIGSTOP on the desktop runtime makes its port blackhole — the kernel still +# completes the TCP handshake from the listen backlog, but no WebSocket +# upgrade ever comes back, which is what a wedged Tailscale tunnel or a relay +# with nothing behind it looks like to the phone. +# +# Everything is driven with xcrun simctl rather than `orca emulator`, because the +# emulator CLI routes through the desktop runtime that this script freezes. +# +# Setup: +# node scripts/start-emulator.mjs --device "iPhone 17 Pro" --wait-for-ready \ +# > /tmp/orca-emulator-boot.log 2>&1 & +# +# Usage: repro-mobile-foreground-stall.sh [log] +set -euo pipefail + +UDID="${1:?simulator udid}" +PORT="${2:?port of the paired host, from the [net] logs}" +LOG="${3:-/tmp/orca-emulator-boot.log}" +BUNDLE_ID=com.stably.orca.mobile +# Long enough for the tiered backoff to reach its 30s/60s tail. +ESCALATE_SECONDS=200 + +APP=$(pgrep -f "CoreSimulator.*Orca.app/Orca" | head -1) +DESK=$(pgrep -f "serve-mobile-pairing" | head -1) +: "${APP:?mobile app is not running in the simulator}" +: "${DESK:?headless desktop runtime is not running}" + +strip() { sed 's/\x1b\[[0-9;]*m//g'; } +since() { sed -n "$(( $1 + 1 )),\$p" "$LOG" | strip; } +step() { echo "$(date +%T) $*"; } + +echo "### app=$APP desktop=$DESK port=$PORT" + +step "[1] desktop goes unreachable" +kill -STOP "$DESK" +sleep "$ESCALATE_SECONDS" +step "[2] backoff at $(since 0 | grep "$PORT" | grep -o '"attempt": [0-9]*' | tail -1)" + +MARK=$(wc -l < "$LOG") +while true; do + since "$MARK" | grep "$PORT" | grep -q '"to": "connecting"' && break + sleep 0.3 +done +step "[3] connect window open — user switches away" +xcrun simctl launch "$UDID" com.apple.mobilesafari >/dev/null 2>&1 +sleep 1 +kill -STOP "$APP" +step "[4] phone suspended mid-dial" +sleep 5 + +MARK=$(wc -l < "$LOG") +kill -CONT "$APP" +sleep 0.3 +xcrun simctl launch "$UDID" "$BUNDLE_ID" >/dev/null 2>&1 +T0=$(date +%s) +step "[5] user returns to Orca <-- t0, desktop still down" + +# The desktop is deliberately still unreachable here: the only question is +# whether returning to the app abandons the dead dial or waits it out. +sleep 6 +echo "--- first 6s after t0 ---" +since "$MARK" | grep -E "$PORT|foreground" \ + | grep -E 'state |foreground|scheduleReconnect|openConnection' | head -8 + +kill -CONT "$DESK" +step "[6] desktop healthy again" +for _ in $(seq 1 45); do + if since "$MARK" | grep "$PORT" | grep -q '"to": "connected"'; then + step ">>> connected $(( $(date +%s) - T0 ))s after t0" + exit 0 + fi + sleep 2 +done +step ">>> STILL STUCK 90s after t0" +exit 1 diff --git a/mobile/app/h/[hostId]/accounts-screen-styles.ts b/mobile/src/accounts/mobile-accounts-screen-styles.ts similarity index 97% rename from mobile/app/h/[hostId]/accounts-screen-styles.ts rename to mobile/src/accounts/mobile-accounts-screen-styles.ts index 4a987b7a442..65074f340ae 100644 --- a/mobile/app/h/[hostId]/accounts-screen-styles.ts +++ b/mobile/src/accounts/mobile-accounts-screen-styles.ts @@ -1,5 +1,5 @@ import { StyleSheet } from 'react-native' -import { colors, spacing, typography, radii } from '../../../src/theme/mobile-theme' +import { colors, spacing, typography, radii } from '../theme/mobile-theme' export const styles = StyleSheet.create({ container: { diff --git a/mobile/src/components/MobileAgentIcon.tsx b/mobile/src/components/MobileAgentIcon.tsx index 6c47fce7a5b..c5557ab3934 100644 --- a/mobile/src/components/MobileAgentIcon.tsx +++ b/mobile/src/components/MobileAgentIcon.tsx @@ -32,7 +32,7 @@ function OmpIcon({ size = 16 }: { size?: number }) { - + diff --git a/mobile/src/components/MobileHostCard.tsx b/mobile/src/components/MobileHostCard.tsx index b79d0c01f5c..4e466922f4a 100644 --- a/mobile/src/components/MobileHostCard.tsx +++ b/mobile/src/components/MobileHostCard.tsx @@ -14,6 +14,9 @@ export function MobileHostCard(props: { verdict: ConnectionVerdict path: MobileConnectionPath worktreeCounts?: { total: number; active: number } + // Why (STA-3123): the host is connected but its worktree catalog request failed, + // so the card must say "unavailable" instead of asserting a count of zero. + worktreeCountsUnavailable?: boolean onPress: () => void onLongPress: () => void }) { @@ -21,7 +24,9 @@ export function MobileHostCard(props: { const isError = ['warning', 'unreachable', 'auth-failed'].includes(props.verdict.kind) const worktreeSummary = props.worktreeCounts ? `${props.worktreeCounts.total} worktree${props.worktreeCounts.total === 1 ? '' : 's'}${props.worktreeCounts.active > 0 ? ` · ${props.worktreeCounts.active} active` : ''}` - : null + : props.worktreeCountsUnavailable + ? 'Worktree list unavailable' + : null return ( [styles.card, pressed && styles.cardPressed]} diff --git a/mobile/src/components/MobileMarkdown.test.ts b/mobile/src/components/MobileMarkdown.test.ts index 20a92663a49..5a59e749b20 100644 --- a/mobile/src/components/MobileMarkdown.test.ts +++ b/mobile/src/components/MobileMarkdown.test.ts @@ -1,8 +1,40 @@ import { describe, expect, it } from 'vitest' +import { isMobileMermaidLanguage } from './mobile-mermaid-language' import { normalizeMobileMarkdownPreviewHtml } from './mobile-markdown-preview-html' import { parseMobileMarkdown } from './mobile-markdown-parser' +describe('isMobileMermaidLanguage', () => { + it('matches mermaid case-insensitively after trim', () => { + expect(isMobileMermaidLanguage('mermaid')).toBe(true) + expect(isMobileMermaidLanguage('Mermaid')).toBe(true) + expect(isMobileMermaidLanguage(' MERMAID ')).toBe(true) + }) + + it('rejects non-mermaid languages and missing language', () => { + expect(isMobileMermaidLanguage(undefined)).toBe(false) + expect(isMobileMermaidLanguage('')).toBe(false) + expect(isMobileMermaidLanguage('ts')).toBe(false) + expect(isMobileMermaidLanguage('mermaidx')).toBe(false) + }) +}) + describe('parseMobileMarkdown', () => { + it('parses mermaid fences as code blocks with language mermaid', () => { + expect(parseMobileMarkdown('```mermaid\ngraph TD; A-->B\n```')).toEqual([ + { type: 'code', text: 'graph TD; A-->B', language: 'mermaid', closed: true } + ]) + expect(isMobileMermaidLanguage('mermaid')).toBe(true) + }) + + it('marks an unterminated fence as not closed while it streams', () => { + expect(parseMobileMarkdown('```mermaid\ngraph TD; A-->B')).toEqual([ + { type: 'code', text: 'graph TD; A-->B', language: 'mermaid', closed: false } + ]) + expect(parseMobileMarkdown('```mermaid\ngraph TD; A-->B\n```')[0]).toMatchObject({ + closed: true + }) + }) + it('parses GFM tables into table blocks', () => { expect(parseMobileMarkdown('| Name | State |\n| --- | --- |\n| Orca | Open |')).toEqual([ { diff --git a/mobile/src/components/MobileMarkdown.tsx b/mobile/src/components/MobileMarkdown.tsx index 8e968f604ac..dc58f5e5d6a 100644 --- a/mobile/src/components/MobileMarkdown.tsx +++ b/mobile/src/components/MobileMarkdown.tsx @@ -7,7 +7,9 @@ import { isFilePathCodeSpan, normalizeFilePath } from './markdown-file-path-detection' +import { isMobileMermaidLanguage } from './mobile-mermaid-language' import { parseMobileMarkdown } from './mobile-markdown-parser' +import { MermaidDiagram } from './pr-sidebar/MermaidDiagram' type Props = { content?: string @@ -23,6 +25,8 @@ type Props = { const MAX_TABLE_ROWS = 40 const MAX_TABLE_COLUMNS = 8 +/** Prose base size — passed to MermaidDiagram fallback mono text. */ +const MERMAID_BASE = 13 function openMarkdownUrl(url: string): void { const trimmed = url.trim() @@ -153,6 +157,7 @@ function MobileMarkdownInner({ content, fallback = '', textScale = 1, onOpenFile if (!text) { return fallback ? {fallback} : null } + const mermaidSourceOccurrences = new Map() return ( @@ -175,6 +180,20 @@ function MobileMarkdownInner({ content, fallback = '', textScale = 1, onOpenFile ) } if (block.type === 'code') { + // Mermaid fences render as diagrams (WebView), not as raw code — same as PR sidebar. + // Unclosed fences are still streaming: mounting the WebView per tick would + // reload its document up to 20x/sec, so they stay raw code until terminated. + if (isMobileMermaidLanguage(block.language) && block.closed) { + const occurrence = mermaidSourceOccurrences.get(block.text) ?? 0 + mermaidSourceOccurrences.set(block.text, occurrence + 1) + return ( + + ) + } return ( {block.language ? {block.language} : null} diff --git a/mobile/src/components/mobile-agent-icon-gradient.test.ts b/mobile/src/components/mobile-agent-icon-gradient.test.ts new file mode 100644 index 00000000000..8e2781edfb2 --- /dev/null +++ b/mobile/src/components/mobile-agent-icon-gradient.test.ts @@ -0,0 +1,65 @@ +import { createElement } from 'react' +import { act, create, type ReactTestRenderer } from 'react-test-renderer' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { MobileAgentIcon } from './MobileAgentIcon' + +vi.mock('react-native', () => ({ + Image: 'Image', + StyleSheet: { create: (styles: unknown) => styles }, + Text: 'Text', + View: 'View' +})) + +vi.mock('lucide-react-native', () => ({ + Terminal: 'Terminal' +})) + +vi.mock('react-native-svg', () => ({ + default: 'Svg', + Defs: 'Defs', + G: 'G', + LinearGradient: 'LinearGradient', + Path: 'Path', + Stop: 'Stop' +})) + +vi.mock('./mobile-agent-icon-assets', () => ({ + MOBILE_AGENT_ICON_ASSETS: {} +})) + +vi.mock('./AgentIcons', () => ({ + ClaudeIcon: 'ClaudeIcon', + OpenAIIcon: 'OpenAIIcon' +})) + +describe('MobileAgentIcon OMP gradient', () => { + let renderer: ReactTestRenderer | null = null + + beforeEach(() => { + globalThis.IS_REACT_ACT_ENVIRONMENT = true + }) + + afterEach(() => { + act(() => renderer?.unmount()) + renderer = null + vi.restoreAllMocks() + }) + + it('uses valid SVG gradient stop offsets', async () => { + const consoleError = vi.spyOn(console, 'error').mockImplementation((...args) => { + if (typeof args[0] !== 'string' || !args[0].includes('react-test-renderer is deprecated')) { + throw new Error(String(args[0])) + } + }) + await act(async () => { + renderer = create(createElement(MobileAgentIcon, { agentId: 'omp' })) + }) + consoleError.mockRestore() + + expect(renderer.root.findAllByType('Stop').map((stop) => stop.props.offset)).toEqual([ + '0', + '0.5', + '1' + ]) + }) +}) diff --git a/mobile/src/components/mobile-markdown-mermaid-routing.test.ts b/mobile/src/components/mobile-markdown-mermaid-routing.test.ts new file mode 100644 index 00000000000..c89dfa00853 --- /dev/null +++ b/mobile/src/components/mobile-markdown-mermaid-routing.test.ts @@ -0,0 +1,80 @@ +import { createElement } from 'react' +import { act, create, type ReactTestRenderer } from 'react-test-renderer' +import { afterEach, describe, expect, it, vi } from 'vitest' +import { MobileMarkdown } from './MobileMarkdown' + +vi.mock('react-native', () => ({ + Linking: { openURL: vi.fn() }, + Pressable: 'Pressable', + ScrollView: 'ScrollView', + StyleSheet: { create: (styles: T) => styles, hairlineWidth: 1 }, + Text: 'Text', + View: 'View' +})) +vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' })) + +let renderer: ReactTestRenderer | undefined + +afterEach(() => { + renderer?.unmount() + renderer = undefined + vi.restoreAllMocks() +}) + +function render(content: string): ReactTestRenderer { + act(() => { + renderer = create(createElement(MobileMarkdown, { content })) + }) + return renderer! +} + +function mermaidCount(tree: ReactTestRenderer): number { + return tree.root.findAllByType('MermaidDiagram' as never).length +} + +function firstMermaid(tree: ReactTestRenderer) { + return tree.root.findByType('MermaidDiagram' as never) +} + +describe('MobileMarkdown mermaid routing', () => { + it('routes a closed mermaid fence to MermaidDiagram', () => { + const tree = render('```mermaid\ngraph TD; A-->B\n```') + expect(mermaidCount(tree)).toBe(1) + }) + + it('keeps a streaming (unterminated) mermaid fence as raw code', () => { + const tree = render('```mermaid\ngraph TD; A-->B') + expect(mermaidCount(tree)).toBe(0) + }) + + it('keeps identical sibling diagrams uniquely keyed', () => { + const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) + const diagram = '```mermaid\ngraph TD; A-->B\n```' + const tree = render(`${diagram}\n\n${diagram}`) + const warnings = consoleError.mock.calls.flat().join(' ') + expect(mermaidCount(tree)).toBe(2) + expect(warnings).not.toContain('same key') + }) + + it('preserves a completed diagram while later prose streams', () => { + const diagram = '```mermaid\ngraph TD; A-->B\n```' + const tree = render(diagram) + const initial = firstMermaid(tree) + act(() => tree.update(createElement(MobileMarkdown, { content: `${diagram}\n\nNext` }))) + expect(firstMermaid(tree)).toBe(initial) + }) + + it('remounts a diagram when its source changes', () => { + const tree = render('```mermaid\ngraph TD; A-->B\n```') + const initial = firstMermaid(tree) + act(() => + tree.update(createElement(MobileMarkdown, { content: '```mermaid\ngraph TD; A-->C\n```' })) + ) + expect(firstMermaid(tree)).not.toBe(initial) + }) + + it('does not route other code fences to MermaidDiagram', () => { + const tree = render('```ts\nconst a = 1\n```') + expect(mermaidCount(tree)).toBe(0) + }) +}) diff --git a/mobile/src/components/mobile-markdown-parser.ts b/mobile/src/components/mobile-markdown-parser.ts index b6375f389c5..fa16b3b9310 100644 --- a/mobile/src/components/mobile-markdown-parser.ts +++ b/mobile/src/components/mobile-markdown-parser.ts @@ -2,7 +2,7 @@ export type MobileMarkdownBlock = | { type: 'paragraph'; text: string } | { type: 'heading'; level: number; text: string } | { type: 'quote'; text: string } - | { type: 'code'; text: string; language?: string } + | { type: 'code'; text: string; language?: string; closed: boolean } | { type: 'list'; ordered: boolean; items: Array<{ text: string; checked?: boolean }> } | { type: 'image'; alt: string; url: string } | { type: 'table'; headers: string[]; rows: string[][] } @@ -42,10 +42,12 @@ export function parseMobileMarkdown(content: string): MobileMarkdownBlock[] { code.push(lines[index] ?? '') index += 1 } - if (index < lines.length) { + // closed=false means the fence is still streaming in (no terminator yet). + const closed = index < lines.length + if (closed) { index += 1 } - blocks.push({ type: 'code', text: code.join('\n'), language: fence[1] }) + blocks.push({ type: 'code', text: code.join('\n'), language: fence[1], closed }) continue } diff --git a/mobile/src/components/mobile-mermaid-language.ts b/mobile/src/components/mobile-mermaid-language.ts new file mode 100644 index 00000000000..8e7811ba167 --- /dev/null +++ b/mobile/src/components/mobile-mermaid-language.ts @@ -0,0 +1,4 @@ +/** True when a fenced code block language should render as a Mermaid diagram. */ +export function isMobileMermaidLanguage(language?: string): boolean { + return language?.trim().toLowerCase() === 'mermaid' +} diff --git a/mobile/src/components/pr-sidebar/MermaidDiagram.tsx b/mobile/src/components/pr-sidebar/MermaidDiagram.tsx index b4c4811c0d3..0df2aa210db 100644 --- a/mobile/src/components/pr-sidebar/MermaidDiagram.tsx +++ b/mobile/src/components/pr-sidebar/MermaidDiagram.tsx @@ -1,7 +1,8 @@ -import { useMemo, useState } from 'react' +import { memo, useMemo, useState } from 'react' import { ScrollView, StyleSheet, Text, View } from 'react-native' import { WebView } from 'react-native-webview' import { colors, radii, spacing, typography } from '../../theme/mobile-theme' +import { MERMAID_ENGINE_JS } from './mermaid-webview-engine.generated' type Props = { source: string @@ -9,11 +10,15 @@ type Props = { } // Renders a ```mermaid fence as a diagram via a sandboxed WebView (mermaid has no -// native RN renderer). Mermaid is loaded from a CDN inside the WebView HTML, the -// SVG is themed dark to match the sidebar, and the WebView posts back its rendered -// height so we can size to content. On any failure (no network, parse error, -// render error) we fall back to the raw source in a labeled mono code box. -export function MermaidDiagram({ source, base }: Props) { +// native RN renderer). Mermaid ships inside the app as a generated bundle embedded +// in the WebView HTML — no network — the SVG is themed dark to match the sidebar, +// and the WebView posts back its rendered height so we can size to content. On any +// failure (parse error, render error) we fall back to the raw source in a labeled +// mono code box. +// memo: both props are primitives; without it every mounted diagram re-renders +// per frame during pinch-to-zoom (textScale updates), marshalling the full HTML +// string across the Fabric boundary each time. +export const MermaidDiagram = memo(function MermaidDiagram({ source, base }: Props) { const [height, setHeight] = useState(0) const [failed, setFailed] = useState(false) const html = useMemo(() => buildHtml(source), [source]) @@ -58,7 +63,7 @@ export function MermaidDiagram({ source, base }: Props) { /> ) -} +}) function MermaidFallback({ source, base }: Props) { return ( @@ -73,21 +78,33 @@ function MermaidFallback({ source, base }: Props) { ) } -// Self-contained HTML: load mermaid from CDN, render the graph, post the body +// JSON.stringify escapes quotes and control chars but leaves `<`, `>`, `&`, and +// the U+2028/U+2029 line separators raw — so a source containing `` +// would close this inline +
@@ -114,7 +131,7 @@ function buildHtml(source: string): string { } }); mermaid.run({ querySelector: '.mermaid' }) - .then(reportHeight) + .then(function () { reportHeight(); }) .catch(function () { post('error'); }); } catch (e) { post('error'); diff --git a/mobile/src/components/pr-sidebar/mermaid-diagram-html.test.ts b/mobile/src/components/pr-sidebar/mermaid-diagram-html.test.ts new file mode 100644 index 00000000000..d66d82d9f53 --- /dev/null +++ b/mobile/src/components/pr-sidebar/mermaid-diagram-html.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it, vi } from 'vitest' +import { buildHtml } from './MermaidDiagram' +import { MERMAID_ENGINE_JS } from './mermaid-webview-engine.generated' + +vi.mock('react-native', () => ({ + ScrollView: 'ScrollView', + StyleSheet: { create: (styles: T) => styles, hairlineWidth: 1 }, + Text: 'Text', + View: 'View' +})) +vi.mock('react-native-webview', () => ({ WebView: 'WebView' })) + +// The diagram source is untrusted (agent output, PR/chat content). It is embedded +// inside an inline payload break out of the inline script', () => { + const payload = 'graph TD; A-->B' + const countClosers = (html: string) => (html.match(/<\/script>/gi) ?? []).length + // The payload's two must add zero raw closers over a benign render — + // they were neutralized to \u003c instead of closing our inline script. + const benign = countClosers(buildHtml('graph TD; A-->B')) + expect(countClosers(buildHtml(payload))).toBe(benign) + expect(buildHtml(payload)).toContain('\\u003c/script') + }) + + it('escapes the U+2028/U+2029 line separators that would break the JS literal', () => { + const payload = `a${String.fromCharCode(0x2028)}b${String.fromCharCode(0x2029)}c` + const html = buildHtml(payload) + expect(html).toContain('\\u2028') + expect(html).toContain('\\u2029') + expect(html.includes(String.fromCharCode(0x2028))).toBe(false) + expect(html.includes(String.fromCharCode(0x2029))).toBe(false) + }) + + it('still round-trips ordinary source to the exact original string', () => { + const payload = 'graph LR\n A["node & "] --> B' + const html = buildHtml(payload) + const match = html.match(/\.textContent = (".*?");\n {4}mermaid\.initialize/s) + expect(match).not.toBeNull() + expect(JSON.parse(match![1]!)).toBe(payload) + }) + + // Same gate as the terminal document: mermaid is embedded from the lockfile-pinned + // package, so the document itself must load nothing external (offline-safe, no CDN + // supply-chain exposure). The engine's internal URL literals (xmlns, docs links) + // are inert data, so the gate checks the document with the engine stripped out. + it('embeds the mermaid engine and loads no external resource', () => { + const html = buildHtml('graph TD; A-->B') + expect(html).toContain(MERMAID_ENGINE_JS) + expect(html.replace(MERMAID_ENGINE_JS, '')).not.toMatch(/\bhttps?:\/\//) + }) + + it('blocks external resources requested by diagram syntax', () => { + const html = buildHtml('flowchart LR\nA@{ img: "https://example.com/pixel.png" }') + const policy = html.match(/Content-Security-Policy" content="([^"]+)"/)?.[1] + expect(policy).toContain("default-src 'none'") + expect(policy).toContain('img-src data: blob:') + expect(policy).not.toMatch(/https?:/) + }) +}) diff --git a/mobile/src/expo-route-module-boundary.test.ts b/mobile/src/expo-route-module-boundary.test.ts new file mode 100644 index 00000000000..3870f32c216 --- /dev/null +++ b/mobile/src/expo-route-module-boundary.test.ts @@ -0,0 +1,121 @@ +import { readFileSync, readdirSync } from 'node:fs' +import { fileURLToPath } from 'node:url' +import { basename, dirname, extname, join, relative } from 'node:path' +import ts from 'typescript' +import { describe, expect, it } from 'vitest' + +const appDirectory = fileURLToPath(new URL('../app', import.meta.url)) +const routeSourceExtensions = new Set(['.js', '.jsx', '.ts', '.tsx']) + +function sourceFiles(directory: string): string[] { + return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => { + const path = join(directory, entry.name) + return entry.isDirectory() ? sourceFiles(path) : [path] + }) +} + +function isNonScreenExpoModule(path: string): boolean { + const fileName = basename(path) + if (/\+api\.[jt]sx?$/.test(fileName)) { + return true + } + return ( + dirname(relative(appDirectory, path)) === '.' && + /^\+(?:html|middleware|native-intent)\.[jt]sx?$/.test(fileName) + ) +} + +function isPlatformSpecificApiRoute(path: string): boolean { + return /\+api\.(?:android|ios|native|web)\.[jt]sx?$/.test(basename(path)) +} + +function hasDefaultExport(path: string, source: string): boolean { + const extension = extname(path) + const sourceFile = ts.createSourceFile( + path, + source, + ts.ScriptTarget.Latest, + true, + extension === '.jsx' + ? ts.ScriptKind.JSX + : extension === '.js' + ? ts.ScriptKind.JS + : extension === '.tsx' + ? ts.ScriptKind.TSX + : ts.ScriptKind.TS + ) + + return sourceFile.statements.some((statement) => { + if (ts.isExportAssignment(statement)) { + return !statement.isExportEquals + } + if (ts.isExportDeclaration(statement) && !statement.isTypeOnly && statement.exportClause) { + if (ts.isNamespaceExport(statement.exportClause)) { + return statement.exportClause.name.text === 'default' + } + return statement.exportClause.elements.some( + (element) => !element.isTypeOnly && element.name.text === 'default' + ) + } + const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined + return ( + !ts.isInterfaceDeclaration(statement) && + !ts.isTypeAliasDeclaration(statement) && + modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DeclareKeyword) !== true && + modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) === true && + modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) + ) + }) +} + +function isInvalidRouteModule(path: string, source: string): boolean { + return ( + isPlatformSpecificApiRoute(path) || + (!isNonScreenExpoModule(path) && !hasDefaultExport(path, source)) + ) +} + +describe('Expo route module boundary', () => { + it('allows Expo modules that are not screen routes', () => { + expect(isNonScreenExpoModule(join(appDirectory, 'health+api.ts'))).toBe(true) + expect(isNonScreenExpoModule(join(appDirectory, 'health+api.ios.ts'))).toBe(false) + expect(isNonScreenExpoModule(join(appDirectory, '+html.tsx'))).toBe(true) + expect(isNonScreenExpoModule(join(appDirectory, '+middleware.ts'))).toBe(true) + expect(isNonScreenExpoModule(join(appDirectory, '+native-intent.ts'))).toBe(true) + expect(isNonScreenExpoModule(join(appDirectory, 'nested', '+middleware.ts'))).toBe(false) + }) + + it('recognizes syntax-level default exports', () => { + expect(hasDefaultExport('route.tsx', 'export default function Route() {}')).toBe(true) + expect( + hasDefaultExport('route.jsx', 'export default function Route() { return }') + ).toBe(true) + expect(hasDefaultExport('route.ts', "export { default } from './route-screen'")).toBe(true) + expect(hasDefaultExport('route.ts', "export { Route as default } from './route-screen'")).toBe( + true + ) + expect(hasDefaultExport('support.ts', '// export default')).toBe(false) + expect(hasDefaultExport('support.ts', "const marker = 'export default'")).toBe(false) + expect(hasDefaultExport('support.ts', 'export default interface Support {}')).toBe(false) + expect( + hasDefaultExport('support.ts', "export type { Support as default } from './types'") + ).toBe(false) + }) + + it('rejects platform-specific API routes even with a default export', () => { + expect(isPlatformSpecificApiRoute(join(appDirectory, 'health+api.ts'))).toBe(false) + for (const platform of ['android', 'ios', 'native', 'web']) { + const path = join(appDirectory, `health+api.${platform}.ts`) + expect(isInvalidRouteModule(path, 'export default function Route() {}')).toBe(true) + } + }) + + it('keeps support modules outside the app route directory', () => { + const invalidRoutes = sourceFiles(appDirectory) + .filter((path) => routeSourceExtensions.has(extname(path))) + .filter((path) => isInvalidRouteModule(path, readFileSync(path, 'utf8'))) + .map((path) => relative(appDirectory, path)) + + expect(invalidRoutes).toEqual([]) + }) +}) diff --git a/mobile/src/session/MobileBrowserTabActionSheet.tsx b/mobile/src/session/MobileBrowserTabActionSheet.tsx index 655aa717ab9..5f605d1395c 100644 --- a/mobile/src/session/MobileBrowserTabActionSheet.tsx +++ b/mobile/src/session/MobileBrowserTabActionSheet.tsx @@ -1,5 +1,5 @@ import { ChevronLeft, ChevronRight, RefreshCw } from 'lucide-react-native' -import type { MobileSessionTab } from '../../app/h/[hostId]/session/mobile-session-route-types' +import type { MobileSessionTab } from './mobile-session-route-types' import { ActionSheetModal, type ActionSheetAction } from '../components/ActionSheetModal' import { getMobileSessionTabTitle } from './mobile-terminal-tab-agent' diff --git a/mobile/src/session/MobileSessionHeaderIconButton.tsx b/mobile/src/session/MobileSessionHeaderIconButton.tsx index 68e1a1173a4..b1037bb958f 100644 --- a/mobile/src/session/MobileSessionHeaderIconButton.tsx +++ b/mobile/src/session/MobileSessionHeaderIconButton.tsx @@ -1,7 +1,7 @@ import type { ComponentType } from 'react' import { Pressable } from 'react-native' import { colors } from '../theme/mobile-theme' -import { styles } from '../../app/h/[hostId]/session/mobile-session-styles' +import { styles } from './mobile-session-styles' type HeaderIconProps = { size?: number diff --git a/mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx b/mobile/src/session/QuickCommandsTabButton.tsx similarity index 92% rename from mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx rename to mobile/src/session/QuickCommandsTabButton.tsx index 5faebb7691d..364a35daf75 100644 --- a/mobile/app/h/[hostId]/session/QuickCommandsTabButton.tsx +++ b/mobile/src/session/QuickCommandsTabButton.tsx @@ -1,7 +1,7 @@ import { Pressable, View } from 'react-native' import { SquareChevronRight } from 'lucide-react-native' -import { colors } from '../../../../src/theme/mobile-theme' +import { colors } from '../theme/mobile-theme' import { styles } from './mobile-session-styles' type Props = { diff --git a/mobile/src/session/ai-vault-resume-launch.ts b/mobile/src/session/ai-vault-resume-launch.ts index bb8a1e07ad9..aa8c1bf98a6 100644 --- a/mobile/src/session/ai-vault-resume-launch.ts +++ b/mobile/src/session/ai-vault-resume-launch.ts @@ -3,7 +3,7 @@ import { buildAiVaultResumeCommand, buildAiVaultResumeShellCommand, realHomeCodexResumeEnvDeletion -} from '../../../src/shared/ai-vault-types' +} from '../../../src/shared/ai-vault-resume-command' import { RESUME_RPC_TIMEOUT_MS } from './ai-vault-resume-preparation' import { isResumableTuiAgent } from '../../../src/shared/agent-session-resume' import type { SleepingAgentLaunchConfig } from '../../../src/shared/agent-session-resume' diff --git a/mobile/src/session/mobile-bulk-close-sheet-actions.ts b/mobile/src/session/mobile-bulk-close-sheet-actions.ts index 8565575fe08..68dee5c2af3 100644 --- a/mobile/src/session/mobile-bulk-close-sheet-actions.ts +++ b/mobile/src/session/mobile-bulk-close-sheet-actions.ts @@ -1,7 +1,4 @@ -import type { - MarkdownDocState, - MobileSessionTab -} from '../../app/h/[hostId]/session/mobile-session-route-types' +import type { MarkdownDocState, MobileSessionTab } from './mobile-session-route-types' import type { ActionSheetAction } from '../components/ActionSheetModal' import { BULK_TAB_CLOSE_ACTIONS, diff --git a/mobile/src/session/mobile-native-chat-open-file.test.ts b/mobile/src/session/mobile-native-chat-open-file.test.ts index 2f8ceb936a7..e2bf001ffdf 100644 --- a/mobile/src/session/mobile-native-chat-open-file.test.ts +++ b/mobile/src/session/mobile-native-chat-open-file.test.ts @@ -36,6 +36,7 @@ describe('resolveMobileNativeChatWorktreePath', () => { .mockResolvedValueOnce({ ok: true, result: { + worktree: 'sibling-worktree', exists: true, isDirectory: false, openTarget: { kind: 'worktree-file', relativePath: 'src/app.ts' } @@ -51,7 +52,7 @@ describe('resolveMobileNativeChatWorktreePath', () => { }) expect(sendRequest).toHaveBeenLastCalledWith('files.open', { - worktree: 'id:worktree', + worktree: 'id:sibling-worktree', relativePath: 'src/app.ts' }) }) diff --git a/mobile/src/session/mobile-native-chat-open-file.ts b/mobile/src/session/mobile-native-chat-open-file.ts index 44d6d23c066..6460c82849c 100644 --- a/mobile/src/session/mobile-native-chat-open-file.ts +++ b/mobile/src/session/mobile-native-chat-open-file.ts @@ -1,12 +1,17 @@ import type { RuntimeTerminalPathResolution } from '../../../src/shared/runtime-types' import type { RpcClient } from '../transport/rpc-client' -export async function resolveMobileNativeChatWorktreePath(args: { +type MobileNativeChatWorktreeTarget = { + worktreeId: string + relativePath: string +} + +async function resolveMobileNativeChatWorktreeTarget(args: { client: RpcClient worktreeId: string pathText: string terminal: string | null -}): Promise { +}): Promise { try { const response = await args.client.sendRequest('files.resolveTerminalPath', { worktree: `id:${args.worktreeId}`, @@ -20,28 +25,39 @@ export async function resolveMobileNativeChatWorktreePath(args: { if (!resolved.exists || resolved.isDirectory) { return null } - return resolved.openTarget?.kind === 'worktree-file' - ? resolved.openTarget.relativePath - : (resolved.relativePath ?? null) + const relativePath = + resolved.openTarget?.kind === 'worktree-file' + ? resolved.openTarget.relativePath + : (resolved.relativePath ?? null) + return relativePath + ? { worktreeId: resolved.worktree?.trim() || args.worktreeId, relativePath } + : null } catch { - // Callers fire-and-forget file opens; a disconnect/timeout must not become - // an unhandled rejection. return null } } +export async function resolveMobileNativeChatWorktreePath(args: { + client: RpcClient + worktreeId: string + pathText: string + terminal: string | null +}): Promise { + return (await resolveMobileNativeChatWorktreeTarget(args))?.relativePath ?? null +} + export async function openMobileNativeChatFile(args: { client: RpcClient worktreeId: string pathText: string terminal: string | null }): Promise { - const relativePath = await resolveMobileNativeChatWorktreePath(args) - if (relativePath) { + const target = await resolveMobileNativeChatWorktreeTarget(args) + if (target) { try { await args.client.sendRequest('files.open', { - worktree: `id:${args.worktreeId}`, - relativePath + worktree: `id:${target.worktreeId}`, + relativePath: target.relativePath }) } catch { // Best-effort open; failures surface as a no-op rather than an diff --git a/mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts b/mobile/src/session/mobile-session-command-input-styles.ts similarity index 98% rename from mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts rename to mobile/src/session/mobile-session-command-input-styles.ts index 1bb852c4218..b19c13a502e 100644 --- a/mobile/app/h/[hostId]/session/mobile-session-command-input-styles.ts +++ b/mobile/src/session/mobile-session-command-input-styles.ts @@ -1,6 +1,6 @@ import { StyleSheet } from 'react-native' -import { colors, spacing, radii, typography } from '../../../../src/theme/mobile-theme' +import { colors, spacing, radii, typography } from '../theme/mobile-theme' export const mobileSessionCommandInputStyles = StyleSheet.create({ createWarningBanner: { diff --git a/mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts b/mobile/src/session/mobile-session-frame-styles.ts similarity index 97% rename from mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts rename to mobile/src/session/mobile-session-frame-styles.ts index 738632ba495..a02c14be014 100644 --- a/mobile/app/h/[hostId]/session/mobile-session-frame-styles.ts +++ b/mobile/src/session/mobile-session-frame-styles.ts @@ -1,6 +1,6 @@ import { StyleSheet } from 'react-native' -import { colors, spacing, radii, typography } from '../../../../src/theme/mobile-theme' +import { colors, spacing, radii, typography } from '../theme/mobile-theme' export const mobileSessionFrameStyles = StyleSheet.create({ container: { diff --git a/mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts b/mobile/src/session/mobile-session-reader-styles.ts similarity index 97% rename from mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts rename to mobile/src/session/mobile-session-reader-styles.ts index aba5340ec7a..eedd47d328b 100644 --- a/mobile/app/h/[hostId]/session/mobile-session-reader-styles.ts +++ b/mobile/src/session/mobile-session-reader-styles.ts @@ -1,6 +1,6 @@ import { Platform, StyleSheet } from 'react-native' -import { colors, spacing, radii, typography } from '../../../../src/theme/mobile-theme' +import { colors, spacing, radii, typography } from '../theme/mobile-theme' export const mobileSessionReaderStyles = StyleSheet.create({ markdownTextInput: { diff --git a/mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts b/mobile/src/session/mobile-session-review-comment-styles.ts similarity index 98% rename from mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts rename to mobile/src/session/mobile-session-review-comment-styles.ts index b9d19578b83..8d8b2d11ccd 100644 --- a/mobile/app/h/[hostId]/session/mobile-session-review-comment-styles.ts +++ b/mobile/src/session/mobile-session-review-comment-styles.ts @@ -1,6 +1,6 @@ import { StyleSheet } from 'react-native' -import { colors, spacing, radii, typography } from '../../../../src/theme/mobile-theme' +import { colors, spacing, radii, typography } from '../theme/mobile-theme' export const mobileSessionReviewCommentStyles = StyleSheet.create({ diffCommentAddButton: { diff --git a/mobile/app/h/[hostId]/session/mobile-session-route-types.ts b/mobile/src/session/mobile-session-route-types.ts similarity index 85% rename from mobile/app/h/[hostId]/session/mobile-session-route-types.ts rename to mobile/src/session/mobile-session-route-types.ts index c5a94e9d38f..7e74a5d04c0 100644 --- a/mobile/app/h/[hostId]/session/mobile-session-route-types.ts +++ b/mobile/src/session/mobile-session-route-types.ts @@ -1,13 +1,10 @@ -import type { MobileBrowserTab } from '../../../../src/browser/MobileBrowserPane' -import type { MobileTerminalTheme } from '../../../../src/terminal/terminal-webview-contract' -import type { MobileDiffLine } from '../../../../src/session/mobile-diff-lines' -import type { - MobileHighlightedDiffLine, - MobileSyntaxSegment -} from '../../../../src/session/mobile-file-syntax' -import type { TerminalRecord } from '../../../../src/session/mobile-terminal-records' -import type { DiffComment, TuiAgent } from '../../../../../src/shared/types' -import type { AgentStatusEntry } from '../../../../../src/shared/agent-status-types' +import type { DiffComment, TuiAgent } from '../../../src/shared/types' +import type { AgentStatusEntry } from '../../../src/shared/agent-status-types' +import type { MobileBrowserTab } from '../browser/MobileBrowserPane' +import type { MobileTerminalTheme } from '../terminal/terminal-webview-contract' +import type { MobileDiffLine } from './mobile-diff-lines' +import type { MobileHighlightedDiffLine, MobileSyntaxSegment } from './mobile-file-syntax' +import type { TerminalRecord } from './mobile-terminal-records' export type Terminal = TerminalRecord diff --git a/mobile/app/h/[hostId]/session/mobile-session-styles.ts b/mobile/src/session/mobile-session-styles.ts similarity index 100% rename from mobile/app/h/[hostId]/session/mobile-session-styles.ts rename to mobile/src/session/mobile-session-styles.ts diff --git a/mobile/src/session/mobile-terminal-diagnostics.ts b/mobile/src/session/mobile-terminal-diagnostics.ts index 8695928ed03..6ee636fb9f4 100644 --- a/mobile/src/session/mobile-terminal-diagnostics.ts +++ b/mobile/src/session/mobile-terminal-diagnostics.ts @@ -141,12 +141,35 @@ export class MobileTerminalDiagnostics { }) } - streamResubscribing(handle: string, seq: number, dims: { cols: number; rows: number }): void { + streamResubscribing( + handle: string, + seq: number, + dims: { cols: number; rows: number }, + attempt: number, + delayMs: number + ): void { logMobileTerminalDiagnostic('stream-resubscribe-for-viewport', { handle: shortenMobileTerminalDiagnosticId(handle), seq, cols: dims.cols, - rows: dims.rows + rows: dims.rows, + attempt, + delayMs + }) + } + + streamResubscribeHeld(handle: string, seq: number): void { + logMobileTerminalDiagnostic('stream-resubscribe-held-absent-dims', { + handle: shortenMobileTerminalDiagnosticId(handle), + seq + }) + } + + streamResubscribeExhausted(handle: string, seq: number, attempts: number): void { + logMobileTerminalDiagnostic('stream-resubscribe-exhausted', { + handle: shortenMobileTerminalDiagnosticId(handle), + seq, + attempts }) } diff --git a/mobile/src/session/mobile-terminal-file-tap-open.test.ts b/mobile/src/session/mobile-terminal-file-tap-open.test.ts index fec1b5b663c..a958b977260 100644 --- a/mobile/src/session/mobile-terminal-file-tap-open.test.ts +++ b/mobile/src/session/mobile-terminal-file-tap-open.test.ts @@ -135,6 +135,56 @@ describe('openMobileTerminalFileTap', () => { expect(switchSessionTab).toHaveBeenCalledWith(openedTab) }) + it('opens a sibling terminal path through the resolved owning worktree', async () => { + const client = createClient([ + ok({ + worktree: 'wt-2', + relativePath: 'docs/readme.md', + absolutePath: '/repo-b/docs/readme.md', + exists: true, + isDirectory: false, + openTarget: { + kind: 'worktree-file', + provider: 'local', + relativePath: 'docs/readme.md', + absolutePath: '/repo-b/docs/readme.md' + } + }) + ]) + const pushPreviewRoute = vi.fn() + + openMobileTerminalFileTap({ + client, + hostId: 'host-1', + worktreeId: 'wt-1', + pathText: '/repo-b/docs/readme.md', + line: null, + column: null, + pushPreviewRoute, + openBrowser: vi.fn(), + triggerOpenFeedback: vi.fn(), + fetchSessionTabs: vi.fn(), + getSessionTabs: () => [], + getActiveSessionTabId: () => null, + getActivationState: activeTerminalState, + switchSessionTab: vi.fn(), + scheduleDelayedAction: vi.fn() + }) + await Promise.resolve() + await Promise.resolve() + + expect(pushPreviewRoute).toHaveBeenCalledWith({ + pathname: '/h/[hostId]/files/preview/[worktreeId]', + params: expect.objectContaining({ + hostId: 'host-1', + worktreeId: 'wt-2', + source: 'worktree', + relativePath: 'docs/readme.md' + }) + }) + expect(client.sendRequest).not.toHaveBeenCalledWith('files.open', expect.anything()) + }) + it('opens worktree-contained line references through the preview route', async () => { const client = createClient([ ok({ diff --git a/mobile/src/session/mobile-terminal-file-tap-open.ts b/mobile/src/session/mobile-terminal-file-tap-open.ts index 31a5c892d75..8d6e681b0f4 100644 --- a/mobile/src/session/mobile-terminal-file-tap-open.ts +++ b/mobile/src/session/mobile-terminal-file-tap-open.ts @@ -74,13 +74,17 @@ async function openMobileTerminalFileTapAsync { + it('accepts only usable numeric host dimensions', () => { + expect(readTerminalViewportDims({ cols: 40, rows: 50 })).toEqual({ + hostCols: 40, + hostRows: 50 + }) + expect(readTerminalViewportDims({ cols: Number.NaN, rows: 0 })).toEqual({ + hostCols: null, + hostRows: null + }) + }) +}) + +describe('resolveTerminalViewportResubscribe', () => { + it('resubscribes immediately on the first pass when the viewport is unmeasured', () => { + expect( + resolveTerminalViewportResubscribe({ + hostCols: 80, + hostRows: 24, + viewportMeasured: false, + viewport: null, + attempts: 0 + }) + ).toEqual({ kind: 'resubscribe', delayMs: 0 }) + }) + + it('caps even the unmeasured pass once the budget is spent', () => { + expect( + resolveTerminalViewportResubscribe({ + hostCols: 80, + hostRows: 24, + viewportMeasured: false, + viewport: null, + attempts: MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS + }) + ).toEqual({ kind: 'exhausted' }) + }) + + it('holds on absent host dims instead of resubscribing (STA-3337 regression)', () => { + for (const [hostCols, hostRows] of [ + [null, null], + [80, null], + [null, 24] + ] as const) { + expect( + resolveTerminalViewportResubscribe({ + hostCols, + hostRows, + viewportMeasured: true, + viewport: PHONE, + attempts: 0 + }) + ).toEqual({ kind: 'hold' }) + } + }) + + it('keeps holding on absent dims across repeated frames without spending budget', () => { + for (let frame = 0; frame < 50; frame += 1) { + expect( + resolveTerminalViewportResubscribe({ + hostCols: null, + hostRows: null, + viewportMeasured: true, + viewport: PHONE, + attempts: 0 + }).kind + ).toBe('hold') + } + }) + + it('converges when host dims match the measured viewport', () => { + expect( + resolveTerminalViewportResubscribe({ + hostCols: PHONE.cols, + hostRows: PHONE.rows, + viewportMeasured: true, + viewport: PHONE, + attempts: 2 + }) + ).toEqual({ kind: 'converged' }) + }) + + it('backs off across mismatch attempts and then exhausts', () => { + const delays = [0, 1, 2].map((attempts) => { + const decision = resolveTerminalViewportResubscribe({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + attempts + }) + if (decision.kind !== 'resubscribe') { + throw new Error(`expected resubscribe at attempt ${attempts}, got ${decision.kind}`) + } + return decision.delayMs + }) + expect(delays[0]).toBe(0) + expect(delays[1]).toBeGreaterThan(0) + expect(delays[2]).toBeGreaterThan(delays[1]) + expect( + resolveTerminalViewportResubscribe({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + attempts: MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS + }) + ).toEqual({ kind: 'exhausted' }) + }) +}) + +describe('shouldResubscribeAfterViewportMeasure', () => { + it('always resubscribes when the viewport was never measured (server must learn it)', () => { + expect( + shouldResubscribeAfterViewportMeasure({ + hostCols: PHONE.cols, + hostRows: PHONE.rows, + measured: PHONE, + viewportWasMeasured: false + }) + ).toBe(true) + }) + + it('skips the resubscribe when the fresh measure already matches the host', () => { + expect( + shouldResubscribeAfterViewportMeasure({ + hostCols: PHONE.cols, + hostRows: PHONE.rows, + measured: PHONE, + viewportWasMeasured: true + }) + ).toBe(false) + }) + + it('resubscribes when the host still disagrees with the fresh measure', () => { + expect( + shouldResubscribeAfterViewportMeasure({ + hostCols: 80, + hostRows: 24, + measured: PHONE, + viewportWasMeasured: true + }) + ).toBe(true) + }) +}) + +describe('TerminalViewportResubscribeBudget', () => { + const exhaust = (budget: TerminalViewportResubscribeBudget, handle: string) => { + for (let i = 0; i < MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS; i += 1) { + budget.chargeAttempt(handle) + } + } + + it('starts at zero and counts charged attempts per handle', () => { + const budget = new TerminalViewportResubscribeBudget() + expect(budget.attempts('t1')).toBe(0) + budget.chargeAttempt('t1') + budget.chargeAttempt('t1') + expect(budget.attempts('t1')).toBe(2) + expect(budget.attempts('t2')).toBe(0) + }) + + it('resets attempts and re-arms the announcement on convergence', () => { + const budget = new TerminalViewportResubscribeBudget() + exhaust(budget, 't1') + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + budget.markConverged('t1') + expect(budget.attempts('t1')).toBe(0) + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + }) + + it('announces exhaustion exactly once', () => { + const budget = new TerminalViewportResubscribeBudget() + exhaust(budget, 't1') + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + expect(budget.shouldAnnounceExhaustion('t1')).toBe(false) + }) + + it('does not refill an exhausted handle that stayed listed', () => { + const budget = new TerminalViewportResubscribeBudget() + exhaust(budget, 't1') + for (let refresh = 0; refresh < 5; refresh += 1) { + budget.notifyListedHandles(new Set(['t1'])) + } + expect(budget.attempts('t1')).toBe(MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS) + }) + + it('refills only after the exhausted handle went absent and came back', () => { + const budget = new TerminalViewportResubscribeBudget() + exhaust(budget, 't1') + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + budget.notifyListedHandles(new Set()) + // Still exhausted while absent — the refill lands on the return. + expect(budget.attempts('t1')).toBe(MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS) + budget.notifyListedHandles(new Set(['t1'])) + expect(budget.attempts('t1')).toBe(0) + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + }) + + it('leaves below-cap handles untouched by list refreshes', () => { + const budget = new TerminalViewportResubscribeBudget() + budget.chargeAttempt('t1') + budget.notifyListedHandles(new Set()) + budget.notifyListedHandles(new Set(['t1'])) + expect(budget.attempts('t1')).toBe(1) + }) + + it('forget clears one handle, clear clears everything', () => { + const budget = new TerminalViewportResubscribeBudget() + exhaust(budget, 't1') + exhaust(budget, 't2') + budget.forget('t1') + expect(budget.attempts('t1')).toBe(0) + expect(budget.attempts('t2')).toBe(MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS) + budget.clear() + expect(budget.attempts('t2')).toBe(0) + }) +}) + +describe('runTerminalViewportFitPass', () => { + const HANDLE = 't1' + + function makeHarness(overrides: { + hostCols?: number | null + hostRows?: number | null + viewportMeasured?: boolean + viewport?: { cols: number; rows: number } | null + measured?: { cols: number; rows: number } | null + budget?: TerminalViewportResubscribeBudget + }) { + const budget = overrides.budget ?? new TerminalViewportResubscribeBudget() + const diagnostics = { + streamResubscribing: vi.fn(), + streamResubscribeHeld: vi.fn(), + streamResubscribeExhausted: vi.fn() + } + const terminalUnsubsRef = { current: new Map void>([[HANDLE, () => {}]]) } + const scheduled: { fn: () => void; ms: number }[] = [] + const webView = { + awaitReady: () => Promise.resolve(), + measureFitDimensions: () => Promise.resolve(overrides.measured ?? PHONE) + } + const unsubscribeTerminal = vi.fn((handle: string) => { + terminalUnsubsRef.current.delete(handle) + }) + // Mimic the real subscribe path: arming registers an unsubscribe handle. + const subscribeToTerminal = vi.fn((handle: string) => { + terminalUnsubsRef.current.set(handle, () => {}) + }) + const showToast = vi.fn() + const args: TerminalViewportFitPassArgs = { + handle: HANDLE, + seq: 1, + hostCols: overrides.hostCols ?? null, + hostRows: overrides.hostRows ?? null, + budget, + diagnostics, + viewportRef: { current: overrides.viewport ?? null }, + viewportMeasuredRef: { current: overrides.viewportMeasured ?? false }, + subscribeSeqRef: { current: new Map([[HANDLE, 1]]) }, + initializedHandlesRef: { current: new Set([HANDLE]) }, + terminalUnsubsRef, + terminalFrameHeightRef: { current: 0 }, + getTerminalRef: () => webView, + unsubscribeTerminal, + subscribeToTerminal, + scheduleDelayedAction: (fn, ms) => scheduled.push({ fn, ms }), + showToast + } + return { + args, + budget, + diagnostics, + scheduled, + subscribeToTerminal, + unsubscribeTerminal, + showToast + } + } + + const settle = () => new Promise((resolve) => setTimeout(resolve, 0)) + + it('holds without any teardown when host dims are absent (STA-3337 regression)', async () => { + const h = makeHarness({ viewportMeasured: true, viewport: PHONE }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.unsubscribeTerminal).not.toHaveBeenCalled() + expect(h.subscribeToTerminal).not.toHaveBeenCalled() + expect(h.diagnostics.streamResubscribeHeld).toHaveBeenCalledTimes(1) + }) + + it('measures and resubscribes immediately on the first pass, charging one attempt', async () => { + const h = makeHarness({ hostCols: 80, hostRows: 24 }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.unsubscribeTerminal).toHaveBeenCalledTimes(1) + expect(h.subscribeToTerminal).toHaveBeenCalledTimes(1) + expect(h.args.viewportRef.current).toEqual(PHONE) + expect(h.args.viewportMeasuredRef.current).toBe(true) + expect(h.budget.attempts(HANDLE)).toBe(1) + }) + + it('treats an equal fresh measure as convergence instead of resubscribing', async () => { + const budget = new TerminalViewportResubscribeBudget() + budget.chargeAttempt(HANDLE) + // Stale cached viewport disagrees with the host, but the fresh measure matches it. + const h = makeHarness({ + hostCols: PHONE.cols, + hostRows: PHONE.rows, + viewportMeasured: true, + viewport: { cols: 30, rows: 20 }, + measured: PHONE, + budget + }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.subscribeToTerminal).not.toHaveBeenCalled() + expect(h.budget.attempts(HANDLE)).toBe(0) + }) + + it('defers later attempts through the backoff scheduler while keeping the stream up', async () => { + const budget = new TerminalViewportResubscribeBudget() + budget.chargeAttempt(HANDLE) + const h = makeHarness({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + budget + }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.scheduled).toHaveLength(1) + expect(h.scheduled[0].ms).toBeGreaterThan(0) + // The stream must still be up until the deferred retry fires. + expect(h.unsubscribeTerminal).not.toHaveBeenCalled() + h.scheduled[0].fn() + expect(h.unsubscribeTerminal).toHaveBeenCalledTimes(1) + expect(h.subscribeToTerminal).toHaveBeenCalledTimes(1) + expect(h.budget.attempts(HANDLE)).toBe(2) + }) + + it('drops a deferred retry whose subscribe generation went stale', async () => { + const budget = new TerminalViewportResubscribeBudget() + budget.chargeAttempt(HANDLE) + const h = makeHarness({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + budget + }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.scheduled).toHaveLength(1) + h.args.subscribeSeqRef.current.set(HANDLE, 2) + h.scheduled[0].fn() + expect(h.unsubscribeTerminal).not.toHaveBeenCalled() + expect(h.budget.attempts(HANDLE)).toBe(1) + }) + + it('drops a deferred retry after the live stream converges', async () => { + const budget = new TerminalViewportResubscribeBudget() + budget.chargeAttempt(HANDLE) + const h = makeHarness({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + budget + }) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.scheduled).toHaveLength(1) + expect(h.budget.observeResize(HANDLE, PHONE, PHONE)).toEqual([PHONE.cols, PHONE.rows]) + h.scheduled[0].fn() + expect(h.unsubscribeTerminal).not.toHaveBeenCalled() + expect(h.subscribeToTerminal).not.toHaveBeenCalled() + expect(h.budget.attempts(HANDLE)).toBe(0) + }) + + it('announces exhaustion once and stops touching the stream', async () => { + const budget = new TerminalViewportResubscribeBudget() + for (let i = 0; i < MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS; i += 1) { + budget.chargeAttempt(HANDLE) + } + const h = makeHarness({ + hostCols: 80, + hostRows: 24, + viewportMeasured: true, + viewport: PHONE, + budget + }) + runTerminalViewportFitPass(h.args) + runTerminalViewportFitPass(h.args) + await settle() + expect(h.unsubscribeTerminal).not.toHaveBeenCalled() + expect(h.subscribeToTerminal).not.toHaveBeenCalled() + expect(h.showToast).toHaveBeenCalledTimes(1) + expect(h.diagnostics.streamResubscribeExhausted).toHaveBeenCalledTimes(2) + }) +}) + +describe('STA-3337 stream shapes', () => { + it('empty scrollback with absent dims settles after a single register pass', () => { + const budget = new TerminalViewportResubscribeBudget() + // Pass 1: no viewport yet — measure and resubscribe so the server learns it. + const first = resolveTerminalViewportResubscribe({ + hostCols: null, + hostRows: null, + viewportMeasured: false, + viewport: null, + attempts: budget.attempts('t1') + }) + expect(first).toEqual({ kind: 'resubscribe', delayMs: 0 }) + budget.chargeAttempt('t1') + // Pass 2+: host still reports no dims — the stream must be left alone. + for (let frame = 0; frame < 10; frame += 1) { + expect( + resolveTerminalViewportResubscribe({ + hostCols: null, + hostRows: null, + viewportMeasured: true, + viewport: PHONE, + attempts: budget.attempts('t1') + }).kind + ).toBe('hold') + } + expect(budget.attempts('t1')).toBe(1) + }) + + it('non-converging numeric dims degrade after the bounded backoff run', () => { + const budget = new TerminalViewportResubscribeBudget() + const kinds: string[] = [] + for (let frame = 0; frame < 6; frame += 1) { + const decision = resolveTerminalViewportResubscribe({ + hostCols: 80, + hostRows: 24, + viewportMeasured: frame > 0, + viewport: frame > 0 ? PHONE : null, + attempts: budget.attempts('t1') + }) + kinds.push(decision.kind) + if (decision.kind === 'resubscribe') { + budget.chargeAttempt('t1') + } + } + expect(kinds).toEqual([ + 'resubscribe', + 'resubscribe', + 'resubscribe', + 'exhausted', + 'exhausted', + 'exhausted' + ]) + expect(budget.shouldAnnounceExhaustion('t1')).toBe(true) + expect(budget.shouldAnnounceExhaustion('t1')).toBe(false) + }) +}) diff --git a/mobile/src/session/mobile-terminal-viewport-resubscribe.ts b/mobile/src/session/mobile-terminal-viewport-resubscribe.ts new file mode 100644 index 00000000000..8ad3c99c13e --- /dev/null +++ b/mobile/src/session/mobile-terminal-viewport-resubscribe.ts @@ -0,0 +1,293 @@ +/** Bounds the scrollback→measure→resubscribe fit loop (STA-3337): a host whose + * frame dims can never equal the phone viewport must not re-arm the stream + * forever — it broke gesture recognition and drained battery at ~25 cycles/s. */ + +import type { MobileTerminalDiagnostics } from './mobile-terminal-diagnostics' + +export const MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS = 3 + +/** Attempt-indexed teardown delay. Attempt 0 is the ordinary first fit pass + * (server learns the viewport) and must stay immediate; later attempts mean + * the server answered with non-matching dims, so probe at a decaying rate. */ +const TERMINAL_VIEWPORT_RESUBSCRIBE_BACKOFF_MS = [0, 750, 3000] as const + +export type TerminalViewportDims = { readonly cols: number; readonly rows: number } + +function readPositiveDimension(value: unknown): number | null { + return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null +} + +export function readTerminalViewportDims(data: Readonly>): { + readonly hostCols: number | null + readonly hostRows: number | null +} { + return { + hostCols: readPositiveDimension(data.cols), + hostRows: readPositiveDimension(data.rows) + } +} + +export type TerminalViewportResubscribeDecision = + | { readonly kind: 'resubscribe'; readonly delayMs: number } + | { readonly kind: 'converged' } + | { readonly kind: 'hold' } + | { readonly kind: 'exhausted' } + +function resubscribeDelayMs(attempts: number): number { + return TERMINAL_VIEWPORT_RESUBSCRIBE_BACKOFF_MS[ + Math.min(attempts, TERMINAL_VIEWPORT_RESUBSCRIBE_BACKOFF_MS.length - 1) + ] +} + +export function resolveTerminalViewportResubscribe(args: { + hostCols: number | null + hostRows: number | null + viewportMeasured: boolean + viewport: TerminalViewportDims | null + attempts: number +}): TerminalViewportResubscribeDecision { + const overBudget = args.attempts >= MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS + // First subscribe carries no viewport; resubscribing is how the server learns it. + if (!args.viewportMeasured || args.viewport == null) { + return overBudget ? { kind: 'exhausted' } : { kind: 'resubscribe', delayMs: 0 } + } + // Why: a host that doesn't report PTY dims can never converge — resubscribing + // replays the identical frame, so keep the stream instead of probing it. + if (args.hostCols == null || args.hostRows == null) { + return { kind: 'hold' } + } + if (args.hostCols === args.viewport.cols && args.hostRows === args.viewport.rows) { + return { kind: 'converged' } + } + return overBudget + ? { kind: 'exhausted' } + : { kind: 'resubscribe', delayMs: resubscribeDelayMs(args.attempts) } +} + +/** Post-measure re-check: the pre-measure mismatch may have been a stale cached + * viewport. Resubscribing is only productive when the server still disagrees + * with the fresh measure, or was never told the viewport at all. */ +export function shouldResubscribeAfterViewportMeasure(args: { + hostCols: number | null + hostRows: number | null + measured: TerminalViewportDims + viewportWasMeasured: boolean +}): boolean { + if (!args.viewportWasMeasured) { + return true + } + return args.hostCols !== args.measured.cols || args.hostRows !== args.measured.rows +} + +/** Per-handle resubscribe budget, mirroring the chat-side rearm bound: attempts + * refill only when the handle actually left terminal.list and came back. A + * still-listed non-converging handle re-funded on every list refresh would undo + * the bound this class exists to enforce. */ +export class TerminalViewportResubscribeBudget { + private readonly attemptsByHandle = new Map() + private readonly absentSinceExhaustion = new Set() + private readonly announcedExhaustion = new Set() + private readonly retryGenerationByHandle = new Map() + + attempts(handle: string): number { + return this.attemptsByHandle.get(handle) ?? 0 + } + + chargeAttempt(handle: string): void { + this.attemptsByHandle.set(handle, this.attempts(handle) + 1) + } + + retryGeneration(handle: string): object { + const existing = this.retryGenerationByHandle.get(handle) + if (existing) { + return existing + } + const generation = {} + this.retryGenerationByHandle.set(handle, generation) + return generation + } + + isRetryGenerationCurrent(handle: string, generation: object): boolean { + return this.retryGenerationByHandle.get(handle) === generation + } + + observeResize( + handle: string, + data: Readonly>, + viewport: TerminalViewportDims | null + ): readonly [number, number] { + const { hostCols, hostRows } = readTerminalViewportDims(data) + const cols = hostCols ?? 80 + const rows = hostRows ?? 24 + if (viewport?.cols === cols && viewport.rows === rows) { + this.markConverged(handle) + } + return [cols, rows] + } + + markConverged(handle: string): void { + this.forget(handle) + } + + /** True exactly once per exhaustion so the degraded state is announced, not spammed. */ + shouldAnnounceExhaustion(handle: string): boolean { + if (this.announcedExhaustion.has(handle)) { + return false + } + this.announcedExhaustion.add(handle) + return true + } + + notifyListedHandles(liveHandles: ReadonlySet): void { + for (const handle of Array.from(this.attemptsByHandle.keys())) { + if (this.attempts(handle) < MAX_TERMINAL_VIEWPORT_RESUBSCRIBE_ATTEMPTS) { + continue + } + if (!liveHandles.has(handle)) { + this.absentSinceExhaustion.add(handle) + continue + } + // Why: only an absence marker buys a refill — the handle's PTY may be live + // again, so a fresh budget (and a fresh degrade announcement) is warranted. + if (this.absentSinceExhaustion.delete(handle)) { + this.forget(handle) + } + } + } + + forget(handle: string): void { + this.attemptsByHandle.delete(handle) + this.absentSinceExhaustion.delete(handle) + this.announcedExhaustion.delete(handle) + this.retryGenerationByHandle.delete(handle) + } + + clear(): void { + this.attemptsByHandle.clear() + this.absentSinceExhaustion.clear() + this.announcedExhaustion.clear() + this.retryGenerationByHandle.clear() + } +} + +type MutableRef = { current: T } + +type TerminalFitWebView = { + awaitReady: () => Promise + measureFitDimensions: (frameHeight?: number) => Promise +} + +export type TerminalViewportFitPassArgs = { + handle: string + seq: number + hostCols: number | null + hostRows: number | null + budget: TerminalViewportResubscribeBudget + diagnostics: Pick< + MobileTerminalDiagnostics, + 'streamResubscribing' | 'streamResubscribeHeld' | 'streamResubscribeExhausted' + > + viewportRef: MutableRef + viewportMeasuredRef: MutableRef + subscribeSeqRef: MutableRef> + initializedHandlesRef: MutableRef> + terminalUnsubsRef: MutableRef void>> + terminalFrameHeightRef: MutableRef + getTerminalRef: (handle: string | null) => TerminalFitWebView | undefined + unsubscribeTerminal: (handle: string) => void + subscribeToTerminal: (handle: string) => void + scheduleDelayedAction: (fn: () => void, ms: number) => void + showToast: (message: string, durationMs?: number) => void +} + +/** One bounded fit pass per scrollback frame: converge, hold, degrade visibly, + * or measure and resubscribe (backing off) so the server can phone-fit. */ +export function runTerminalViewportFitPass(args: TerminalViewportFitPassArgs): void { + const { handle, seq, hostCols, hostRows, budget, diagnostics } = args + const retryGeneration = budget.retryGeneration(handle) + const decision = resolveTerminalViewportResubscribe({ + hostCols, + hostRows, + viewportMeasured: args.viewportMeasuredRef.current, + viewport: args.viewportRef.current, + attempts: budget.attempts(handle) + }) + if (decision.kind === 'converged') { + budget.markConverged(handle) + return + } + if (decision.kind === 'hold') { + diagnostics.streamResubscribeHeld(handle, seq) + return + } + if (decision.kind === 'exhausted') { + diagnostics.streamResubscribeExhausted(handle, seq, budget.attempts(handle)) + if (budget.shouldAnnounceExhaustion(handle)) { + args.showToast("Couldn't fit the terminal to this screen", 4000) + } + return + } + const viewportWasMeasured = args.viewportMeasuredRef.current + void (async () => { + // Why: wait for init()'s rAF chain before measuring, else the measure races ahead and returns null (log dump 2026-05-06). + await args.getTerminalRef(handle)?.awaitReady() + if ( + args.subscribeSeqRef.current.get(handle) !== seq || + !budget.isRetryGenerationCurrent(handle, retryGeneration) + ) { + return + } + const dims = await args + .getTerminalRef(handle) + ?.measureFitDimensions(args.terminalFrameHeightRef.current || undefined) + // Why: re-check seq — the awaits may have let a newer subscribe cycle arm; tearing it down would resubscribe a stale generation. + if ( + args.subscribeSeqRef.current.get(handle) !== seq || + !budget.isRetryGenerationCurrent(handle, retryGeneration) + ) { + return + } + if (!args.getTerminalRef(handle) || !dims) { + return + } + args.viewportRef.current = dims + args.viewportMeasuredRef.current = true + if ( + !shouldResubscribeAfterViewportMeasure({ + hostCols, + hostRows, + measured: dims, + viewportWasMeasured + }) + ) { + // Why: the pre-measure mismatch was a stale cached viewport; the server already agrees. + budget.markConverged(handle) + return + } + const resubscribe = (): void => { + if ( + args.subscribeSeqRef.current.get(handle) !== seq || + !budget.isRetryGenerationCurrent(handle, retryGeneration) + ) { + return + } + if (!args.getTerminalRef(handle)) { + return + } + diagnostics.streamResubscribing(handle, seq, dims, budget.attempts(handle), decision.delayMs) + args.unsubscribeTerminal(handle) + args.initializedHandlesRef.current.delete(handle) + args.subscribeToTerminal(handle) + // Why: only a resubscribe that actually armed spends budget; one turned away by its own gates never reached the host. + if (args.terminalUnsubsRef.current.has(handle)) { + budget.chargeAttempt(handle) + } + } + if (decision.delayMs > 0) { + // Why: keep the live stream up through the backoff so input keeps flowing; teardown happens only when the retry fires. + args.scheduleDelayedAction(resubscribe, decision.delayMs) + } else { + resubscribe() + } + })() +} diff --git a/mobile/src/session/use-mobile-native-chat-prompts.test.ts b/mobile/src/session/use-mobile-native-chat-prompts.test.ts new file mode 100644 index 00000000000..413fd1047fd --- /dev/null +++ b/mobile/src/session/use-mobile-native-chat-prompts.test.ts @@ -0,0 +1,62 @@ +import { createElement } from 'react' +import TestRenderer from 'react-test-renderer' +import { describe, expect, it } from 'vitest' +import type { AgentStatusEntry } from '../../../src/shared/agent-status-types' +import { useMobileNativeChatPrompts } from './use-mobile-native-chat-prompts' + +const APPROVAL = JSON.stringify({ + approval: { tool: 'Bash', summary: 'pnpm build > build.log 2>&1' } +}) + +function permissionFor(status: Partial | null): unknown { + let captured: unknown + function Probe(): null { + captured = useMobileNativeChatPrompts({ + enabled: true, + status: status as AgentStatusEntry | null, + messages: [] + }).permission + return null + } + TestRenderer.act(() => { + TestRenderer.create(createElement(Probe)) + }) + return captured +} + +describe('useMobileNativeChatPrompts approval-envelope state gate', () => { + it('renders no approval card while the agent is working', () => { + expect(permissionFor({ state: 'working', interactivePrompt: APPROVAL })).toBeNull() + }) + + it('renders no approval card after the turn is done', () => { + expect(permissionFor({ state: 'done', interactivePrompt: APPROVAL })).toBeNull() + }) + + it('renders no approval card without a status', () => { + expect(permissionFor(null)).toBeNull() + }) + + it('renders the approval card while the agent is waiting', () => { + expect(permissionFor({ state: 'waiting', interactivePrompt: APPROVAL })).toMatchObject({ + title: 'Allow Bash?', + detail: 'pnpm build > build.log 2>&1' + }) + }) + + it('renders the approval card while the agent is blocked', () => { + expect(permissionFor({ state: 'blocked', interactivePrompt: APPROVAL })).toMatchObject({ + title: 'Allow Bash?' + }) + }) + + it('prefers the heuristic numbered menu over the envelope while paused', () => { + const permission = permissionFor({ + state: 'waiting', + interactivePrompt: APPROVAL, + lastAssistantMessage: 'Allow this Bash command?\n1. Yes\n2. No' + }) as { options: Array<{ label: string }> } | null + expect(permission).toMatchObject({ title: 'Permission requested' }) + expect(permission?.options.map((o) => o.label)).toEqual(['Yes', 'No']) + }) +}) diff --git a/mobile/src/session/use-mobile-native-chat-prompts.ts b/mobile/src/session/use-mobile-native-chat-prompts.ts index 11a17696bfc..1e362030750 100644 --- a/mobile/src/session/use-mobile-native-chat-prompts.ts +++ b/mobile/src/session/use-mobile-native-chat-prompts.ts @@ -19,15 +19,18 @@ export function useMobileNativeChatPrompts(args: { }): MobileNativeChatPrompts { const { enabled, status, messages } = args const blocked = status?.state === 'waiting' || status?.state === 'blocked' + // Both permission paths sit inside the paused gate: an approval envelope can + // outlive its answer (the host keeps it sticky), so only a waiting/blocked + // agent may surface it — never a working or done one (STA-3144). const permission = - (blocked && status - ? detectAgentPermission({ + blocked && status + ? (detectAgentPermission({ state: status.state, lastAssistantMessage: status.lastAssistantMessage, toolName: status.toolName, toolInput: status.toolInput - }) - : null) ?? parseApprovalFromStatus(status?.interactivePrompt) + }) ?? parseApprovalFromStatus(status.interactivePrompt)) + : null const question = blocked && status && !permission ? parseAgentQuestion(status.lastAssistantMessage ?? '') : null const askFromStatus = useMemo( diff --git a/mobile/src/terminal/terminal-keyboard-avoidance-lift.test.ts b/mobile/src/terminal/terminal-keyboard-avoidance-lift.test.ts new file mode 100644 index 00000000000..4c11320db2e --- /dev/null +++ b/mobile/src/terminal/terminal-keyboard-avoidance-lift.test.ts @@ -0,0 +1,122 @@ +import { describe, expect, it } from 'vitest' + +import { computeActiveTerminalKeyboardLift } from './terminal-keyboard-avoidance-lift' +import { parseTerminalKeyboardAvoidanceMetrics } from './terminal-webview-contract' +import type { TerminalKeyboardAvoidanceMetrics } from './terminal-webview-contract' + +const FRAME_HEIGHT = 800 +const ROWS = 40 +const KEYBOARD_LIFT = 300 + +function metrics( + overrides: Partial = {} +): TerminalKeyboardAvoidanceMetrics { + return { cursorY: 0, contentBottomRow: 0, rows: ROWS, altScreen: false, ...overrides } +} + +describe('computeActiveTerminalKeyboardLift', () => { + it('returns 0 when the keyboard is closed', () => { + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: 0, + metrics: metrics({ cursorY: 30, contentBottomRow: 34 }), + terminalFrameHeight: FRAME_HEIGHT + }) + ).toBe(0) + }) + + it('falls back to the full lift when metrics are missing', () => { + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: undefined, + terminalFrameHeight: FRAME_HEIGHT + }) + ).toBe(KEYBOARD_LIFT) + }) + + it('falls back to the full lift when rows or frame height are unmeasured', () => { + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ rows: 0 }), + terminalFrameHeight: FRAME_HEIGHT + }) + ).toBe(KEYBOARD_LIFT) + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics(), + terminalFrameHeight: 0 + }) + ).toBe(KEYBOARD_LIFT) + }) + + it('lifts fully for alt-screen TUIs', () => { + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ cursorY: 10, contentBottomRow: 10, altScreen: true }), + terminalFrameHeight: FRAME_HEIGHT + }) + ).toBe(KEYBOARD_LIFT) + }) + + it('clears a main-buffer footer while an old payload retains cursor-only behavior', () => { + const candidate = computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ cursorY: 30, contentBottomRow: 34 }), + terminalFrameHeight: FRAME_HEIGHT + }) + const oldPayload = parseTerminalKeyboardAvoidanceMetrics({ cursorY: 30, rows: ROWS }) + const cursorOnly = computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: oldPayload, + terminalFrameHeight: FRAME_HEIGHT + }) + expect({ candidate, cursorOnly }).toEqual({ candidate: 220, cursorOnly: 140 }) + }) + + it('keeps short output near the top put (no lift)', () => { + expect( + computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ cursorY: 2, contentBottomRow: 5 }), + terminalFrameHeight: FRAME_HEIGHT + }) + ).toBe(0) + }) + + it('matches cursor-clearing behavior for a scrolled shell (prompt at the bottom)', () => { + const lift = computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ cursorY: 38, contentBottomRow: 38 }), + terminalFrameHeight: FRAME_HEIGHT + }) + expect(lift).toBe(KEYBOARD_LIFT) + }) + + it('never exceeds the keyboard lift', () => { + const lift = computeActiveTerminalKeyboardLift({ + keyboardLift: KEYBOARD_LIFT, + metrics: metrics({ cursorY: 39, contentBottomRow: 39 }), + terminalFrameHeight: FRAME_HEIGHT + }) + expect(lift).toBeLessThanOrEqual(KEYBOARD_LIFT) + }) + + it('uses the platform-adjusted lift proportionally on iOS and Android', () => { + const tuiMetrics = metrics({ cursorY: 30, contentBottomRow: 34 }) + const android = computeActiveTerminalKeyboardLift({ + keyboardLift: 300, + metrics: tuiMetrics, + terminalFrameHeight: FRAME_HEIGHT + }) + const ios = computeActiveTerminalKeyboardLift({ + keyboardLift: 266, + metrics: tuiMetrics, + terminalFrameHeight: FRAME_HEIGHT + }) + expect({ android, ios }).toEqual({ android: 220, ios: 186 }) + }) +}) diff --git a/mobile/src/terminal/terminal-keyboard-avoidance-lift.ts b/mobile/src/terminal/terminal-keyboard-avoidance-lift.ts new file mode 100644 index 00000000000..6ada640430d --- /dev/null +++ b/mobile/src/terminal/terminal-keyboard-avoidance-lift.ts @@ -0,0 +1,29 @@ +import type { TerminalKeyboardAvoidanceMetrics } from './terminal-webview-contract' + +type ActiveTerminalKeyboardLiftParams = { + keyboardLift: number + metrics: TerminalKeyboardAvoidanceMetrics | undefined + terminalFrameHeight: number +} + +export function computeActiveTerminalKeyboardLift( + params: ActiveTerminalKeyboardLiftParams +): number { + const { keyboardLift, metrics, terminalFrameHeight } = params + if (keyboardLift <= 0) { + return 0 + } + if (!metrics || metrics.rows <= 0 || terminalFrameHeight <= 0) { + return keyboardLift + } + if (metrics.altScreen) { + return keyboardLift + } + const rowHeight = terminalFrameHeight / metrics.rows + // Main-buffer TUI footer rows can sit below the caret. + const anchorRow = Math.max(metrics.cursorY, metrics.contentBottomRow) + const anchorBottom = (anchorRow + 1) * rowHeight + const dockTop = terminalFrameHeight - keyboardLift + const margin = rowHeight + return Math.min(keyboardLift, Math.max(0, anchorBottom + margin - dockTop)) +} diff --git a/mobile/src/terminal/terminal-keyboard-avoidance-metrics-injected.ts b/mobile/src/terminal/terminal-keyboard-avoidance-metrics-injected.ts new file mode 100644 index 00000000000..a3a29ac61f9 --- /dev/null +++ b/mobile/src/terminal/terminal-keyboard-avoidance-metrics-injected.ts @@ -0,0 +1,43 @@ +export const TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS = ` + function lineHasVisibleContent(line, cell) { + if (line.translateToString(true).trim().length > 0) return true; + if (!cell || !line.getCell) return false; + var limit = Math.min(term.cols || 0, line.length || 0); + for (var x = 0; x < limit; x++) { + var current = line.getCell(x, cell); + if (!current) continue; + if (!current.isBgDefault() || current.isInverse()) return true; + if (typeof current.isUnderline === 'function' && current.isUnderline()) return true; + if (typeof current.isStrikethrough === 'function' && current.isStrikethrough()) return true; + if (typeof current.isOverline === 'function' && current.isOverline()) return true; + } + return false; + } + + function computeContentBottomRow() { + if (!term || !term.buffer || !term.buffer.active) return 0; + var buffer = term.buffer.active; + var top = buffer.viewportY || 0; + var cell = buffer.getNullCell ? buffer.getNullCell() : null; + for (var y = (term.rows || 0) - 1; y >= 0; y--) { + try { + var line = buffer.getLine(top + y); + if (line && lineHasVisibleContent(line, cell)) return y; + } catch (e) {} + } + return 0; + } + + function emitKeyboardAvoidanceMetrics() { + if (!term) return; + var alt = false; + try { alt = term.buffer && term.buffer.active && term.buffer.active.type === 'alternate'; } catch (e) {} + notify({ + type: 'keyboard-avoidance-metrics', + cursorY: term.buffer && term.buffer.active ? term.buffer.active.cursorY : 0, + contentBottomRow: alt ? 0 : computeContentBottomRow(), + rows: term.rows || 0, + altScreen: alt + }); + } +` diff --git a/mobile/src/terminal/terminal-keyboard-avoidance-webview.test.ts b/mobile/src/terminal/terminal-keyboard-avoidance-webview.test.ts new file mode 100644 index 00000000000..3a09ae3acd4 --- /dev/null +++ b/mobile/src/terminal/terminal-keyboard-avoidance-webview.test.ts @@ -0,0 +1,215 @@ +import { readFileSync } from 'node:fs' +import { Script } from 'node:vm' +import { Terminal } from '@xterm/xterm' +import { describe, expect, it, vi } from 'vitest' +import { TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS } from './terminal-keyboard-avoidance-metrics-injected' +import { parseTerminalKeyboardAvoidanceMetrics } from './terminal-webview-contract' + +const terminalHtmlSource = readFileSync( + new URL('./terminal-webview-html.ts', import.meta.url), + 'utf8' +) +const reflowSource = readFileSync( + new URL('./terminal-webview-reflow-injected.ts', import.meta.url), + 'utf8' +) + +type Cell = { isBgDefault: () => boolean; isInverse: () => number } +type MetricsNotification = { + type: string + cursorY: number + contentBottomRow: number + rows: number + altScreen: boolean +} + +function makeLine(text = '', styledColumns: number[] = []) { + const styled = new Set(styledColumns) + return { + isWrapped: false, + length: 10, + translateToString: vi.fn(() => text), + getCell: (column: number): Cell => ({ + isBgDefault: () => !styled.has(column), + isInverse: () => 0 + }) + } +} + +function runMetrics(lines: (ReturnType | undefined)[], altScreen = false) { + const notifications: Record[] = [] + const buffer = { + cursorY: 2, + viewportY: 3, + type: altScreen ? 'alternate' : 'normal', + getLine: (index: number) => lines[index - 3], + getNullCell: () => ({}) + } + const context = { + notifications, + notify: (message: Record) => notifications.push(message), + term: { buffer: { active: buffer }, cols: 10, rows: lines.length } + } + new Script( + `${TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS}\nemitKeyboardAvoidanceMetrics();` + ).runInNewContext(context) + return notifications[0] as MetricsNotification +} + +function runTerminalMetrics(term: Terminal) { + const notifications: Record[] = [] + new Script( + `${TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS}\nemitKeyboardAvoidanceMetrics();` + ).runInNewContext({ + notify: (message: Record) => notifications.push(message), + term + }) + return notifications[0] as MetricsNotification +} + +function write(term: Terminal, data: string): Promise { + return new Promise((resolve) => term.write(data, resolve)) +} + +describe('terminal keyboard-avoidance WebView metrics', () => { + it('finds text on wrapped rows using the visible viewport offset', () => { + const lines = [makeLine('header'), makeLine(''), makeLine('wrapped footer')] + lines[2]!.isWrapped = true + expect(runMetrics(lines)).toMatchObject({ contentBottomRow: 2 }) + }) + + it('supports cells without decoration APIs and keeps background-only ANSI chrome visible', () => { + expect(runMetrics([makeLine('header'), makeLine(''), makeLine('')])).toMatchObject({ + contentBottomRow: 0 + }) + expect(runMetrics([makeLine('header'), makeLine(''), makeLine('', [4])])).toMatchObject({ + contentBottomRow: 2 + }) + }) + + it('classifies real xterm text and styled whitespace by rendered visibility', async () => { + const cases = [ + { name: 'default spaces', data: ' ', expected: 0 }, + { name: 'text', data: 'footer', expected: 7 }, + { name: 'background', data: '\x1b[41m \x1b[0m', expected: 7 }, + { name: 'inverse', data: '\x1b[7m \x1b[0m', expected: 7 }, + { name: 'underline', data: '\x1b[4m \x1b[0m', expected: 7 }, + { name: 'strikethrough', data: '\x1b[9m \x1b[0m', expected: 7 }, + { name: 'overline', data: '\x1b[53m \x1b[0m', expected: 7 }, + // Hidden text still reserves TUI layout, so keyboard avoidance treats it as content. + { name: 'invisible text', data: '\x1b[8mfooter\x1b[0m', expected: 7 } + ] + + for (const { name, data, expected } of cases) { + const term = new Terminal({ cols: 10, rows: 8 }) + try { + await write(term, `\x1b[8;1H${data}`) + expect(runTerminalMetrics(term), name).toMatchObject({ contentBottomRow: expected }) + } finally { + term.dispose() + } + } + }) + + it('tracks the real xterm viewport and alternate screen', async () => { + const term = new Terminal({ cols: 10, rows: 4, scrollback: 100 }) + try { + await write(term, 'header\r\n\r\n\r\n\r\nfooter') + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 3, altScreen: false }) + term.scrollLines(-2) + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 0, altScreen: false }) + await write(term, '\x1b[?1049h\x1b[4m \x1b[0m') + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 0, altScreen: true }) + } finally { + term.dispose() + } + }) + + it('follows real xterm resize and reset state', async () => { + const term = new Terminal({ cols: 10, rows: 8 }) + try { + await write(term, '\x1b[8;1Hfooter') + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 7 }) + term.resize(10, 4) + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 3 }) + term.reset() + expect(runTerminalMetrics(term)).toMatchObject({ contentBottomRow: 0 }) + } finally { + term.dispose() + } + }) + + it('keeps real xterm metrics compatible with old payloads', async () => { + const term = new Terminal({ cols: 10, rows: 8 }) + try { + await write(term, '\x1b[8;1Hfooter\x1b[2;1H') + const { cursorY, rows, altScreen } = runTerminalMetrics(term) + expect(parseTerminalKeyboardAvoidanceMetrics({ cursorY, rows, altScreen })).toEqual({ + cursorY: 1, + contentBottomRow: 1, + rows: 8, + altScreen: false + }) + } finally { + term.dispose() + } + }) + + it('releases real xterm metric observers across terminal lifecycles', async () => { + for (let cycle = 0; cycle < 25; cycle += 1) { + const term = new Terminal({ cols: 10, rows: 4 }) + let emissions = 0 + const observer = term.onWriteParsed(() => { + runTerminalMetrics(term) + emissions += 1 + }) + try { + await write(term, `cycle ${cycle}`) + expect(emissions).toBeGreaterThan(0) + observer.dispose() + const disposedAt = emissions + await write(term, ' after dispose') + expect(emissions).toBe(disposedAt) + } finally { + observer.dispose() + term.dispose() + } + } + }) + + it('stops at the first bottom-up match and skips scans on alternate screen', () => { + const footer = makeLine('footer') + const header = makeLine('header') + expect(runMetrics([header, makeLine(''), footer])).toMatchObject({ contentBottomRow: 2 }) + expect(footer.translateToString).toHaveBeenCalledTimes(1) + expect(header.translateToString).not.toHaveBeenCalled() + + footer.translateToString.mockImplementation(() => { + throw new Error('alternate screen must not scan') + }) + expect(runMetrics([header, makeLine(''), footer], true)).toMatchObject({ + altScreen: true, + contentBottomRow: 0 + }) + }) + + it('refreshes metrics after every buffer geometry reset', () => { + const resizeStart = terminalHtmlSource.indexOf(' function resize(cols, rows)') + const resizeEnd = terminalHtmlSource.indexOf('\n // reflow()', resizeStart) + const clearStart = terminalHtmlSource.indexOf("} else if (msg.type === 'clear') {") + const clearEnd = terminalHtmlSource.indexOf("} else if (msg.type === 'measure')", clearStart) + const textScaleStart = terminalHtmlSource.indexOf(' function applyTextScale(scale)') + const textScaleEnd = terminalHtmlSource.indexOf('\n var panX', textScaleStart) + + for (const block of [ + terminalHtmlSource.slice(resizeStart, resizeEnd), + terminalHtmlSource.slice(clearStart, clearEnd), + terminalHtmlSource.slice(textScaleStart, textScaleEnd), + reflowSource + ]) { + expect(block.indexOf('emitKeyboardAvoidanceMetrics()')).toBeGreaterThan( + block.includes('term.resize') ? block.indexOf('term.resize') : block.indexOf('term.reset') + ) + } + }) +}) diff --git a/mobile/src/terminal/terminal-live-input-affordance.test.ts b/mobile/src/terminal/terminal-live-input-affordance.test.ts index cc681e2056e..0125cb053e6 100644 --- a/mobile/src/terminal/terminal-live-input-affordance.test.ts +++ b/mobile/src/terminal/terminal-live-input-affordance.test.ts @@ -10,7 +10,7 @@ const liveInputStatusSource = readFileSync( 'utf8' ) const commandInputStylesSource = readFileSync( - new URL('../../app/h/[hostId]/session/mobile-session-command-input-styles.ts', import.meta.url), + new URL('../session/mobile-session-command-input-styles.ts', import.meta.url), 'utf8' ) const liveInputFocusSource = readFileSync( diff --git a/mobile/src/terminal/terminal-webview-contract.test.ts b/mobile/src/terminal/terminal-webview-contract.test.ts new file mode 100644 index 00000000000..0a3527111e3 --- /dev/null +++ b/mobile/src/terminal/terminal-webview-contract.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from 'vitest' + +import { parseTerminalKeyboardAvoidanceMetrics } from './terminal-webview-contract' + +describe('parseTerminalKeyboardAvoidanceMetrics', () => { + it('parses a full payload', () => { + expect( + parseTerminalKeyboardAvoidanceMetrics({ + cursorY: 30, + contentBottomRow: 34, + rows: 40, + altScreen: true + }) + ).toEqual({ cursorY: 30, contentBottomRow: 34, rows: 40, altScreen: true }) + }) + + it('defaults contentBottomRow to cursorY when absent (older WebView bundles)', () => { + expect(parseTerminalKeyboardAvoidanceMetrics({ cursorY: 12, rows: 40 })).toEqual({ + cursorY: 12, + contentBottomRow: 12, + rows: 40, + altScreen: false + }) + }) + + it('defaults non-numeric fields to zero', () => { + expect(parseTerminalKeyboardAvoidanceMetrics({})).toEqual({ + cursorY: 0, + contentBottomRow: 0, + rows: 0, + altScreen: false + }) + }) + + it('bounds untrusted numeric fields to the reported viewport', () => { + expect( + parseTerminalKeyboardAvoidanceMetrics({ + cursorY: Number.POSITIVE_INFINITY, + contentBottomRow: 99.8, + rows: 40.7, + altScreen: 'true' + }) + ).toEqual({ cursorY: 0, contentBottomRow: 39, rows: 40, altScreen: false }) + expect( + parseTerminalKeyboardAvoidanceMetrics({ + cursorY: -4, + contentBottomRow: Number.NaN, + rows: -1 + }) + ).toEqual({ cursorY: 0, contentBottomRow: 0, rows: 0, altScreen: false }) + }) +}) diff --git a/mobile/src/terminal/terminal-webview-contract.ts b/mobile/src/terminal/terminal-webview-contract.ts index 63c155b7a23..c28fd4a5038 100644 --- a/mobile/src/terminal/terminal-webview-contract.ts +++ b/mobile/src/terminal/terminal-webview-contract.ts @@ -14,10 +14,34 @@ export type TerminalModes = { export type TerminalKeyboardAvoidanceMetrics = { cursorY: number + // Main-buffer TUIs can render footer rows below the caret. + contentBottomRow: number rows: number altScreen: boolean } +export function parseTerminalKeyboardAvoidanceMetrics( + msg: Record +): TerminalKeyboardAvoidanceMetrics { + const rows = toNonNegativeInteger(msg.rows) + const maxRow = Math.max(0, rows - 1) + const cursorY = Math.min(toNonNegativeInteger(msg.cursorY), maxRow) + const contentBottomRow = + msg.contentBottomRow === undefined + ? cursorY + : Math.min(toNonNegativeInteger(msg.contentBottomRow), maxRow) + return { + cursorY, + contentBottomRow, + rows, + altScreen: msg.altScreen === true + } +} + +function toNonNegativeInteger(value: unknown): number { + return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0 +} + export type MobileTerminalTheme = RuntimeMobileTerminalTheme export type TerminalSelectionEvents = { diff --git a/mobile/src/terminal/terminal-webview-html.ts b/mobile/src/terminal/terminal-webview-html.ts index a7715e4f564..c3ba29bb542 100644 --- a/mobile/src/terminal/terminal-webview-html.ts +++ b/mobile/src/terminal/terminal-webview-html.ts @@ -3,6 +3,7 @@ import type { RuntimeMobileTerminalTheme } from '../../../src/shared/runtime-typ import { colors } from '../theme/mobile-theme' import { TERMINAL_TEXT_SCALES } from '../storage/preferences' import { TERMINAL_PATH_TAP_JS } from './terminal-path-tap-injected' +import { TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS } from './terminal-keyboard-avoidance-metrics-injected' import { XTERM_ENGINE_CSS, XTERM_ENGINE_JS } from './terminal-webview-engine.generated' import { TERMINAL_REFLOW_JS } from './terminal-webview-reflow-injected' import { TERMINAL_SURFACE_SWAP_JS } from './terminal-webview-surface-swap-injected' @@ -287,6 +288,7 @@ window.onerror = function(msg) { if (cols < MIN_FIT_COLS) return; var rows = Math.max(8, Math.floor(window.innerHeight / cellH)); term.resize(cols, rows); + emitKeyboardAvoidanceMetrics(); } applyFitScale('text-scale'); }); @@ -802,6 +804,7 @@ ${TERMINAL_WEBGL_RECOVERY_JS} if (!term) return; initRows = rows || initRows; term.resize(cols || term.cols, rows || term.rows); + emitKeyboardAvoidanceMetrics(); applyFitScale('resize-msg'); notify({ type: 'ready', cols: cols, rows: rows }); } @@ -958,6 +961,7 @@ ${TERMINAL_WEBGL_RECOVERY_JS} initialOscLinkEvictionReady = false; if (term) { term.clear(); term.reset(); } emitModesIfChanged(); + emitKeyboardAvoidanceMetrics(); resetEvictionCounter(); if (selMode === 'select') { notify({ type: 'selection-evicted' }); @@ -1100,17 +1104,7 @@ ${TERMINAL_WEBGL_RECOVERY_JS} sgrMousePixelsMode: false }; - function emitKeyboardAvoidanceMetrics() { - if (!term) return; - var alt = false; - try { alt = term.buffer && term.buffer.active && term.buffer.active.type === 'alternate'; } catch (e) {} - notify({ - type: 'keyboard-avoidance-metrics', - cursorY: term.buffer && term.buffer.active ? term.buffer.active.cursorY : 0, - rows: term.rows || 0, - altScreen: alt - }); - } + ${TERMINAL_KEYBOARD_AVOIDANCE_METRICS_JS} function attachTermObservers() { if (!term) return; diff --git a/mobile/src/terminal/terminal-webview-notification-dispatch.test.ts b/mobile/src/terminal/terminal-webview-notification-dispatch.test.ts new file mode 100644 index 00000000000..bcd777a2e8f --- /dev/null +++ b/mobile/src/terminal/terminal-webview-notification-dispatch.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it, vi } from 'vitest' + +import { dispatchTerminalWebViewNotification } from './terminal-webview-notification-dispatch' + +describe('dispatchTerminalWebViewNotification', () => { + it('preserves bounded keyboard metrics through the dispatcher', () => { + const onKeyboardAvoidanceMetrics = vi.fn() + dispatchTerminalWebViewNotification( + { + type: 'keyboard-avoidance-metrics', + cursorY: 30, + contentBottomRow: 99, + rows: 40, + altScreen: true + }, + { onKeyboardAvoidanceMetrics, reportEngineError: vi.fn() } + ) + expect(onKeyboardAvoidanceMetrics).toHaveBeenCalledWith({ + cursorY: 30, + contentBottomRow: 39, + rows: 40, + altScreen: true + }) + }) + + it('keeps old WebView payloads cursor-compatible', () => { + const onKeyboardAvoidanceMetrics = vi.fn() + dispatchTerminalWebViewNotification( + { type: 'keyboard-avoidance-metrics', cursorY: 12, rows: 40 }, + { onKeyboardAvoidanceMetrics, reportEngineError: vi.fn() } + ) + expect(onKeyboardAvoidanceMetrics).toHaveBeenCalledWith({ + cursorY: 12, + contentBottomRow: 12, + rows: 40, + altScreen: false + }) + }) +}) diff --git a/mobile/src/terminal/terminal-webview-notification-dispatch.ts b/mobile/src/terminal/terminal-webview-notification-dispatch.ts index 372df650fe0..77019d3f996 100644 --- a/mobile/src/terminal/terminal-webview-notification-dispatch.ts +++ b/mobile/src/terminal/terminal-webview-notification-dispatch.ts @@ -1,4 +1,7 @@ -import type { TerminalSelectionEvents } from './terminal-webview-contract' +import { + parseTerminalKeyboardAvoidanceMetrics, + type TerminalSelectionEvents +} from './terminal-webview-contract' export type TerminalWebViewNotificationHandlers = Omit< TerminalSelectionEvents, @@ -63,13 +66,7 @@ export function dispatchTerminalWebViewNotification( handlers.onOpenUrl?.(url) } } else if (msg.type === 'keyboard-avoidance-metrics') { - const cursorY = typeof msg.cursorY === 'number' ? msg.cursorY : 0 - const rows = typeof msg.rows === 'number' ? msg.rows : 0 - handlers.onKeyboardAvoidanceMetrics?.({ - cursorY, - rows, - altScreen: !!msg.altScreen - }) + handlers.onKeyboardAvoidanceMetrics?.(parseTerminalKeyboardAvoidanceMetrics(msg)) } else if (msg.type === 'haptic') { const kind = msg.kind if (kind === 'selection' || kind === 'success' || kind === 'error' || kind === 'edge-bump') { diff --git a/mobile/src/terminal/terminal-webview-reflow-injected.ts b/mobile/src/terminal/terminal-webview-reflow-injected.ts index 4fea62f5107..ef704529e4b 100644 --- a/mobile/src/terminal/terminal-webview-reflow-injected.ts +++ b/mobile/src/terminal/terminal-webview-reflow-injected.ts @@ -28,5 +28,6 @@ export const TERMINAL_REFLOW_JS = ` } applyFitScale('reflow-msg'); updateScrollIndicator(false); + emitKeyboardAvoidanceMetrics(); } ` diff --git a/mobile/src/theme/mobile-theme-contrast.test.ts b/mobile/src/theme/mobile-theme-contrast.test.ts new file mode 100644 index 00000000000..6546e6aaa43 --- /dev/null +++ b/mobile/src/theme/mobile-theme-contrast.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from 'vitest' +import { colors } from './mobile-theme' + +function channelLuminance(channel: number): number { + const value = channel / 255 + return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4 +} + +function relativeLuminance(hex: string): number { + const red = Number.parseInt(hex.slice(1, 3), 16) + const green = Number.parseInt(hex.slice(3, 5), 16) + const blue = Number.parseInt(hex.slice(5, 7), 16) + return ( + 0.2126 * channelLuminance(red) + + 0.7152 * channelLuminance(green) + + 0.0722 * channelLuminance(blue) + ) +} + +function contrastRatio(foreground: string, background: string): number { + const lighter = Math.max(relativeLuminance(foreground), relativeLuminance(background)) + const darker = Math.min(relativeLuminance(foreground), relativeLuminance(background)) + return (lighter + 0.05) / (darker + 0.05) +} + +describe('mobile text contrast', () => { + it('keeps muted text readable on every standard dark surface', () => { + for (const surface of [colors.bgBase, colors.bgPanel, colors.bgRaised]) { + expect(contrastRatio(colors.textMuted, surface)).toBeGreaterThanOrEqual(4.5) + } + }) + + it('keeps secondary text more prominent than muted text', () => { + expect(contrastRatio(colors.textSecondary, colors.bgPanel)).toBeGreaterThan( + contrastRatio(colors.textMuted, colors.bgPanel) + ) + }) +}) diff --git a/mobile/src/theme/mobile-theme.ts b/mobile/src/theme/mobile-theme.ts index dbf09b745b9..0ee1771ecb7 100644 --- a/mobile/src/theme/mobile-theme.ts +++ b/mobile/src/theme/mobile-theme.ts @@ -9,8 +9,8 @@ export const colors = { editorSurface: '#1e1e1e', textPrimary: '#e0e0e0', - textSecondary: '#888888', - textMuted: '#555555', + textSecondary: '#a1a1a1', + textMuted: '#8c8c8c', // Crisp near-white surface for the single primary action on a screen (the // worktree FAB). Brighter than textPrimary so it reads as a solid button, not diff --git a/mobile/src/transport/foreground-stale-dial-restart.test.ts b/mobile/src/transport/foreground-stale-dial-restart.test.ts new file mode 100644 index 00000000000..8c9ebd94d7e --- /dev/null +++ b/mobile/src/transport/foreground-stale-dial-restart.test.ts @@ -0,0 +1,301 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { connect } from './rpc-client' +import { classifyConnection, verdictDisplayLabel } from './connection-health' + +// Slack P0 — "mobile connection issue. was using it with my linux host then +// after i navigated out of the app and back it doesn't work anymore. Now i went +// back again it's connected now." +// +// The tell is that the SECOND foreground fixed it. notifyForeground only ever +// acted on 'connected' (probe the socket) and 'reconnecting' (redial now). A +// phone that is suspended mid-dial resumes in 'connecting'/'handshaking', where +// the nudge did nothing: the user waited out the remainder of the 12s connect +// budget on a socket opened over a network path that no longer existed, and +// then the *preserved* backoff delay — up to 60s of "Connecting…" against a +// desktop that was answering the whole time. By the next foreground the client +// had landed in 'reconnecting', where the nudge works, so it connected at once. + +vi.mock('./e2ee', () => ({ + generateKeyPair: () => ({ publicKey: new Uint8Array(32), secretKey: new Uint8Array(32) }), + deriveSharedKey: () => new Uint8Array(32), + publicKeyFromBase64: () => new Uint8Array(32), + publicKeyToBase64: () => 'client-public-key', + encrypt: (plaintext: string) => `encrypted:${plaintext}`, + decrypt: (raw: string) => raw.replace(/^encrypted:/, ''), + decryptBytes: (bytes: Uint8Array) => bytes +})) + +// Mirrors React Native's WebSocket: readyState lives in JS and only advances on +// a delivered event, so a socket the OS killed while the app was suspended stays +// CONNECTING forever from the client's point of view. +class MockWebSocket { + static CONNECTING = 0 + static OPEN = 1 + static CLOSING = 2 + static CLOSED = 3 + readonly CONNECTING = 0 + readonly OPEN = 1 + + readyState = MockWebSocket.CONNECTING + onopen: (() => void) | null = null + onclose: ((event?: unknown) => void) | null = null + onmessage: ((event: { data: unknown }) => void) | null = null + onerror: ((event?: unknown) => void) | null = null + // A socket the OS tore down while suspended never reports its own close. + deliversCloseEvent = true + sent: string[] = [] + + constructor(readonly endpoint: string) { + sockets.push(this) + } + + send(payload: string): void { + this.sent.push(payload) + } + + close(): void { + if (this.readyState === MockWebSocket.CLOSED) { + return + } + this.readyState = MockWebSocket.CLOSED + if (this.deliversCloseEvent) { + this.onclose?.({ code: 1006, wasClean: false }) + } + } + + open(): void { + this.readyState = MockWebSocket.OPEN + this.onopen?.() + } + + authenticate(): void { + this.open() + this.onmessage?.({ data: JSON.stringify({ type: 'e2ee_ready' }) }) + this.onmessage?.({ data: 'encrypted:{"type":"e2ee_authenticated"}' }) + } +} + +const sockets: MockWebSocket[] = [] +const originalWebSocket = globalThis.WebSocket + +function latest(): MockWebSocket { + const socket = sockets[sockets.length - 1] + if (!socket) { + throw new Error('no socket opened') + } + return socket +} + +function label(client: ReturnType, endpoint: string): string { + return verdictDisplayLabel( + classifyConnection({ + state: client.getState(), + reconnectAttempts: client.getReconnectAttempt(), + lastConnectedAt: client.getLastConnectedAt(), + endpoint, + nowMs: Date.now() + }) + ) +} + +// A suspended app is not a slow app: wall-clock time passes but not one JS timer +// runs, so the backoff loop does NOT keep cycling in the background. Advancing +// the system clock without draining the timer queue is what reproduces that — +// the connect timer armed before the suspension is still pending on resume, and +// the client is still sitting in the state it was suspended in. +function suspend(backgroundMs: number): void { + for (const socket of sockets) { + // iOS reclaims a suspended app's sockets without telling JS. + socket.deliversCloseEvent = false + } + vi.setSystemTime(Date.now() + backgroundMs) +} + +// Steps the clock one second at a time and reports how long the user has to sit +// on "Connecting…" before the client opens its next socket. +async function millisecondsUntilNextDial(dialsBefore: number): Promise { + const limitMs = 180_000 + for (let elapsedMs = 0; elapsedMs <= limitMs; elapsedMs += 1_000) { + if (sockets.length > dialsBefore) { + return elapsedMs + } + await vi.advanceTimersByTimeAsync(1_000) + } + return limitMs +} + +// Waits out the current backoff so the phone is suspended mid-dial — the state +// the reporter's phone resumed into — rather than between dials. +async function advanceUntilDialing(client: ReturnType): Promise { + for (let elapsedMs = 0; elapsedMs <= 120_000; elapsedMs += 250) { + if (client.getState() === 'connecting') { + return + } + await vi.advanceTimersByTimeAsync(250) + } + throw new Error(`client never re-entered connecting (state=${client.getState()})`) +} + +const TAILSCALE_ENDPOINT = 'ws://100.84.12.9:6769' + +describe('foregrounding a phone that was suspended mid-dial', () => { + beforeEach(() => { + vi.useFakeTimers() + vi.spyOn(console, 'log').mockImplementation(() => {}) + sockets.length = 0 + globalThis.WebSocket = MockWebSocket as unknown as typeof WebSocket + }) + + afterEach(() => { + vi.useRealTimers() + vi.restoreAllMocks() + globalThis.WebSocket = originalWebSocket + }) + + it('abandons a dial that predates the foreground edge instead of waiting it out', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + expect(client.getState()).toBe('connected') + + // The user leaves the app. The link dies while the phone is suspended, so + // the client is left holding a socket that will never open. + latest().close() + expect(client.getState()).toBe('reconnecting') + await vi.advanceTimersByTimeAsync(500) + expect(client.getState()).toBe('connecting') + const doomed = latest() + + suspend(120_000) + + // Back in the app. The desktop is healthy and answering. + const socketsBeforeForeground = sockets.length + client.notifyForeground() + + expect(sockets.length).toBe(socketsBeforeForeground + 1) + expect(latest()).not.toBe(doomed) + latest().authenticate() + expect(client.getState()).toBe('connected') + }) + + it('does not strand the user on "Connecting…" for a minute after returning', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + latest().close() + + // The desktop drops off the network while the user is still in the app, so + // the tiered backoff climbs into its slow tail (15s, 30s, 60s) before they + // ever leave. This is what makes the post-resume wait a full minute. + for (let dial = 0; dial < 6; dial++) { + await vi.advanceTimersByTimeAsync(12_000 + 60_000) + } + expect(client.getReconnectAttempt()).toBeGreaterThanOrEqual(6) + await advanceUntilDialing(client) + + suspend(90_000) + const dialsBefore = sockets.length + client.notifyForeground() + + // The desktop is reachable again and the user is looking at the screen, so + // the redial has to be in flight now — not after the abandoned socket's + // connect budget expires and another tail-length backoff is waited out. + expect(await millisecondsUntilNextDial(dialsBefore)).toBe(0) + + latest().authenticate() + expect(client.getState()).toBe('connected') + expect(label(client, TAILSCALE_ENDPOINT)).toBe('Connected') + + client.close() + }) + + it('clears the escalated label once the foreground redial lands', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + latest().close() + for (let dial = 0; dial < 4; dial++) { + await vi.advanceTimersByTimeAsync(12_000 + 60_000) + } + // Four failed dials is past WARNING_ATTEMPTS, so the card reads "Can't + // connect — check Tailscale" rather than a neutral "Connecting…". + expect(label(client, TAILSCALE_ENDPOINT)).toBe("Can't connect — check Tailscale") + await advanceUntilDialing(client) + const doomed = latest() + + suspend(120_000) + client.notifyForeground() + + expect(latest()).not.toBe(doomed) + latest().authenticate() + expect(client.getState()).toBe('connected') + expect(client.getReconnectAttempt()).toBe(0) + expect(label(client, TAILSCALE_ENDPOINT)).toBe('Connected') + + client.close() + }) + + it('keeps escalating when the user checks back repeatedly during a real outage', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + latest().close() + + // The desktop really is gone. Abandoning the stale dial must book the failure + // it represents, or each visit resets the counter faster than it can climb and + // the card reassures the user with "Connecting…" indefinitely (issue #10119). + for (let visit = 0; visit < 14; visit++) { + await advanceUntilDialing(client) + suspend(30_000) + client.notifyForeground() + } + + expect(client.getReconnectAttempt()).toBeGreaterThanOrEqual(12) + expect(label(client, TAILSCALE_ENDPOINT)).toBe("Can't reach desktop — check Tailscale") + + // And the escalation is not sticky: the desktop comes back, the card clears. + latest().authenticate() + expect(label(client, TAILSCALE_ENDPOINT)).toBe('Connected') + + client.close() + }) + + it('leaves a dial opened after the foreground edge alone', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + latest().close() + await vi.advanceTimersByTimeAsync(500) + const fresh = latest() + expect(client.getState()).toBe('connecting') + + // A Wi-Fi→cellular handoff fires a second revival nudge right behind the + // AppState one. It must not churn the dial that the first nudge just opened. + client.notifyForeground() + const afterFirstNudge = latest() + client.notifyForeground() + client.notifyForeground() + + expect(latest()).toBe(afterFirstNudge) + expect(fresh.endpoint).toBe(TAILSCALE_ENDPOINT) + + client.close() + }) + + it('abandons a handshake stalled across the suspension', async () => { + const client = connect(TAILSCALE_ENDPOINT, 'token', 'server-key') + latest().authenticate() + latest().close() + await vi.advanceTimersByTimeAsync(500) + + // The upgrade completed but the desktop never sent e2ee_ready before the + // phone was suspended — the classic wedged relay/Tailscale half-open. + latest().open() + expect(client.getState()).toBe('handshaking') + const wedged = latest() + + suspend(120_000) + client.notifyForeground() + + expect(latest()).not.toBe(wedged) + latest().authenticate() + expect(client.getState()).toBe('connected') + + client.close() + }) +}) diff --git a/mobile/src/transport/mobile-direct-return-probe.ts b/mobile/src/transport/mobile-direct-return-probe.ts new file mode 100644 index 00000000000..dfb0572aa38 --- /dev/null +++ b/mobile/src/transport/mobile-direct-return-probe.ts @@ -0,0 +1,83 @@ +import { openAuthenticatedDirectEndpoint } from './mobile-direct-endpoint-probe' +import type { MobileEndpointHysteresis } from './mobile-endpoint-hysteresis' +import type { RpcClient } from './rpc-client' +import type { HostProfile } from './types' +import type { MobileConnectionPath } from './stable-logical-rpc-client' + +const DIRECT_PROBE_INTERVAL_MS = 15_000 + +// While the runtime channel rides the relay, periodically probe the direct +// endpoint and migrate back once hysteresis proves it stable. +export class DirectReturnProbe { + private timer: ReturnType | null = null + + constructor( + private readonly deps: { + now: () => number + setTimer: typeof setTimeout + clearTimer: typeof clearTimeout + openDirect: (endpoint: string) => RpcClient + }, + private readonly hooks: { + hysteresis: MobileEndpointHysteresis + host: () => HostProfile + canSchedule: () => boolean + canAttempt: () => boolean + beginOperation: () => void + migrate: (client: RpcClient, path: MobileConnectionPath) => Promise + onDirectMigrated: () => Promise + afterProbe: () => void + } + ) {} + + schedule(delayMs = DIRECT_PROBE_INTERVAL_MS): void { + if (!this.hooks.canSchedule() || this.timer) { + return + } + this.timer = this.deps.setTimer(() => { + this.timer = null + void this.probe() + }, delayMs) + } + + clear(): void { + if (this.timer) { + this.deps.clearTimer(this.timer) + this.timer = null + } + } + + private async probe(): Promise { + if (!this.hooks.canAttempt() || !this.hooks.hysteresis.canProbe(this.deps.now())) { + this.schedule() + return + } + this.hooks.beginOperation() + let successful: Awaited> = null + try { + successful = await openAuthenticatedDirectEndpoint( + this.hooks.host(), + this.deps.openDirect, + 12_000 + ) + if (!successful) { + this.hooks.hysteresis.recordDirectFailure(this.deps.now()) + return + } + if (!this.hooks.hysteresis.recordDirectSuccess(this.deps.now())) { + successful.client.close() + return + } + await this.hooks.migrate(successful.client, successful.path) + successful = null + this.hooks.hysteresis.recordMigration(this.deps.now()) + await this.hooks.onDirectMigrated() + } finally { + successful?.client.close() + // Why: a relay drop or backoff timer can arrive while the probe owns the + // operation mutex; afterProbe releases it and replays deferred recovery. + this.hooks.afterProbe() + this.schedule() + } + } +} diff --git a/mobile/src/transport/mobile-endpoint-lifecycle.ts b/mobile/src/transport/mobile-endpoint-lifecycle.ts index 57881022a56..d41898152c3 100644 --- a/mobile/src/transport/mobile-endpoint-lifecycle.ts +++ b/mobile/src/transport/mobile-endpoint-lifecycle.ts @@ -90,6 +90,7 @@ function createSupervisor( readBundle: readMobileRelayCredentialBundle, writeBundle: writeMobileRelayCredentialBundle, saveHost, + onLog, now: Date.now, randomBytes: ExpoCrypto.getRandomBytes, setTimer: setTimeout, diff --git a/mobile/src/transport/mobile-endpoint-supervisor-contract.ts b/mobile/src/transport/mobile-endpoint-supervisor-contract.ts index d26e0706f70..0098de6e079 100644 --- a/mobile/src/transport/mobile-endpoint-supervisor-contract.ts +++ b/mobile/src/transport/mobile-endpoint-supervisor-contract.ts @@ -3,7 +3,7 @@ import type { MobileRelayCredentialBundle } from './mobile-relay-credential-bund import type { MobileRelayRpcSession } from './mobile-relay-rpc-session' import type { resolveMobileRelayEndpoint } from './mobile-relay-resume-director' import type { RpcClient } from './rpc-client' -import type { HostProfile } from './types' +import type { ConnectionLogSink, HostProfile } from './types' export type MobileEndpointSupervisorDependencies = { openDirect: (endpoint: string) => RpcClient @@ -20,4 +20,5 @@ export type MobileEndpointSupervisorDependencies = { randomBytes: (length: number) => Uint8Array setTimer: typeof setTimeout clearTimer: typeof clearTimeout + onLog?: ConnectionLogSink } diff --git a/mobile/src/transport/mobile-endpoint-supervisor.test.ts b/mobile/src/transport/mobile-endpoint-supervisor.test.ts index 3ec05f5ef1e..e6d0ff8bb32 100644 --- a/mobile/src/transport/mobile-endpoint-supervisor.test.ts +++ b/mobile/src/transport/mobile-endpoint-supervisor.test.ts @@ -52,18 +52,21 @@ class FakeRelaySession extends FakeSession implements MobileRelayRpcSession { constructor( state: ConnectionState, private readonly failure: Error | null = null, - private readonly lease = Date.now() + 120_000 + private readonly resumeExpiry = Date.now() + 30 * 24 * 3_600_000 ) { super(state) } - getLeaseExpiresAt = () => this.lease + // Why: production-realistic defaults — fictional fake values hid three + // live defects in this subsystem (latch, churn, int32 timer overflow). + getAttachDeadlineAt = () => Date.now() + 10_000 + getResumeExpiresAt = () => this.resumeExpiry getResumeConfirmation = () => ({ v: 1 as const, reqId: 'confirm-1', currentVersion: 2, acceptedAs: 'current' as const, renewed: true, - resumeExpiresAt: Date.now() + 300_000 + resumeExpiresAt: this.resumeExpiry }) getFailure = () => this.failure } @@ -716,6 +719,7 @@ describe('mobile endpoint supervisor', () => { .mockReturnValueOnce(new FakeRelaySession('disconnected', new RelayOuterError(4408))) const deps = dependencies({ openRelay, + openDirect: vi.fn(() => new FakeSession('disconnected')), resolveRelay: vi.fn(() => resolvePending) }) const supervisor = new MobileEndpointSupervisor(logical, host, deps) @@ -744,12 +748,13 @@ describe('mobile endpoint supervisor', () => { .mockReturnValueOnce(new FakeRelaySession('disconnected', new RelayOuterError(4408))) const deps = dependencies({ openRelay, + openDirect: vi.fn(() => new FakeSession('disconnected')), resolveRelay: vi.fn(() => resolvePending) }) const supervisor = new MobileEndpointSupervisor(logical, host, deps) await supervisor.start() - await vi.advanceTimersByTimeAsync(1000) + await vi.advanceTimersByTimeAsync(60_000) await vi.waitFor(() => expect(deps.resolveRelay).toHaveBeenCalledOnce()) supervisor.setForeground(false) finishResolve?.(relay) @@ -785,11 +790,14 @@ describe('mobile endpoint supervisor', () => { .fn() .mockReturnValueOnce(new FakeRelaySession('connected', null, Date.now() + 31_000)) .mockImplementation(() => new FakeRelaySession('disconnected', new RelayOuterError(4404))) - const deps = dependencies({ openRelay }) + const deps = dependencies({ + openRelay, + openDirect: vi.fn(() => new FakeSession('disconnected')) + }) const supervisor = new MobileEndpointSupervisor(logical, host, deps) await supervisor.start() - await vi.advanceTimersByTimeAsync(1000) + await vi.advanceTimersByTimeAsync(60_000) expect(openRelay).toHaveBeenCalledTimes(2) await vi.advanceTimersByTimeAsync(5000) @@ -808,12 +816,13 @@ describe('mobile endpoint supervisor', () => { .mockImplementation(() => new FakeRelaySession('connected')) const deps = dependencies({ openRelay, + openDirect: vi.fn(() => new FakeSession('disconnected')), randomBytes: () => new Uint8Array([128, 0]) }) const supervisor = new MobileEndpointSupervisor(logical, host, deps) await supervisor.start() - await vi.advanceTimersByTimeAsync(1000) + await vi.advanceTimersByTimeAsync(60_000) expect(openRelay).toHaveBeenCalledTimes(2) // The old relay can outlive its rejected lease replacement, then close separately. @@ -833,12 +842,13 @@ describe('mobile endpoint supervisor', () => { .mockImplementation(() => new FakeRelaySession('connected')) const deps = dependencies({ openRelay, + openDirect: vi.fn(() => new FakeSession('disconnected')), randomBytes: () => new Uint8Array([128, 0]) }) const supervisor = new MobileEndpointSupervisor(logical, host, deps) await supervisor.start() - await vi.advanceTimersByTimeAsync(1000) + await vi.advanceTimersByTimeAsync(60_000) expect(openRelay).toHaveBeenCalledTimes(2) supervisor.setForeground(true) diff --git a/mobile/src/transport/mobile-endpoint-supervisor.ts b/mobile/src/transport/mobile-endpoint-supervisor.ts index c8b3cdbcfb1..77ffbbde3db 100644 --- a/mobile/src/transport/mobile-endpoint-supervisor.ts +++ b/mobile/src/transport/mobile-endpoint-supervisor.ts @@ -1,5 +1,5 @@ -import { openAuthenticatedDirectEndpoint } from './mobile-direct-endpoint-probe' import type { MobileEndpointSupervisorDependencies } from './mobile-endpoint-supervisor-contract' +import { DirectReturnProbe } from './mobile-direct-return-probe' import { RelayReconnectController } from './mobile-relay-reconnect-controller' import { RelayLeaseRotationTimer } from './mobile-relay-lease-rotation-timer' import { MobileEndpointHysteresis } from './mobile-endpoint-hysteresis' @@ -9,6 +9,8 @@ import { persistRelayHost, toError } from './mobile-endpoint-supervisor-support' +import { selectDialableRelayCredentials } from './mobile-relay-credential-selection' +import { createRelayRecoveryLog, type RelayRecoveryLog } from './mobile-relay-recovery-log' import { applyResumeConfirmation, mobileRelayCredentialNeedsRotation, @@ -20,7 +22,6 @@ import type { HostProfile } from './types' export type { MobileEndpointSupervisorDependencies } from './mobile-endpoint-supervisor-contract' -const DIRECT_PROBE_INTERVAL_MS = 15_000 const DIRECT_OBSERVATION_MS = 30_000 const MINIMUM_DWELL_MS = 60_000 const FAILURE_COOLDOWN_MS = 60_000 @@ -32,11 +33,12 @@ export class MobileEndpointSupervisor { private operationInFlight = false private credentialRotationInFlight = false private relayRotationPending = false - private probeTimer: ReturnType | null = null private unsubscribeState: (() => void) | null = null private readonly hysteresis: MobileEndpointHysteresis private readonly relayReconnect: RelayReconnectController private readonly leaseRotation: RelayLeaseRotationTimer + private readonly logRelay: RelayRecoveryLog + private readonly directProbe: DirectReturnProbe constructor( private readonly logical: StableLogicalRpcClient, @@ -49,24 +51,52 @@ export class MobileEndpointSupervisor { failureCooldownMs: FAILURE_COOLDOWN_MS, minimumDwellMs: MINIMUM_DWELL_MS }) + this.logRelay = createRelayRecoveryLog(dependencies.now, dependencies.onLog) this.relayReconnect = new RelayReconnectController(dependencies, this.recoverRelay.bind(this)) this.leaseRotation = new RelayLeaseRotationTimer(dependencies, () => { this.relayRotationPending = true void this.recoverRelay(true) }) + this.directProbe = new DirectReturnProbe(dependencies, { + hysteresis: this.hysteresis, + host: () => this.host, + canSchedule: () => + !this.stopped && this.foreground && this.logical.getActivePath() === 'relay', + canAttempt: () => !this.stopped && this.foreground && !this.operationInFlight, + beginOperation: () => { + this.operationInFlight = true + }, + migrate: (client, path) => this.logical.migrateTo(client, path), + onDirectMigrated: async () => { + this.leaseRotation.clear() + this.relayRotationPending = false + await this.rotateCredentialIfNeeded(this.relayReconnect.resetForDirectConnection()) + }, + afterProbe: () => { + this.operationInFlight = false + if (this.relayRotationPending || this.logical.getState() !== 'connected') { + void this.recoverRelay(this.relayRotationPending) + } + } + }) } async start(): Promise { this.bundle = await this.dependencies.readBundle(this.host.id).catch(() => null) - if (this.stopped || !this.bundle || !this.host.relay) { + if (this.stopped || !this.host.relay) { return } + if (!this.bundle) { + // Why: a Keychain race at open must not kill relay recovery for the whole + // process lifetime; each recovery attempt re-reads the durable bundle. + this.logRelay('credential bundle unavailable at start; recovery will re-read') + } this.unsubscribeState = this.logical.onStateChange((state) => { if (state === 'connected') { if (this.logical.getActivePath() !== 'relay') { void this.rotateCredentialIfNeeded(this.relayReconnect.resetForDirectConnection()) } - this.scheduleDirectProbe() + this.directProbe.schedule() } else { // Why: the direct client enters reconnecting after its first failed // dial and may never publish disconnected while its retry loop lives. @@ -78,7 +108,7 @@ export class MobileEndpointSupervisor { // are still loading, before the supervisor subscribes to state changes. await this.recoverRelay() } else { - this.scheduleDirectProbe() + this.directProbe.schedule() } } @@ -87,11 +117,11 @@ export class MobileEndpointSupervisor { this.foreground = foreground if (foreground) { this.relayReconnect.handleForeground(this.logical, wasForeground) - this.scheduleDirectProbe(0) + this.directProbe.schedule(0) } else { // Why: background phones must not hold billed relay data splices. this.relayReconnect.suspendActiveRelay(this.logical) - this.clearDirectProbeTimer() + this.directProbe.clear() this.relayReconnect.clear() this.leaseRotation.clear() } @@ -101,7 +131,7 @@ export class MobileEndpointSupervisor { this.stopped = true this.unsubscribeState?.() this.unsubscribeState = null - this.clearDirectProbeTimer() + this.directProbe.clear() this.relayReconnect.clear() this.leaseRotation.clear() } @@ -112,7 +142,6 @@ export class MobileEndpointSupervisor { this.stopped || !this.foreground || this.operationInFlight || - !this.bundle || !this.host.relay || (!forceReplacement && !this.relayReconnect.needsRecovery(this.logical.getState())) ) { @@ -121,23 +150,42 @@ export class MobileEndpointSupervisor { // Why: revival and lease timers can overlap resume failures; one shared cooldown // prevents PEER_DROPPED/LIMIT_EXCEEDED reconnect churn. if (this.relayReconnect.shouldDefer()) { + this.logRelay('recovery deferred by cooldown or gate') return } this.operationInFlight = true let lastError: Error | null = null let retryAfterOperation = false try { - const credentials = this.relayReconnect.eligibleCredentials( - this.bundle.current, - this.bundle.grace - ) - for (const credential of credentials) { + const selection = await selectDialableRelayCredentials({ + bundle: this.bundle, + controller: this.relayReconnect, + readBundle: () => this.dependencies.readBundle(this.host.id), + onAdoptedFresherBundle: () => this.logRelay('adopted fresher durable credential bundle') + }) + this.bundle = selection.bundle + if (selection.credentials.length === 0) { + // Why: "expired" vs "missing" separates a sleep-past-expiry phone + // (needs re-pair or LAN) from a Keychain failure in field reports. + this.logRelay( + selection.bundle + ? 'relay credential expired or rejected; slow reprobe armed' + : 'no relay credential bundle; slow reprobe armed' + ) + this.relayReconnect.armCredentialReprobe() + return + } + for (const credential of selection.credentials) { const result = await this.tryRelayCredential(credential) if (result.ok) { retryAfterOperation = this.logical.getState() !== 'connected' return } lastError = result.error + this.logRelay( + 'relay dial failed', + `${result.error.name}: ${String(result.error.message).slice(0, 80)}` + ) if (this.relayReconnect.shouldTryGraceAfterRelayFailure(result.error)) { // Why: a rejected version stays invalid; retry only the grace credential. this.relayReconnect.recordRejectedCredential(credential.version) @@ -145,12 +193,10 @@ export class MobileEndpointSupervisor { break } } - if (credentials.length > 0) { - // Why: cleanup may happen while a relay dial is awaiting the network; - // record its outcome without recreating a foreground retry timer. - const scheduleRetry = !forceReplacement && this.foreground && !this.stopped - this.relayReconnect.registerFailure(lastError, scheduleRetry) - } + // Why: cleanup may happen while a relay dial is awaiting the network; + // record its outcome without recreating a foreground retry timer. + const scheduleRetry = !forceReplacement && this.foreground && !this.stopped + this.relayReconnect.registerFailure(lastError, scheduleRetry) } finally { this.operationInFlight = false if (forceReplacement && this.relayRotationPending && !this.stopped && this.foreground) { @@ -207,6 +253,7 @@ export class MobileEndpointSupervisor { } this.relayRotationPending = false this.hysteresis.recordMigration(this.dependencies.now()) + this.logRelay('runtime channel migrated to relay') const confirmation = session.getResumeConfirmation() if (confirmation) { this.bundle = applyResumeConfirmation(this.bundle, credential.version, confirmation) @@ -215,71 +262,21 @@ export class MobileEndpointSupervisor { await this.dependencies.writeBundle(this.bundle).catch(() => {}) } // Why: async persistence can finish after stop/background; never recreate a stale timer. + // Why: rotate against the resume credential's expiry, never the hello's + // leaseExpiresAt — that field is the cell's ~10s attach-reservation + // deadline, and using it forced a session replacement every second. this.leaseRotation.scheduleFromLease( - this.stopped || !this.foreground ? null : session.getLeaseExpiresAt() + this.stopped || !this.foreground + ? null + : (confirmation?.resumeExpiresAt ?? session.getResumeExpiresAt()) ) - this.scheduleDirectProbe() + this.directProbe.schedule() return { ok: true } } catch (error) { return { ok: false, error: session.getFailure() ?? toError(error) } } } - private scheduleDirectProbe(delayMs = DIRECT_PROBE_INTERVAL_MS): void { - if ( - this.stopped || - !this.foreground || - this.logical.getActivePath() !== 'relay' || - this.probeTimer - ) { - return - } - this.probeTimer = this.dependencies.setTimer(() => { - this.probeTimer = null - void this.probeDirect() - }, delayMs) - } - - private async probeDirect(): Promise { - if ( - this.stopped || - !this.foreground || - this.operationInFlight || - !this.hysteresis.canProbe(this.dependencies.now()) - ) { - this.scheduleDirectProbe() - return - } - this.operationInFlight = true - let successful: Awaited> = null - try { - const openDirect = this.dependencies.openDirect - successful = await openAuthenticatedDirectEndpoint(this.host, openDirect, 12_000) - if (!successful) { - this.hysteresis.recordDirectFailure(this.dependencies.now()) - return - } - if (!this.hysteresis.recordDirectSuccess(this.dependencies.now())) { - successful.client.close() - return - } - await this.logical.migrateTo(successful.client, successful.path) - successful = null - this.hysteresis.recordMigration(this.dependencies.now()) - this.leaseRotation.clear() - this.relayRotationPending = false - await this.rotateCredentialIfNeeded(this.relayReconnect.resetForDirectConnection()) - } finally { - successful?.client.close() - this.operationInFlight = false - // Why: a relay drop or backoff timer can arrive while the direct probe owns the mutex. - if (this.relayRotationPending || this.logical.getState() !== 'connected') { - void this.recoverRelay(this.relayRotationPending) - } - this.scheduleDirectProbe() - } - } - private async rotateCredentialIfNeeded(force = false): Promise { if ( this.stopped || @@ -321,11 +318,4 @@ export class MobileEndpointSupervisor { } } } - - private clearDirectProbeTimer(): void { - if (this.probeTimer) { - this.dependencies.clearTimer(this.probeTimer) - this.probeTimer = null - } - } } diff --git a/mobile/src/transport/mobile-relay-credential-selection.ts b/mobile/src/transport/mobile-relay-credential-selection.ts new file mode 100644 index 00000000000..dcaca2080dd --- /dev/null +++ b/mobile/src/transport/mobile-relay-credential-selection.ts @@ -0,0 +1,42 @@ +import type { MobileRelayCredentialBundle } from './mobile-relay-credential-bundle' +import type { RelayReconnectController } from './mobile-relay-reconnect-controller' + +// Why: pairing recovery, re-pairing, or a raced rotation can land a fresh +// durable bundle after the supervisor snapshotted its copy; a gated retry must +// see it instead of dialing (or refusing to dial) on stale state forever. +// +// Adoption is decided by OUTCOME, not by version: renewals extend expiresAt +// without bumping current.version, and a re-pair restarts the version counter, +// so version comparison cannot tell fresh from stale. The durable bundle is +// adopted exactly when it yields a dialable (unexpired, non-rejected) +// credential while the in-memory one does not — which also means a revoked +// version can never be resurrected from a stale disk copy. +export async function selectDialableRelayCredentials(args: { + bundle: MobileRelayCredentialBundle | null + controller: RelayReconnectController + readBundle: () => Promise + onAdoptedFresherBundle: () => void +}): Promise<{ + bundle: MobileRelayCredentialBundle | null + credentials: MobileRelayCredentialBundle['current'][] +}> { + const memory = args.bundle + const memoryCredentials = memory + ? args.controller.eligibleCredentials(memory.current, memory.grace) + : [] + if (memoryCredentials.length > 0) { + // Why: in-memory can be newer than disk (a resume confirmation whose + // durable write failed); never let a stale disk copy shadow it. + return { bundle: memory, credentials: memoryCredentials } + } + const disk = await args.readBundle().catch(() => null) + if (disk) { + const diskCredentials = args.controller.eligibleCredentials(disk.current, disk.grace) + if (diskCredentials.length > 0) { + args.controller.acceptFreshCredential(disk.current.version) + args.onAdoptedFresherBundle() + return { bundle: disk, credentials: diskCredentials } + } + } + return { bundle: memory ?? disk, credentials: [] } +} diff --git a/mobile/src/transport/mobile-relay-lease-rotation-timer.ts b/mobile/src/transport/mobile-relay-lease-rotation-timer.ts index bf2a3dd4d1c..19aedfe8be1 100644 --- a/mobile/src/transport/mobile-relay-lease-rotation-timer.ts +++ b/mobile/src/transport/mobile-relay-lease-rotation-timer.ts @@ -2,6 +2,13 @@ // little before the deadline (and retry shortly if a forced rotation didn't land) // so the session never lapses. Owns the single lease/rotation timer slot. const LEASE_ROTATION_MARGIN_MS = 30_000 +// Why: both ends must be clamped. The floor bounds any bad deadline to one +// forced rotation per minute instead of a sub-second loop; the ceiling keeps +// the delay far below setTimeout's 32-bit limit (a 30-day resume TTL minus the +// margin overflows int32 and fires at 1ms), at the cost of a harmless +// re-resume every few hours on long-lived sessions. +const LEASE_ROTATION_MIN_DELAY_MS = 60_000 +const LEASE_ROTATION_MAX_DELAY_MS = 6 * 60 * 60 * 1000 export type RelayLeaseRotationDependencies = { now: () => number @@ -23,9 +30,12 @@ export class RelayLeaseRotationTimer { if (!leaseExpiresAt) { return } - const delay = Math.max( - 1000, - leaseExpiresAt - this.dependencies.now() - LEASE_ROTATION_MARGIN_MS + const delay = Math.min( + LEASE_ROTATION_MAX_DELAY_MS, + Math.max( + LEASE_ROTATION_MIN_DELAY_MS, + leaseExpiresAt - this.dependencies.now() - LEASE_ROTATION_MARGIN_MS + ) ) this.arm(delay) } diff --git a/mobile/src/transport/mobile-relay-reconnect-controller.test.ts b/mobile/src/transport/mobile-relay-reconnect-controller.test.ts index d630f0db68b..cc640d4d7e7 100644 --- a/mobile/src/transport/mobile-relay-reconnect-controller.test.ts +++ b/mobile/src/transport/mobile-relay-reconnect-controller.test.ts @@ -6,7 +6,9 @@ import { RelayReconnectController } from './mobile-relay-reconnect-controller' import type { StableLogicalRpcClient } from './stable-logical-rpc-client' vi.mock('react-native', () => ({ Platform: { OS: 'ios' } })) -vi.mock('expo-crypto', () => ({ getRandomBytes: (length: number) => new Uint8Array(length) })) +vi.mock('expo-crypto', () => ({ + getRandomBytes: (length: number) => new Uint8Array(length) +})) describe('relay reconnect controller', () => { beforeEach(() => { @@ -47,16 +49,104 @@ describe('relay reconnect controller', () => { expect(onRetry).not.toHaveBeenCalled() }) - it('waits for an external signal after rejected E2EE authentication', () => { + it('reprobes slowly after rejected E2EE authentication instead of parking forever', () => { + // Why: on a relay-only phone a permanent gate is a permanent outage — the + // desktop can commit pairing credentials moments after the first rejection. const onRetry = vi.fn() const reconnect = createController(onRetry) reconnect.registerFailure(new MobileE2EEAuthenticationError()) expect(reconnect.shouldDefer()).toBe(true) - expect(vi.getTimerCount()).toBe(0) - vi.advanceTimersByTime(60_000) expect(onRetry).not.toHaveBeenCalled() + vi.advanceTimersByTime(59_000) + expect(onRetry).not.toHaveBeenCalled() + vi.advanceTimersByTime(1_000) + expect(onRetry).toHaveBeenCalledTimes(1) + // The reprobe tick passes the gate exactly once, then defers again. + expect(reconnect.shouldDefer()).toBe(false) + expect(reconnect.shouldDefer()).toBe(true) + }) + + it('keeps the fresh-credential gate reprobing after each failed gated attempt', () => { + const onRetry = vi.fn() + const reconnect = createController(onRetry) + + reconnect.registerFailure(new RelayOuterError(4401)) + expect(reconnect.shouldDefer()).toBe(true) + + vi.advanceTimersByTime(60_000) + expect(onRetry).toHaveBeenCalledTimes(1) + expect(reconnect.shouldDefer()).toBe(false) + // The gated attempt fails again with only rejected credentials on hand. + reconnect.registerFailure(new RelayOuterError(4401)) + + // The gated cadence escalates: the second reprobe waits twice as long. + vi.advanceTimersByTime(60_000) + expect(onRetry).toHaveBeenCalledTimes(1) + vi.advanceTimersByTime(60_000) + expect(onRetry).toHaveBeenCalledTimes(2) + }) + + it('resets the gated cadence when the app returns to the foreground', () => { + // Why: reopening the app is the strongest "conditions changed" signal a + // phone produces — it must not wait out an escalated 15-minute tick even + // when it cannot lift the credential gate itself. + const onRetry = vi.fn() + const reconnect = createController(onRetry) + const logical = { getState: () => 'disconnected' } as never + + reconnect.registerFailure(new RelayOuterError(4401)) + vi.advanceTimersByTime(60_000) + expect(onRetry).toHaveBeenCalledTimes(1) + // A failed gated attempt escalates the next tick beyond the base cadence. + reconnect.registerFailure(new RelayOuterError(4401)) + + reconnect.clear() + reconnect.handleForeground(logical, false) + expect(onRetry).toHaveBeenCalledTimes(2) + + expect(reconnect.shouldDefer()).toBe(true) + vi.advanceTimersByTime(60_000) + expect(onRetry).toHaveBeenCalledTimes(3) + }) + + it('does not let an orphaned reprobe timer swallow the next fast backoff', () => { + const onRetry = vi.fn() + const reconnect = createController(onRetry) + const logical = { getState: () => 'disconnected' } as never + + reconnect.registerFailure(new MobileE2EEAuthenticationError()) + // A foreground revival nudge clears the external-signal gate and its timer. + reconnect.handleForeground(logical, true) + expect(onRetry).toHaveBeenCalledTimes(1) + + // A plain transport failure must schedule its own fast retry, not wait + // out a leftover 60s reprobe timer. + reconnect.registerFailure(new RelayOuterError(4429)) + vi.advanceTimersByTime(600) + expect(onRetry).toHaveBeenCalledTimes(2) + }) + + it('lifts the fresh-credential gate when a durable bundle carries a new version', () => { + const onRetry = vi.fn() + const reconnect = createController(onRetry) + + reconnect.recordRejectedCredential(2) + reconnect.armCredentialReprobe() + expect(reconnect.shouldDefer()).toBe(true) + + reconnect.acceptFreshCredential(2) + expect(reconnect.shouldDefer()).toBe(true) + + reconnect.acceptFreshCredential(3) + expect(reconnect.shouldDefer()).toBe(false) + expect( + reconnect.eligibleCredentials( + { token: 'fresh', version: 3, expiresAt: Number.MAX_SAFE_INTEGER }, + null + ) + ).toHaveLength(1) }) it('upgrades host-revival gating to fresh credentials without later downgrading it', () => { diff --git a/mobile/src/transport/mobile-relay-reconnect-controller.ts b/mobile/src/transport/mobile-relay-reconnect-controller.ts index 6f586c17499..f2a7cad6b05 100644 --- a/mobile/src/transport/mobile-relay-reconnect-controller.ts +++ b/mobile/src/transport/mobile-relay-reconnect-controller.ts @@ -17,6 +17,12 @@ const RELAY_BACKOFF_CEILING_MS = 30_000 const RELAY_STABLE_CONNECTION_MS = RELAY_BACKOFF_CEILING_MS const RELAY_HOST_OFFLINE_RETRY_MIN_MS = 5_000 const RELAY_HOST_OFFLINE_RETRY_MAX_MS = 15_000 +// Why: gates must slow recovery down, never end it — a relay-only phone has no +// direct path to refresh credentials, so a timerless gate is a permanent outage. +// The cadence escalates and jitters so a permanently revoked device is not a +// forever one-minute beacon and a fleet-wide gating event cannot phase-align. +const RELAY_GATE_REPROBE_BASE_MS = 60_000 +const RELAY_GATE_REPROBE_CEILING_MS = 15 * 60_000 export type RelayReconnectDependencies = { now: () => number @@ -34,6 +40,8 @@ export class RelayReconnectController { private timer: ReturnType | null = null private activeSession: MobileRelayRpcSession | null = null private recoveryGate: RecoveryGate | null = null + private gateReprobePending = false + private gateReprobeStreak = 0 private readonly rejectedCredentialVersions = new Set() constructor( @@ -43,12 +51,15 @@ export class RelayReconnectController { handleForeground(logical: StableLogicalRpcClient, wasForeground: boolean): void { if (!wasForeground) { - // Why: an app resume is a fresh signal, unlike repeated network-flap nudges. + // Why: an app resume is a fresh signal, unlike repeated network-flap + // nudges — it resets the gated cadence even when it cannot lift the + // credential gate, so reopening the app never waits out a 15min tick. + this.gateReprobeStreak = 0 if (this.recoveryGate !== 'fresh-credential') { this.reset() } } else if (this.recoveryGate === 'external-signal') { - this.recoveryGate = null + this.liftGate() } if ( wasForeground && @@ -87,8 +98,7 @@ export class RelayReconnectController { this.activeSession = session this.activeRelayConnectedAt = this.dependencies.now() this.nextAttemptAt = 0 - this.recoveryGate = null - this.clearTimer() + this.liftGate() } resetForDirectConnection(): boolean { @@ -97,10 +107,14 @@ export class RelayReconnectController { this.activeSession = null this.activeRelayConnectedAt = null if (needsCredentialRefresh) { - // Why: the rejected credential stays unusable until its replacement is durable. + // Why: the rejected credential stays unusable until its replacement is + // durable. No reprobe timer here — direct is live, rotation over it + // clears the gate, and any later state failure re-arms via shouldDefer. this.consecutiveFailures = 0 this.nextAttemptAt = 0 this.recoveryGate = 'fresh-credential' + this.gateReprobePending = false + this.gateReprobeStreak = 0 this.clearTimer() } else { this.reset() @@ -128,10 +142,36 @@ export class RelayReconnectController { if (eligible.length === 0 && this.rejectedCredentialVersions.size > 0) { this.recoveryGate = 'fresh-credential' this.clearTimer() + this.scheduleGateReprobe() } return eligible } + // For callers that found no dialable credential at all: keep a slow retry + // alive so a later durable write can recover. + armCredentialReprobe(): void { + if (this.rejectedCredentialVersions.size > 0) { + this.recoveryGate = 'fresh-credential' + this.clearTimer() + this.scheduleGateReprobe() + return + } + // Why: a merely missing or expired bundle must not enter the credential + // gate — that gate forces a rotation on the next direct connect. A plain + // cooldown retries the read on the same escalating cadence. + const delay = this.gateReprobeDelayMs() + this.nextAttemptAt = this.dependencies.now() + delay + this.clearTimer() + this.scheduleReprobeTick(delay, false) + } + + // A durable bundle whose current version is not rejected reopens the gate. + acceptFreshCredential(version: number): void { + if (this.recoveryGate === 'fresh-credential' && !this.rejectedCredentialVersions.has(version)) { + this.liftGate() + } + } + recordRejectedCredential(version: number): void { this.rejectedCredentialVersions.add(version) } @@ -154,6 +194,12 @@ export class RelayReconnectController { // re-dial. Arms the self-scheduled retry so recovery still happens on its own. shouldDefer(): boolean { if (this.recoveryGate) { + if (this.gateReprobePending) { + // Why: the slow reprobe tick gets exactly one attempt through the gate. + this.gateReprobePending = false + return false + } + this.scheduleGateReprobe() return true } if (this.dependencies.now() < this.nextAttemptAt) { @@ -173,8 +219,9 @@ export class RelayReconnectController { this.recoveryGate === 'fresh-credential' || (this.recoveryGate === 'external-signal' && recovery?.kind !== 'disable-relay-credential') ) { - // Why: only the gate's external signal can make a known-fatal recovery retryable. + // Why: a failed reprobe stays gated, but the slow cadence must keep going. this.clearTimer() + this.scheduleGateReprobe() return } const now = this.dependencies.now() @@ -192,15 +239,20 @@ export class RelayReconnectController { recovery?.kind === 'retry-after-host-offline' ? this.hostOfflineDelayMs() : this.delayMs() this.nextAttemptAt = now + delay if (error instanceof MobileE2EEAuthenticationError) { - // Why: pairing state cannot change on a timer; polling only wakes the radio. + // Why: an E2EE rejection is usually pairing revocation, but it also fires + // transiently right after pairing while the desktop commits credentials — + // reprobe slowly instead of waiting forever for a UI nudge. this.recoveryGate = 'external-signal' this.clearTimer() + this.scheduleGateReprobe() return } if (recovery?.kind === 'disable-relay-credential') { - // Why: a rejected outer credential cannot recover until direct connectivity refreshes it. + // Why: never redial a rejected credential fast, but keep a slow reprobe + // alive — the caller re-reads durable state before each gated attempt. this.recoveryGate = 'fresh-credential' this.clearTimer() + this.scheduleGateReprobe() return } if (recovery?.kind === 'retry-after-host-offline') { @@ -235,12 +287,12 @@ export class RelayReconnectController { this.consecutiveFailures = 0 this.activeRelayConnectedAt = null this.nextAttemptAt = 0 - this.recoveryGate = null - this.clearTimer() + this.liftGate() } clear(): void { this.clearTimer() + this.gateReprobePending = false this.activeSession = null this.activeRelayConnectedAt = null } @@ -263,6 +315,45 @@ export class RelayReconnectController { }, delay) } + private scheduleGateReprobe(): void { + this.scheduleReprobeTick(this.gateReprobeDelayMs(), true) + } + + private scheduleReprobeTick(delay: number, mintToken: boolean): void { + if (this.timer) { + return + } + this.timer = this.dependencies.setTimer(() => { + this.timer = null + // Why: the streak advances once per fired tick — arm attempts within one + // cycle recompute the same delay instead of triple-escalating it. + this.gateReprobeStreak = Math.min(this.gateReprobeStreak + 1, 8) + // Why: the tick token is only minted while its gate still holds; a later + // gate must not spend a stale token and bypass its own cooldown. + if (mintToken && this.recoveryGate) { + this.gateReprobePending = true + } + this.onRetry() + }, delay) + } + + private gateReprobeDelayMs(): number { + const base = Math.min( + RELAY_GATE_REPROBE_CEILING_MS, + RELAY_GATE_REPROBE_BASE_MS * 2 ** Math.min(this.gateReprobeStreak, 8) + ) + return Math.floor(base * (0.75 + 0.5 * this.jitterFraction())) + } + + // Why: clearing a gate must also drop its timer, pending tick, and cadence — + // an orphaned reprobe timer would otherwise swallow the next fast backoff. + private liftGate(): void { + this.recoveryGate = null + this.gateReprobePending = false + this.gateReprobeStreak = 0 + this.clearTimer() + } + private delayMs(): number { const exponent = Math.max(0, this.consecutiveFailures - 1) const cap = Math.min(RELAY_BACKOFF_CEILING_MS, RELAY_BACKOFF_BASE_MS * 2 ** exponent) diff --git a/mobile/src/transport/mobile-relay-recovery-log.ts b/mobile/src/transport/mobile-relay-recovery-log.ts new file mode 100644 index 00000000000..9b373cd112a --- /dev/null +++ b/mobile/src/transport/mobile-relay-recovery-log.ts @@ -0,0 +1,22 @@ +import type { ConnectionLogSink } from './types' + +export type RelayRecoveryLog = (message: string, detail?: string) => void + +// Why: relay recovery failed silently in production for weeks; every decision +// must reach logcat and the in-app connection log. +export function createRelayRecoveryLog( + now: () => number, + onLog?: ConnectionLogSink +): RelayRecoveryLog { + let sequence = 0 + return (message, detail) => { + console.log(`[relay] ${message}`, detail ?? '') + onLog?.({ + id: `relay-${++sequence}`, + ts: now(), + level: 'info', + message: `Relay: ${message}`, + ...(detail ? { detail } : {}) + }) + } +} diff --git a/mobile/src/transport/mobile-relay-rpc-session.test.ts b/mobile/src/transport/mobile-relay-rpc-session.test.ts index 54ae8387411..f5fa49a785e 100644 --- a/mobile/src/transport/mobile-relay-rpc-session.test.ts +++ b/mobile/src/transport/mobile-relay-rpc-session.test.ts @@ -119,7 +119,7 @@ describe('mobile relay RPC session', () => { }) expect(confirmationRequest.params).not.toHaveProperty('relayDeviceId') expect(confirmationRequest.params).not.toHaveProperty('acceptedCredentialVersion') - expect(session.getLeaseExpiresAt()).toEqual(expect.any(Number)) + expect(session.getAttachDeadlineAt()).toEqual(expect.any(Number)) }) it('rejects a mismatched outer credential version and closes the physical link', () => { diff --git a/mobile/src/transport/mobile-relay-rpc-session.ts b/mobile/src/transport/mobile-relay-rpc-session.ts index a614e833387..ac065012203 100644 --- a/mobile/src/transport/mobile-relay-rpc-session.ts +++ b/mobile/src/transport/mobile-relay-rpc-session.ts @@ -19,7 +19,10 @@ type PendingRequest = { } export type MobileRelayRpcSession = RpcClient & { - getLeaseExpiresAt(): number | null + // The cell's attach-reservation deadline (~10s). Diagnostics only — never + // schedule anything from it; rotation keys off getResumeExpiresAt(). + getAttachDeadlineAt(): number | null + getResumeExpiresAt(): number | null getResumeConfirmation(): DeviceResumeConfirmed | null getFailure(): Error | null } @@ -40,7 +43,8 @@ export function connectMobileRelayRpcSession(args: { let state: ConnectionState = 'connecting' let requestCounter = 0 let lastConnectedAt: number | null = null - let leaseExpiresAt: number | null = null + let attachDeadlineAt: number | null = null + let resumeExpiresAt: number | null = null let resumeConfirmation: DeviceResumeConfirmed | null = null let failure: Error | null = null let closed = false @@ -65,7 +69,8 @@ export function connectMobileRelayRpcSession(args: { fail(new Error('relay resume credential version mismatch')) return } - leaseExpiresAt = hello.leaseExpiresAt + attachDeadlineAt = hello.leaseExpiresAt + resumeExpiresAt = hello.resumeExpiresAt publishState('handshaking') }, onAuthenticated: () => void confirmResume(), @@ -109,7 +114,8 @@ export function connectMobileRelayRpcSession(args: { streams.clear() publishState('disconnected') }, - getLeaseExpiresAt: () => leaseExpiresAt, + getAttachDeadlineAt: () => attachDeadlineAt, + getResumeExpiresAt: () => resumeExpiresAt, getResumeConfirmation: () => resumeConfirmation, getFailure: () => failure } @@ -131,6 +137,7 @@ export function connectMobileRelayRpcSession(args: { throw new Error('relay resume confirmation missing') } resumeConfirmation = result.resumeConfirmation + resumeExpiresAt = result.resumeConfirmation.resumeExpiresAt lastConnectedAt = Date.now() publishState('connected') } catch (error) { diff --git a/mobile/src/transport/mobile-relay-runtime-failover.test.ts b/mobile/src/transport/mobile-relay-runtime-failover.test.ts new file mode 100644 index 00000000000..dcb8ba194e2 --- /dev/null +++ b/mobile/src/transport/mobile-relay-runtime-failover.test.ts @@ -0,0 +1,454 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { connect, type RpcClient } from './rpc-client' +import { + createStableLogicalRpcClient, + type MobileConnectionPath, + type StableLogicalRpcClient +} from './stable-logical-rpc-client' +import { MobileE2EEAuthenticationError } from './mobile-e2ee-v2-physical-channel' +import { RelayOuterError } from './mobile-relay-e2ee-link' +import type { MobileRelayCredentialBundle } from './mobile-relay-credential-bundle' +import type { MobileRelayRpcSession } from './mobile-relay-rpc-session' +import { + MobileEndpointSupervisor, + type MobileEndpointSupervisorDependencies +} from './mobile-endpoint-supervisor' +import type { ConnectionState, HostProfile, RpcResponse } from './types' + +// Regression suite for the 2026-08 field failure: a phone paired over the +// relay whose direct LAN endpoint is unreachable (Tailscale off) dialed the +// LAN endpoint forever and never recovered a relay runtime session. + +vi.mock('react-native', () => ({ Platform: { OS: 'android' } })) +vi.mock('expo-secure-store', () => ({ + WHEN_UNLOCKED_THIS_DEVICE_ONLY: 'when-unlocked' +})) +vi.mock('expo-crypto', () => ({ + getRandomBytes: (length: number) => new Uint8Array(length) +})) + +vi.mock('./e2ee', () => ({ + generateKeyPair: () => ({ + publicKey: new Uint8Array(32), + secretKey: new Uint8Array(32) + }), + deriveSharedKey: () => new Uint8Array(32), + publicKeyFromBase64: () => new Uint8Array(32), + publicKeyToBase64: () => 'client-public-key', + encrypt: (plaintext: string) => plaintext, + decrypt: (raw: string) => raw, + decryptBytes: (bytes: Uint8Array) => bytes +})) + +class FakeSession implements RpcClient { + readonly sendRequest = vi.fn( + async (): Promise => ({ + id: 'rpc-1', + ok: true, + result: {}, + _meta: { runtimeId: 'runtime-1' } + }) + ) + readonly subscribe = vi.fn(() => () => {}) + readonly updateTerminalSubscriptionViewport = vi.fn() + readonly notifyForeground = vi.fn() + readonly close = vi.fn() + private readonly listeners = new Set<(state: ConnectionState) => void>() + + constructor(private state: ConnectionState) {} + + getState = () => this.state + getReconnectAttempt = () => 0 + getLastConnectedAt = () => null + onStateChange = (listener: (state: ConnectionState) => void) => { + this.listeners.add(listener) + return () => this.listeners.delete(listener) + } + + publishState(state: ConnectionState): void { + this.state = state + for (const listener of this.listeners) { + listener(state) + } + } +} + +class FakeRelaySession extends FakeSession implements MobileRelayRpcSession { + constructor( + state: ConnectionState, + private readonly failure: Error | null = null + ) { + super(state) + } + // Why: production-realistic constants — fictional fake values hid three + // live defects in this subsystem (latch, churn, int32 timer overflow). + getAttachDeadlineAt = () => Date.now() + 10_000 + getResumeExpiresAt = () => Date.now() + 30 * 24 * 3_600_000 + getResumeConfirmation = () => null + getFailure = () => this.failure +} + +class FakeLogicalClient extends FakeSession implements StableLogicalRpcClient { + private path: MobileConnectionPath + + constructor(state: ConnectionState, path: MobileConnectionPath) { + super(state) + this.path = path + } + + migrateTo = vi.fn(async (session: RpcClient, path: MobileConnectionPath) => { + if (session.getState() !== 'connected') { + session.close() + throw new Error(`replacement session ${session.getState()}`) + } + this.path = path + this.publishState('connected') + }) + suspendActiveSession = vi.fn(() => this.publishState('disconnected')) + getActivePath = () => this.path +} + +const relay = { + v: 1 as const, + directorUrl: 'https://relay.onorca.dev', + cellUrl: 'https://relay-c1.onorca.dev', + assignmentEpoch: 7, + relayHostId: 'AbCdEf0123_-xyZ9', + e2eeFraming: 2 as const +} + +const DIRECT_ENDPOINT = 'ws://100.88.90.25:6768' + +const host: HostProfile = { + id: 'host-1', + name: 'Blue Whale', + endpoint: DIRECT_ENDPOINT, + deviceToken: 'device-token', + publicKeyB64: 'A'.repeat(44), + lastConnected: 1, + endpoints: [ + { id: 'direct-primary', kind: 'lan', url: DIRECT_ENDPOINT }, + { + id: 'relay-primary', + kind: 'relay', + url: 'wss://relay-c1.onorca.dev/v1/connect/id' + } + ], + relayHostId: relay.relayHostId, + relay +} + +function bundleWith(version: number, expiresAt: number): MobileRelayCredentialBundle { + return { + v: 1, + hostId: host.id, + deviceToken: host.deviceToken, + current: { + token: `token-v${version}`.padEnd(43, 'A'), + hash: 'B'.repeat(43), + version, + expiresAt + } + } +} + +function dependencies( + overrides: Partial = {} +): MobileEndpointSupervisorDependencies { + return { + openDirect: vi.fn(() => new FakeSession('connected')), + openRelay: vi.fn(() => new FakeRelaySession('connected')), + resolveRelay: vi.fn(async ({ relay }) => relay), + readBundle: vi.fn(async () => bundleWith(2, Number.MAX_SAFE_INTEGER)), + writeBundle: vi.fn(async () => {}), + saveHost: vi.fn(async () => {}), + now: Date.now, + randomBytes: (length: number) => new Uint8Array(length), + setTimer: setTimeout, + clearTimer: clearTimeout, + ...overrides + } +} + +describe('relay runtime recovery without direct connectivity', () => { + beforeEach(() => { + vi.spyOn(console, 'log').mockImplementation(() => {}) + vi.useFakeTimers() + vi.setSystemTime(new Date('2026-08-02T12:00:00Z')) + }) + + afterEach(() => { + vi.useRealTimers() + vi.restoreAllMocks() + }) + + it('recovers from a rejected outer credential once a fresher bundle is durable', async () => { + const logical = new FakeLogicalClient('disconnected', 'lan') + const openRelay = vi + .fn() + .mockReturnValueOnce(new FakeRelaySession('disconnected', new RelayOuterError(4401))) + .mockImplementation(() => new FakeRelaySession('connected')) + const readBundle = vi + .fn(async () => bundleWith(3, Number.MAX_SAFE_INTEGER)) + .mockResolvedValueOnce(bundleWith(2, Number.MAX_SAFE_INTEGER)) + const deps = dependencies({ openRelay, readBundle }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(openRelay).toHaveBeenCalledOnce() + + // Pre-fix, the fresh-credential gate latched here with no timer and no exit. + await vi.advanceTimersByTimeAsync(60_000) + expect(openRelay).toHaveBeenCalledTimes(2) + expect(openRelay).toHaveBeenLastCalledWith( + relay, + expect.objectContaining({ version: 3 }), + expect.any(String) + ) + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('recovers when the credential bundle was unreadable at supervisor start', async () => { + const logical = new FakeLogicalClient('disconnected', 'lan') + const readBundle = vi + .fn(async () => bundleWith(2, Number.MAX_SAFE_INTEGER)) + .mockResolvedValueOnce(null) + const deps = dependencies({ readBundle }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + // Pre-fix, a null first read killed relay recovery for the process lifetime. + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + + expect(deps.openRelay).toHaveBeenCalled() + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('recovers from an expired-at-start bundle after a fresh credential lands', async () => { + const logical = new FakeLogicalClient('disconnected', 'lan') + const expired = bundleWith(2, Date.now() - 1) + const readBundle = vi.fn(async () => expired) + const deps = dependencies({ readBundle }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(deps.openRelay).not.toHaveBeenCalled() + + readBundle.mockImplementation(async () => bundleWith(3, Number.MAX_SAFE_INTEGER)) + // Pre-fix, an expired bundle produced a silent no-op with nothing scheduled. + await vi.advanceTimersByTimeAsync(60_000) + + expect(deps.openRelay).toHaveBeenCalledOnce() + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('retries after an E2EE authentication rejection without a UI nudge', async () => { + const logical = new FakeLogicalClient('disconnected', 'lan') + const openRelay = vi + .fn() + .mockReturnValueOnce( + new FakeRelaySession('disconnected', new MobileE2EEAuthenticationError()) + ) + .mockImplementation(() => new FakeRelaySession('connected')) + const deps = dependencies({ openRelay }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(openRelay).toHaveBeenCalledOnce() + + // Pre-fix, this state waited indefinitely for a foreground/navigation event. + await vi.advanceTimersByTimeAsync(60_000) + expect(openRelay).toHaveBeenCalledTimes(2) + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('adopts a durable renewal that extends expiry without bumping the version', async () => { + // Why: resume confirmations and pairing recovery renew expiresAt while + // keeping current.version — version comparison cannot see this freshness. + const logical = new FakeLogicalClient('disconnected', 'lan') + const expired = bundleWith(2, Date.now() - 1) + const readBundle = vi + .fn(async () => bundleWith(2, Number.MAX_SAFE_INTEGER)) + .mockResolvedValueOnce(expired) + .mockResolvedValueOnce(expired) + const deps = dependencies({ readBundle }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(deps.openRelay).not.toHaveBeenCalled() + + await vi.advanceTimersByTimeAsync(60_000) + expect(deps.openRelay).toHaveBeenCalledOnce() + expect(deps.openRelay).toHaveBeenLastCalledWith( + relay, + expect.objectContaining({ version: 2 }), + expect.any(String) + ) + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('adopts a re-paired credential whose version counter restarted', async () => { + // Why: re-pairing overwrites the same keychain slot with a NEW credential + // record whose counter restarts at 1 — lower than the rejected version. + const logical = new FakeLogicalClient('disconnected', 'lan') + const openRelay = vi + .fn() + .mockReturnValueOnce(new FakeRelaySession('disconnected', new RelayOuterError(4401))) + .mockImplementation(() => new FakeRelaySession('connected')) + const readBundle = vi + .fn(async () => bundleWith(1, Number.MAX_SAFE_INTEGER)) + .mockResolvedValueOnce(bundleWith(4, Number.MAX_SAFE_INTEGER)) + const deps = dependencies({ openRelay, readBundle }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(openRelay).toHaveBeenCalledOnce() + + await vi.advanceTimersByTimeAsync(60_000) + expect(openRelay).toHaveBeenCalledTimes(2) + expect(openRelay).toHaveBeenLastCalledWith( + relay, + expect.objectContaining({ version: 1 }), + expect.any(String) + ) + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('does not churn relay sessions off the cell attach-reservation deadline', async () => { + // Why: the relay-hello's leaseExpiresAt is a ~10s attach deadline. Keying + // rotation off it replaced the session every second, killing any RPC + // slower than the cycle (the field symptom: "Worktree list unavailable"). + const logical = new FakeLogicalClient('disconnected', 'lan') + const openRelay = vi.fn(() => new FakeRelaySession('connected')) + // Direct stays unreachable, as in the field — return probes must not + // confuse the churn measurement by migrating back to direct. + const openDirect = vi.fn(() => new FakeSession('disconnected')) + const deps = dependencies({ openRelay, openDirect }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(openRelay).toHaveBeenCalledOnce() + + await vi.advanceTimersByTimeAsync(5 * 60_000) + expect(openRelay).toHaveBeenCalledOnce() + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) + + it('recovers immediately on a background/foreground cycle after an E2EE rejection', async () => { + const logical = new FakeLogicalClient('disconnected', 'lan') + const openRelay = vi + .fn() + .mockReturnValueOnce( + new FakeRelaySession('disconnected', new MobileE2EEAuthenticationError()) + ) + .mockImplementation(() => new FakeRelaySession('connected')) + const deps = dependencies({ openRelay }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(0) + expect(openRelay).toHaveBeenCalledOnce() + + supervisor.setForeground(false) + supervisor.setForeground(true) + await vi.advanceTimersByTimeAsync(0) + + expect(openRelay).toHaveBeenCalledTimes(2) + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + }) +}) + +// The field failure's first symptom: a real direct rpc-client dialing an +// unroutable LAN endpoint (instant 1006) while relay credentials sit unused. +class DeadSocket { + static constructed: string[] = [] + onopen: (() => void) | null = null + onclose: ((event: { code?: number; reason?: string }) => void) | null = null + onerror: ((event: unknown) => void) | null = null + onmessage: ((event: { data: unknown }) => void) | null = null + readyState = 0 + + constructor(readonly url: string) { + DeadSocket.constructed.push(url) + setTimeout(() => { + this.readyState = 3 + this.onclose?.({ code: 1006, reason: '' }) + }, 50) + } + + send(): void {} + close(): void { + this.readyState = 3 + } +} + +describe('failover with a real direct rpc-client', () => { + beforeEach(() => { + DeadSocket.constructed = [] + vi.stubGlobal('WebSocket', DeadSocket) + vi.spyOn(console, 'log').mockImplementation(() => {}) + vi.useFakeTimers() + vi.setSystemTime(new Date('2026-08-02T12:00:00Z')) + }) + + afterEach(() => { + vi.useRealTimers() + vi.unstubAllGlobals() + vi.restoreAllMocks() + }) + + it('migrates the logical client to relay after the direct dial fails', async () => { + const logical = createStableLogicalRpcClient( + connect(DIRECT_ENDPOINT, host.deviceToken, host.publicKeyB64), + 'tailscale' as MobileConnectionPath + ) + const deps = dependencies() + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + await supervisor.start() + await vi.advanceTimersByTimeAsync(3_000) + + expect(deps.openRelay).toHaveBeenCalled() + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + logical.close() + }) + + it('reaches relay even when the bundle read settles after the first direct failure', async () => { + const logical = createStableLogicalRpcClient( + connect(DIRECT_ENDPOINT, host.deviceToken, host.publicKeyB64), + 'tailscale' as MobileConnectionPath + ) + const deps = dependencies({ + readBundle: vi.fn(async () => { + await new Promise((resolve) => setTimeout(resolve, 200)) + return bundleWith(2, Number.MAX_SAFE_INTEGER) + }) + }) + const supervisor = new MobileEndpointSupervisor(logical, host, deps) + + const started = supervisor.start() + await vi.advanceTimersByTimeAsync(300) + await started + await vi.advanceTimersByTimeAsync(3_000) + + expect(deps.openRelay).toHaveBeenCalled() + expect(logical.getActivePath()).toBe('relay') + supervisor.stop() + logical.close() + }) +}) diff --git a/mobile/src/transport/rpc-client-activity-probe.ts b/mobile/src/transport/rpc-client-activity-probe.ts new file mode 100644 index 00000000000..02dc4362fbd --- /dev/null +++ b/mobile/src/transport/rpc-client-activity-probe.ts @@ -0,0 +1,87 @@ +import type { ConnectionState } from './types' + +// Why: RN auto-pongs pings natively, so JS needs an app-level probe to detect half-open sockets. +const ACTIVITY_PROBE_INTERVAL_MS = 20_000 +const ACTIVITY_PROBE_TIMEOUT_MS = 8_000 + +export type RpcActivityProbeDependencies = { + getState: () => ConnectionState + getSocket: () => WebSocket | null + // Counts only validated inbound traffic, so a malformed frame cannot pass for liveness. + getInboundSequence: () => number + nextId: () => string + registerPending: (id: string, onSettled: () => void) => void + clearPending: (id: string) => void + sendProbe: (id: string) => boolean + forceReconnect: (socket: WebSocket) => void +} + +export type RpcActivityProbe = { + start: () => void + stop: () => void + run: () => void +} + +export function createRpcActivityProbe( + dependencies: RpcActivityProbeDependencies +): RpcActivityProbe { + let timer: ReturnType | null = null + let inFlight = false + + function stop(): void { + if (timer) { + clearInterval(timer) + timer = null + } + } + + function run(): void { + const probeWs = dependencies.getSocket() + if (dependencies.getState() !== 'connected' || !probeWs || inFlight) { + return + } + inFlight = true + const id = dependencies.nextId() + const probeInboundSequence = dependencies.getInboundSequence() + let timedOut = false + const timeout = setTimeout(() => { + timedOut = true + inFlight = false + dependencies.clearPending(id) + // Why: any validated frame answered for the socket, even if this probe did not. + if (dependencies.getInboundSequence() > probeInboundSequence) { + return + } + console.log('[net] activity-probe TIMEOUT — forcing reconnect', { + state: dependencies.getState() + }) + // Why: stale probe timers must not close a replacement socket. + if (probeWs === dependencies.getSocket() && probeWs.readyState === WebSocket.OPEN) { + dependencies.forceReconnect(probeWs) + } + }, ACTIVITY_PROBE_TIMEOUT_MS) + + dependencies.registerPending(id, () => { + if (timedOut) { + return + } + inFlight = false + clearTimeout(timeout) + }) + + if (!dependencies.sendProbe(id)) { + inFlight = false + clearTimeout(timeout) + dependencies.clearPending(id) + } + } + + return { + run, + stop, + start(): void { + stop() + timer = setInterval(run, ACTIVITY_PROBE_INTERVAL_MS) + } + } +} diff --git a/mobile/src/transport/rpc-client.ts b/mobile/src/transport/rpc-client.ts index 3cdc612afb9..07891e84d85 100644 --- a/mobile/src/transport/rpc-client.ts +++ b/mobile/src/transport/rpc-client.ts @@ -36,6 +36,8 @@ import { import { markRpcDeliveryUnknown } from './rpc-delivery-ambiguity' import { openRpcRequestBudget, resolvePostConnectRequestTimeout } from './rpc-request-budget' import { isRpcResponse } from './rpc-response-shape' +import { createRpcActivityProbe } from './rpc-client-activity-probe' +import { isStaleForegroundDial } from './rpc-stale-dial' import { websocketPayloadToUint8 } from './websocket-payload-bytes' type PendingRequest = { @@ -126,9 +128,6 @@ const HANDSHAKE_TIMEOUT_MS = 5_000 // Why: RN may not expose WebSocket.readyState constants, but the CONNECTING protocol value (0) is stable across runtimes. const WEBSOCKET_CONNECTING_STATE = 0 -// Why: RN auto-pongs pings natively, so JS needs an app-level probe to detect half-open sockets. -const ACTIVITY_PROBE_INTERVAL_MS = 20_000 - export type ConnectOptions = { onStateChange?: (state: ConnectionState) => void // Fires for every lifecycle event so the UI can show where 'Connecting…' is stuck (e.g. broken Tailscale route). @@ -169,8 +168,6 @@ export function connect( let reconnectTimer: ReturnType | null = null let connectTimer: ReturnType | null = null let handshakeTimer: ReturnType | null = null - let activityProbeTimer: ReturnType | null = null - let activityProbeInFlight = false let intentionallyClosed = false // Consecutive auth rejections; tolerate up to AUTH_RETRY_BUDGET (issue #5200) before latching to avoid a needless re-pair. let authRejectionCount = 0 @@ -181,6 +178,7 @@ export function connect( let inboundSequence = 0 let lastWsClosedAt: number | null = null let wsConstructionCounter = 0 + let dialStartedAt = 0 // Why: fresh ephemeral keypair per connection provides forward secrecy. let sharedKey: Uint8Array | null = null @@ -302,6 +300,7 @@ export function connect( msSinceLastInbound: lastInboundAt != null ? now - lastInboundAt : null }) setState('connecting') + dialStartedAt = now sharedKey = null emitLog( @@ -328,11 +327,7 @@ export function connect( 'WebSocket connect timeout', `No TCP/WS handshake within ${CONNECT_TIMEOUT_MS / 1000}s — endpoint unreachable?` ) - openingWs.close() - if (ws === openingWs) { - synthesizedCloses.remember(openingWs, authenticationGeneration) - handleSocketClosed(openingWs, { timedOut: true }) - } + closeAndSynthesize(openingWs) } }, CONNECT_TIMEOUT_MS) @@ -372,12 +367,7 @@ export function connect( 'Handshake timeout', `No e2ee_ready/e2ee_authenticated within ${HANDSHAKE_TIMEOUT_MS / 1000}s` ) - openingWs.close() - // Why: React Native can omit onclose for a wedged iOS transport. - if (ws === openingWs) { - synthesizedCloses.remember(openingWs, authenticationGeneration) - handleSocketClosed(openingWs, { timedOut: true }) - } + closeAndSynthesize(openingWs) }, HANDSHAKE_TIMEOUT_MS) } @@ -422,17 +412,14 @@ export function connect( try { const msg = JSON.parse(plaintext) if (msg.type === 'e2ee_authenticated') { - if (handshakeTimer) { - clearTimeout(handshakeTimer) - handshakeTimer = null - } + clearHandshakeTimer() console.log('[net] e2ee_authenticated — connected', { streamCount: streamListeners.size }) openingWsAuthenticated = true setState('connected') emitLog('success', 'Authenticated', 'Channel ready for RPC') - startActivityProbe() + activityProbe.start() for (const [id, stream] of streamListeners) { if (stream.cancelled) { removeStreamListener(id) @@ -458,10 +445,7 @@ export function connect( } } else if (msg.type === 'e2ee_error' || (!msg.ok && msg.error?.code === 'unauthorized')) { console.log('[net] e2ee auth FAILED', { msgType: msg.type, error: msg.error }) - if (handshakeTimer) { - clearTimeout(handshakeTimer) - handshakeTimer = null - } + clearHandshakeTimer() handleAuthRejection('Unauthorized — pairing may be revoked') } } catch { @@ -654,11 +638,8 @@ export function connect( activeBrowserScreencastRequestId = null pendingBrowserScreencastRequestId = null markStreamsForReplay() - if (handshakeTimer) { - clearTimeout(handshakeTimer) - handshakeTimer = null - } - stopActivityProbe() + clearHandshakeTimer() + activityProbe.stop() if (intentionallyClosed) { console.log('[net] handleSocketClosed — intentional close') setState('disconnected') @@ -768,66 +749,33 @@ export function connect( } } - // Why: app-level liveness probe (see ACTIVITY_PROBE_INTERVAL_MS) — force-closes the WS on failure so onclose reconnects. - function runActivityProbe() { - if (state !== 'connected' || !ws || activityProbeInFlight) { - return - } - activityProbeInFlight = true - const probeWs = ws - const id = nextId() - const probeInboundSequence = inboundSequence - let timedOut = false - const timeout = setTimeout(() => { - timedOut = true - activityProbeInFlight = false - pending.delete(id) - if (inboundSequence > probeInboundSequence) { - return - } - console.log('[net] activity-probe TIMEOUT — forcing reconnect', { state }) - // Why: stale probe timers must not close a replacement socket. - if (probeWs === ws && probeWs.readyState === WebSocket.OPEN) { - probeWs.close() - // Why: React Native can omit onclose for a wedged iOS transport. - if (probeWs === ws) { - synthesizedCloses.remember(probeWs, authenticationGeneration) - handleSocketClosed(probeWs, { timedOut: true }) - } - } - }, 8_000) - pending.set(id, { - resolve: () => { - if (timedOut) { - return - } - activityProbeInFlight = false - clearTimeout(timeout) - }, - reject: () => { - if (timedOut) { - return - } - activityProbeInFlight = false - clearTimeout(timeout) - } - }) - if (!sendEncrypted({ id, deviceToken, method: 'status.get' })) { - activityProbeInFlight = false - clearTimeout(timeout) - pending.delete(id) + function clearHandshakeTimer() { + if (handshakeTimer) { + clearTimeout(handshakeTimer) + handshakeTimer = null } } - function startActivityProbe() { - stopActivityProbe() - activityProbeTimer = setInterval(runActivityProbe, ACTIVITY_PROBE_INTERVAL_MS) + // Why: a revival signal dials at once rather than waiting out the armed backoff. + // Only the caller knows whether the attempt that led here should be forgiven. + function redialNow(resetAttempts: boolean) { + if (reconnectTimer) { + clearTimeout(reconnectTimer) + reconnectTimer = null + } + if (resetAttempts) { + reconnectAttempt = 0 + } + openConnection() } - function stopActivityProbe() { - if (activityProbeTimer) { - clearInterval(activityProbeTimer) - activityProbeTimer = null + // Why: React Native can omit onclose for a wedged iOS transport, so every forced + // close has to synthesize the close event it may never deliver. + function closeAndSynthesize(socket: WebSocket) { + socket.close() + if (ws === socket) { + synthesizedCloses.remember(socket, authenticationGeneration) + handleSocketClosed(socket, { timedOut: true }) } } @@ -1005,6 +953,17 @@ export function connect( } } + const activityProbe = createRpcActivityProbe({ + getState: () => state, + getSocket: () => ws, + getInboundSequence: () => inboundSequence, + nextId, + registerPending: (id, onSettled) => pending.set(id, { resolve: onSettled, reject: onSettled }), + clearPending: (id) => pending.delete(id), + sendProbe: (id) => sendEncrypted({ id, deviceToken, method: 'status.get' }), + forceReconnect: closeAndSynthesize + }) + openConnection() return { @@ -1160,22 +1119,31 @@ export function connect( if (state === 'connected') { // Why: OS can kill the TCP path while backgrounded without onclose; probe now to detect the half-open socket in ≤8s (issue #5049). console.log('[net] foreground — probing live connection') - startActivityProbe() - runActivityProbe() + activityProbe.start() + activityProbe.run() return } + const dialing = ws + const dialAgeMs = Date.now() - dialStartedAt + let abandoned = false + if (dialing && isStaleForegroundDial(state, dialAgeMs)) { + console.log('[net] foreground — abandoning stale dial', { state, dialAgeMs }) + closeAndSynthesize(dialing) + abandoned = true + } if (state === 'reconnecting') { // Why: foreground is a strong user signal — restart immediately instead of waiting out a 60s/90s backoff timer. console.log('[net] foreground — restarting reconnect loop', { attempt: reconnectAttempt, hadTimer: !!reconnectTimer }) - if (reconnectTimer) { - clearTimeout(reconnectTimer) - reconnectTimer = null - } - reconnectAttempt = 0 - openConnection() + // Why: an abandoned dial keeps the failure it already represents. It never + // authenticated, so it is the same failure the connect timeout would have + // booked had we waited it out — we skip the wait, we don't pardon it. Zeroing + // there would let a resume (or a flapping network) reset the counter faster + // than it climbs, pinning the card at "Connecting…" through a real outage + // (issue #10119). A redial with no dial to abandon is a genuinely fresh start. + redialNow(!abandoned) } }, @@ -1186,11 +1154,8 @@ export function connect( reconnectTimer = null } clearConnectTimer() - if (handshakeTimer) { - clearTimeout(handshakeTimer) - handshakeTimer = null - } - stopActivityProbe() + clearHandshakeTimer() + activityProbe.stop() if (ws) { ws.close() ws = null diff --git a/mobile/src/transport/rpc-stale-dial.ts b/mobile/src/transport/rpc-stale-dial.ts new file mode 100644 index 00000000000..f9a6b51cbf0 --- /dev/null +++ b/mobile/src/transport/rpc-stale-dial.ts @@ -0,0 +1,16 @@ +import type { ConnectionState } from './types' + +// Why: a dial older than this predates the revival signal, so it was opened over a +// network path that may no longer exist. Younger dials belong to the current +// foreground session — AppState 'active' and a Wi-Fi→cellular change fire back to +// back, and both reach the same nudge, so this also keeps them from churning it. +const STALE_DIAL_AGE_MS = 2_000 + +// A phone suspended mid-dial resumes still holding that socket, and React Native +// keeps its readyState at CONNECTING because no close event was ever delivered. +// Treating 'connecting'/'handshaking' as progress worth waiting out left the user +// on the rest of the 12s connect budget over a dead path, then a preserved backoff +// delay — up to a further 60s of "Connecting…" against an answering desktop. +export function isStaleForegroundDial(state: ConnectionState, dialAgeMs: number): boolean { + return (state === 'connecting' || state === 'handshaking') && dialAgeMs >= STALE_DIAL_AGE_MS +} diff --git a/mobile/src/worktree/home-worktree-info.test.ts b/mobile/src/worktree/home-worktree-info.test.ts new file mode 100644 index 00000000000..ebbfe379e99 --- /dev/null +++ b/mobile/src/worktree/home-worktree-info.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest' +import { markHomeWorktreeCatalogUnavailable, type HostWorktreeInfo } from './home-worktree-info' + +describe('markHomeWorktreeCatalogUnavailable', () => { + it('marks a host unavailable when no catalog has loaded', () => { + expect(markHomeWorktreeCatalogUnavailable(undefined, 'host-1')).toEqual({ + hostId: 'host-1', + totalWorktrees: 0, + activeCount: 0, + lastActiveWorktree: null, + catalogUnavailable: true + }) + }) + + it('marks cached counts unavailable without discarding the cached snapshot', () => { + const current: HostWorktreeInfo = { + hostId: 'host-1', + totalWorktrees: 3, + activeCount: 1, + lastActiveWorktree: { + worktreeId: 'worktree-1', + repo: 'orca', + branch: 'feature', + displayName: 'Feature', + liveTerminalCount: 1 + } + } + + expect(markHomeWorktreeCatalogUnavailable(current, 'host-1')).toEqual({ + ...current, + catalogUnavailable: true + }) + }) + + it('reuses an already unavailable snapshot to avoid repeated render churn', () => { + const current: HostWorktreeInfo = { + hostId: 'host-1', + totalWorktrees: 0, + activeCount: 0, + lastActiveWorktree: null, + catalogUnavailable: true + } + + expect(markHomeWorktreeCatalogUnavailable(current, 'host-1')).toBe(current) + }) +}) diff --git a/mobile/src/worktree/home-worktree-info.ts b/mobile/src/worktree/home-worktree-info.ts new file mode 100644 index 00000000000..867e266e89e --- /dev/null +++ b/mobile/src/worktree/home-worktree-info.ts @@ -0,0 +1,37 @@ +export type HomeWorktreeSummary = { + worktreeId: string + repo: string + branch: string + displayName: string + liveTerminalCount: number + status?: 'working' | 'active' | 'permission' | 'done' | 'inactive' + isActive?: boolean + lastOutputAt?: number +} + +export type HostWorktreeInfo = { + hostId: string + totalWorktrees: number + activeCount: number + lastActiveWorktree: HomeWorktreeSummary | null + catalogUnavailable?: boolean +} + +export function markHomeWorktreeCatalogUnavailable( + current: HostWorktreeInfo | undefined, + hostId: string +): HostWorktreeInfo { + if (current?.catalogUnavailable) { + return current + } + if (current) { + return { ...current, catalogUnavailable: true } + } + return { + hostId, + totalWorktrees: 0, + activeCount: 0, + lastActiveWorktree: null, + catalogUnavailable: true + } +} diff --git a/mobile/src/worktree/host-workspace-list-state.test.ts b/mobile/src/worktree/host-workspace-list-state.test.ts new file mode 100644 index 00000000000..15ae4705a6e --- /dev/null +++ b/mobile/src/worktree/host-workspace-list-state.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from 'vitest' +import { + selectHostWorkspaceListState, + type HostWorkspaceListStateInput +} from './host-workspace-list-state' + +function input(overrides: Partial): HostWorkspaceListStateInput { + return { + connState: 'connected', + worktreesLoaded: true, + displayCount: 0, + sectionCount: 0, + catalogError: null, + ...overrides + } +} + +// Regression guard for STA-3123: a remote host whose worktree.ps fails must render +// as a catalog failure, never as a healthy host with zero workspaces. +describe('selectHostWorkspaceListState', () => { + it('reports catalog-error instead of empty when the fetch failed with no rows', () => { + expect(selectHostWorkspaceListState(input({ catalogError: 'forbidden' }))).toBe('catalog-error') + expect( + selectHostWorkspaceListState(input({ catalogError: 'forbidden', worktreesLoaded: false })) + ).toBe('catalog-error') + }) + + it('keeps showing cached rows (no overlay) when a later fetch fails', () => { + expect( + selectHostWorkspaceListState( + input({ catalogError: 'network_error', displayCount: 3, sectionCount: 2 }) + ) + ).toBeNull() + }) + + it('still reports empty for a filtered-out cached list during a failure', () => { + expect( + selectHostWorkspaceListState( + input({ catalogError: 'network_error', displayCount: 3, sectionCount: 0 }) + ) + ).toBe('empty') + }) + + it('reports empty only after a successful load confirmed zero workspaces', () => { + expect(selectHostWorkspaceListState(input({}))).toBe('empty') + expect(selectHostWorkspaceListState(input({ worktreesLoaded: false }))).toBe('loading') + }) + + it('shows the spinner while connecting regardless of error state', () => { + expect( + selectHostWorkspaceListState(input({ connState: 'reconnecting', catalogError: 'x' })) + ).toBe('loading') + expect( + selectHostWorkspaceListState( + input({ connState: 'connecting', worktreesLoaded: false, catalogError: null }) + ) + ).toBe('loading') + }) + + it('renders nothing while disconnected with cached rows', () => { + expect( + selectHostWorkspaceListState( + input({ connState: 'disconnected', displayCount: 2, sectionCount: 1 }) + ) + ).toBeNull() + }) +}) diff --git a/mobile/src/worktree/host-workspace-list-state.ts b/mobile/src/worktree/host-workspace-list-state.ts new file mode 100644 index 00000000000..c14b5859ef4 --- /dev/null +++ b/mobile/src/worktree/host-workspace-list-state.ts @@ -0,0 +1,34 @@ +import type { ConnectionState } from '../transport/types' + +export type HostWorkspaceListStateInput = { + connState: ConnectionState + worktreesLoaded: boolean + displayCount: number + sectionCount: number + catalogError: string | null +} + +// Why (STA-3123): one owner for the list's loading/failed/empty precedence, so a +// failed worktree.ps can never render as a healthy host with zero workspaces. +export function selectHostWorkspaceListState( + input: HostWorkspaceListStateInput +): 'loading' | 'catalog-error' | 'empty' | null { + const { connState, worktreesLoaded, displayCount, sectionCount, catalogError } = input + const connecting = connState === 'connecting' || connState === 'reconnecting' + if ( + (connecting && displayCount === 0) || + (connState === 'connected' && !worktreesLoaded && displayCount === 0 && !catalogError) + ) { + return 'loading' + } + if (connState !== 'connected') { + return null + } + if (catalogError && displayCount === 0) { + return 'catalog-error' + } + if (worktreesLoaded && sectionCount === 0) { + return 'empty' + } + return null +} diff --git a/mobile/src/worktree/host-workspace-list-states.tsx b/mobile/src/worktree/host-workspace-list-states.tsx new file mode 100644 index 00000000000..a9449da2f5b --- /dev/null +++ b/mobile/src/worktree/host-workspace-list-states.tsx @@ -0,0 +1,65 @@ +import { ActivityIndicator, StyleSheet, Text, View } from 'react-native' +import { colors, spacing, typography } from '../theme/mobile-theme' +import { + selectHostWorkspaceListState, + type HostWorkspaceListStateInput +} from './host-workspace-list-state' + +export function HostWorkspaceListStates( + props: HostWorkspaceListStateInput & { + search: string + activeFilterCount: number + } +) { + const state = selectHostWorkspaceListState(props) + if (state === 'loading') { + return ( + + + + ) + } + if (state === 'catalog-error') { + return ( + + Could not load workspaces from this host + + {`worktree.ps failed (${props.catalogError}) — retrying automatically`} + + + ) + } + if (state === 'empty') { + return ( + + + {props.search + ? 'No matching worktrees' + : props.activeFilterCount > 0 + ? 'No worktrees match filters' + : 'No worktrees'} + + + ) + } + return null +} + +const styles = StyleSheet.create({ + centered: { + flex: 1, + alignItems: 'center', + justifyContent: 'center' + }, + emptyText: { + color: colors.textSecondary, + fontSize: typography.bodySize + }, + catalogErrorDetail: { + marginTop: spacing.xs, + paddingHorizontal: spacing.lg, + color: colors.textMuted, + fontSize: typography.metaSize, + textAlign: 'center' + } +}) diff --git a/mobile/src/worktree/worktree-catalog-snapshot-client.test.ts b/mobile/src/worktree/worktree-catalog-snapshot-client.test.ts index 35eb414dbd2..f910387c7d3 100644 --- a/mobile/src/worktree/worktree-catalog-snapshot-client.test.ts +++ b/mobile/src/worktree/worktree-catalog-snapshot-client.test.ts @@ -3,9 +3,17 @@ import type { RpcClient } from '../transport/rpc-client' import { admitWorktreeCatalogResponse, WORKTREE_PS_FULL_LIMIT, - WorktreeCatalogSnapshotClient + WorktreeCatalogSnapshotClient, + type WorktreeCatalogFetchResult } from './worktree-catalog-snapshot-client' +function admitFetched( + snapshots: WorktreeCatalogSnapshotClient, + fetched: WorktreeCatalogFetchResult +) { + return snapshots.admit(fetched.kind === 'response' ? fetched.pending : null) +} + describe('admitWorktreeCatalogResponse', () => { it('accepts new-host full and unchanged responses', () => { const full = admitWorktreeCatalogResponse( @@ -94,8 +102,8 @@ describe('WorktreeCatalogSnapshotClient', () => { ) const snapshots = new WorktreeCatalogSnapshotClient() - const first = snapshots.admit(await snapshots.fetch(client, 'host-1')) - const second = snapshots.admit(await snapshots.fetch(client, 'host-1')) + const first = admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) + const second = admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) expect(first).toEqual(rows) expect(second).toEqual(rows) @@ -109,7 +117,7 @@ describe('WorktreeCatalogSnapshotClient', () => { const snapshots = new WorktreeCatalogSnapshotClient() await snapshots.fetch(client, 'host-1') - snapshots.admit(await snapshots.fetch(client, 'host-1')) + admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) expect(client.sendRequest).toHaveBeenNthCalledWith(2, 'worktree.ps', { limit: WORKTREE_PS_FULL_LIMIT, @@ -121,7 +129,7 @@ describe('WorktreeCatalogSnapshotClient', () => { const client = clientWithResults({ worktrees: [], snapshotId: 'snapshot-1' }) const snapshots = new WorktreeCatalogSnapshotClient() - snapshots.admit(await snapshots.fetch(client, 'host-1')) + admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) snapshots.admit(null) await snapshots.fetch(client, 'host-1') @@ -139,8 +147,8 @@ describe('WorktreeCatalogSnapshotClient', () => { ) const snapshots = new WorktreeCatalogSnapshotClient() - snapshots.admit(await snapshots.fetch(client, 'host-1')) - snapshots.admit(await snapshots.fetch(client, 'host-1')) + admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) + admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) await snapshots.fetch(client, 'host-1') expect(client.sendRequest).toHaveBeenNthCalledWith(3, 'worktree.ps', { @@ -154,7 +162,7 @@ describe('WorktreeCatalogSnapshotClient', () => { const secondClient = clientWithResults({ worktrees: [], snapshotId: 'snapshot-2' }) const snapshots = new WorktreeCatalogSnapshotClient() - snapshots.admit(await snapshots.fetch(firstClient, 'host-1')) + admitFetched(snapshots, await snapshots.fetch(firstClient, 'host-1')) await snapshots.fetch(secondClient, 'host-2') expect(secondClient.sendRequest).toHaveBeenCalledWith('worktree.ps', { @@ -170,8 +178,8 @@ describe('WorktreeCatalogSnapshotClient', () => { // Host A's response is still in flight when the screen switches to host B. const stale = await snapshots.fetch(firstClient, 'host-1') - snapshots.admit(await snapshots.fetch(secondClient, 'host-2')) - expect(snapshots.admit(stale)).toBeNull() + admitFetched(snapshots, await snapshots.fetch(secondClient, 'host-2')) + expect(admitFetched(snapshots, stale)).toBeNull() await snapshots.fetch(secondClient, 'host-2') expect(secondClient.sendRequest).toHaveBeenNthCalledWith(2, 'worktree.ps', { @@ -179,4 +187,40 @@ describe('WorktreeCatalogSnapshotClient', () => { afterSnapshotId: 'snapshot-2' }) }) + + // Why (STA-3123): a failed worktree.ps rendered as "0 worktrees"; callers need the + // failure code to show an error state instead of an empty host. + it('surfaces the RPC error code on failure and keeps the admitted token', async () => { + const responses: unknown[] = [ + { id: 'request', ok: true, result: { worktrees: [], snapshotId: 'snapshot-1' } }, + { id: 'request', ok: false, error: { code: 'forbidden', message: 'nope' } }, + { id: 'request', ok: true, result: { unchanged: true, snapshotId: 'snapshot-1' } } + ] + const client = { + sendRequest: vi.fn(async () => responses.shift()) + } as unknown as RpcClient + const snapshots = new WorktreeCatalogSnapshotClient() + + admitFetched(snapshots, await snapshots.fetch(client, 'host-1')) + const failed = await snapshots.fetch(client, 'host-1') + expect(failed).toEqual({ kind: 'request_failed', code: 'forbidden' }) + + await snapshots.fetch(client, 'host-1') + expect(client.sendRequest).toHaveBeenNthCalledWith(3, 'worktree.ps', { + limit: WORKTREE_PS_FULL_LIMIT, + afterSnapshotId: 'snapshot-1' + }) + }) + + it('falls back to a generic failure code when the error carries none', async () => { + const client = { + sendRequest: vi.fn(async () => ({ id: 'request', ok: false, error: { message: 'x' } })) + } as unknown as RpcClient + const snapshots = new WorktreeCatalogSnapshotClient() + + expect(await snapshots.fetch(client, 'host-1')).toEqual({ + kind: 'request_failed', + code: 'request_failed' + }) + }) }) diff --git a/mobile/src/worktree/worktree-catalog-snapshot-client.ts b/mobile/src/worktree/worktree-catalog-snapshot-client.ts index 8b66ceddddd..9e804c39b34 100644 --- a/mobile/src/worktree/worktree-catalog-snapshot-client.ts +++ b/mobile/src/worktree/worktree-catalog-snapshot-client.ts @@ -1,5 +1,5 @@ import type { RpcClient } from '../transport/rpc-client' -import type { RpcSuccess } from '../transport/types' +import type { RpcFailure, RpcSuccess } from '../transport/types' import type { Worktree } from './workspace-list-sections' // Why: worktree.ps silently truncates at 200; use a high cap so large hosts don't drop workspaces. @@ -10,12 +10,19 @@ export type WorktreeCatalogAdmission = | { kind: 'unchanged'; snapshotId: string } | { kind: 'invalid' } -type PendingWorktreeCatalog = { +export type PendingWorktreeCatalog = { admission: WorktreeCatalogAdmission client: RpcClient hostId: string } +// Why (STA-3123): a failed worktree.ps must stay distinguishable from an empty +// catalog — collapsing both to "no rows" made unreachable remote-server catalogs +// render as a healthy host with 0 worktrees. +export type WorktreeCatalogFetchResult = + | { kind: 'response'; pending: PendingWorktreeCatalog } + | { kind: 'request_failed'; code: string } + function validSnapshotId(value: unknown): string | null { return typeof value === 'string' && value.length > 0 && value.length <= 128 ? value : null } @@ -56,7 +63,7 @@ export class WorktreeCatalogSnapshotClient { private snapshotId: string | null = null private confirmedWorktrees: Worktree[] | null = null - async fetch(client: RpcClient, hostId: string): Promise { + async fetch(client: RpcClient, hostId: string): Promise { if (this.client !== client || this.hostId !== hostId) { this.client = client this.hostId = hostId @@ -69,15 +76,22 @@ export class WorktreeCatalogSnapshotClient { afterSnapshotId: requestedSnapshotId }) if (!response.ok) { - return null + const code = (response as RpcFailure).error?.code + return { + kind: 'request_failed', + code: typeof code === 'string' && code.length > 0 ? code : 'request_failed' + } } return { - admission: admitWorktreeCatalogResponse( - (response as RpcSuccess).result, - requestedSnapshotId - ), - client, - hostId + kind: 'response', + pending: { + admission: admitWorktreeCatalogResponse( + (response as RpcSuccess).result, + requestedSnapshotId + ), + client, + hostId + } } } diff --git a/native/windows-cli-launcher/OrcaCliLauncher.cs b/native/windows-cli-launcher/OrcaCliLauncher.cs index 8f89e303413..6261775859b 100644 --- a/native/windows-cli-launcher/OrcaCliLauncher.cs +++ b/native/windows-cli-launcher/OrcaCliLauncher.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Text; @@ -43,18 +42,17 @@ internal static class OrcaCliLauncher // Why: launching without cmd.exe preserves embedded newlines while matching the // packaged batch launcher's Electron-as-Node environment contract. - MoveEnvironmentVariable(startInfo.EnvironmentVariables, "NODE_OPTIONS", "ORCA_NODE_OPTIONS"); - MoveEnvironmentVariable( - startInfo.EnvironmentVariables, - "NODE_REPL_EXTERNAL_MODULE", - "ORCA_NODE_REPL_EXTERNAL_MODULE" + // Why: ProcessStartInfo's env copy rejects duplicate PATH/Path keys; mutating this + // short-lived process preserves the native block for child inheritance (#12046). + MoveEnvironmentVariable("NODE_OPTIONS", "ORCA_NODE_OPTIONS"); + MoveEnvironmentVariable("NODE_REPL_EXTERNAL_MODULE", "ORCA_NODE_REPL_EXTERNAL_MODULE"); + Environment.SetEnvironmentVariable("ELECTRON_RUN_AS_NODE", "1"); + Environment.SetEnvironmentVariable("ORCA_WINDOWS_PACKAGED_CLI_LAUNCHER", "1"); + string requestedCliCommand = Environment.GetEnvironmentVariable("ORCA_CLI_COMMAND"); + Environment.SetEnvironmentVariable( + "ORCA_CLI_COMMAND", + requestedCliCommand == "orca-ide" ? "orca-ide" : "orca" ); - startInfo.EnvironmentVariables["ELECTRON_RUN_AS_NODE"] = "1"; - startInfo.EnvironmentVariables["ORCA_WINDOWS_PACKAGED_CLI_LAUNCHER"] = "1"; - startInfo.EnvironmentVariables["ORCA_CLI_COMMAND"] = - Environment.GetEnvironmentVariable("ORCA_CLI_COMMAND") == "orca-ide" - ? "orca-ide" - : "orca"; using (Process child = Process.Start(startInfo)) { @@ -69,19 +67,12 @@ internal static class OrcaCliLauncher } } - private static void MoveEnvironmentVariable( - StringDictionary environment, - string sourceName, - string targetName - ) + private static void MoveEnvironmentVariable(string sourceName, string targetName) { string value = Environment.GetEnvironmentVariable(sourceName); - environment.Remove(sourceName); - environment.Remove(targetName); - if (value != null) - { - environment[targetName] = value; - } + Environment.SetEnvironmentVariable(sourceName, null); + // Why: a null value clears the target, matching the previous unconditional Remove. + Environment.SetEnvironmentVariable(targetName, value); } private static string BuildArguments(string cliPath, string[] args) diff --git a/package.json b/package.json index b68ff2de99a..3a86ecfaf71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca", - "version": "1.4.164-rc.2", + "version": "1.4.168-rc.1", "description": "Next-gen IDE for parallel agentic development", "homepage": "https://github.com/stablyai/orca", "author": "stablyai", @@ -16,7 +16,7 @@ "audit:code-quality:native": "oxlint --config config/oxlint-code-quality-native-plugins.json src config tests mobile --deny-warnings", "audit:code-quality:type-aware": "oxlint --type-aware --config config/oxlint-code-quality-type-aware.json src config tests --deny-warnings", "audit:react-doctor": "pnpm dlx react-doctor@0.9.1 . --yes --no-supply-chain --no-telemetry --blocking none", - "audit:dead-code": "pnpm dlx knip@5 --config config/knip.json", + "audit:dead-code": "pnpm dlx knip@5.88.1 --config config/knip.json", "check:code-quality:changed": "node config/scripts/check-changed-code-quality.mjs", "check:react-doctor:changed": "node config/scripts/check-react-doctor-changed.mjs", "check:zustand-selector-fanout": "node config/scripts/zustand-selector-fanout-benchmark.mjs --check", @@ -116,7 +116,11 @@ "bench:multi-workspace-typing": "pnpm run ensure:electron-runtime && node config/scripts/run-multi-workspace-typing-bench.mjs", "bench:cold-park-reveal": "pnpm run ensure:electron-runtime && node tests/tools/benchmarks/terminal-cold-park-reveal-bench.mjs", "bench:cold-park-resource": "pnpm run ensure:electron-runtime && node tests/tools/benchmarks/terminal-cold-park-resource-bench.mjs", - "bench:compare": "node config/scripts/compare-benchmark-artifacts.mjs" + "bench:compare": "node config/scripts/compare-benchmark-artifacts.mjs", + "test:e2e:remote-bulk-open-freeze": "pnpm run ensure:electron-runtime && pnpm exec playwright test tests/e2e/remote-session-bulk-open-freeze-repro.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1", + "test:e2e:ssh-docker-bulk-open-freeze": "node config/scripts/run-ssh-docker-bulk-open-freeze-e2e.mjs", + "repro:live-remote-bulk-open-freeze": "node config/scripts/live-remote-bulk-open-freeze-repro.mjs", + "repro:live-remote-realistic-freeze": "node config/scripts/live-remote-realistic-freeze-repro.mjs" }, "dependencies": { "@electron-toolkit/preload": "^3.0.2", @@ -205,7 +209,7 @@ "lowlight": "^3.3.0", "lucide-react": "^0.577.0", "marked": "^17.0.1", - "mermaid": "^11.15.0", + "mermaid": "^11.16.0", "monaco-editor": "^0.55.1", "oxfmt": "^0.52.0", "oxlint": "^1.75.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dbe19cf1e7a..c4d53a979e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,13 +13,13 @@ patchedDependencies: hash: 47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920 path: config/patches/@xterm__addon-ligatures@0.11.0-beta.287.patch '@xterm/addon-serialize@0.15.0-beta.287': - hash: 81575700d58b62f9262d302aa4ae43b445a6273d579cd75dd6729c8883011ab9 + hash: 96f70e83261df6a29ad7590feb08b988670655ced7596e77253d524f73f608dd path: config/patches/@xterm__addon-serialize@0.15.0-beta.287.patch '@xterm/addon-webgl@0.20.0-beta.286': hash: 6da7d7770b6427246f2a0d057d97da418040e498068b41d0c2d3c6b20bf49258 path: config/patches/@xterm__addon-webgl@0.20.0-beta.286.patch '@xterm/xterm@6.1.0-beta.287': - hash: 082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6 + hash: 037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8 path: config/patches/@xterm__xterm@6.1.0-beta.287.patch node-pty@1.1.0: hash: 8fc49f17011b6611a5b8c00e83a6f12e14e75aada2b0ef26dc5393f8376d20e8 @@ -46,7 +46,7 @@ importers: version: 2.5.6 '@xterm/addon-serialize': specifier: 0.15.0-beta.287 - version: 0.15.0-beta.287(patch_hash=81575700d58b62f9262d302aa4ae43b445a6273d579cd75dd6729c8883011ab9)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.15.0-beta.287(patch_hash=96f70e83261df6a29ad7590feb08b988670655ced7596e77253d524f73f608dd)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/headless': specifier: 6.1.0-beta.287 version: 6.1.0-beta.287 @@ -206,25 +206,25 @@ importers: version: 5.2.0(rolldown-vite@7.3.1(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)(@types/node@25.9.5)(jiti@2.7.0)(yaml@2.8.4)) '@xterm/addon-fit': specifier: 0.12.0-beta.287 - version: 0.12.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.12.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/addon-ligatures': specifier: 0.11.0-beta.287 - version: 0.11.0-beta.287(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.11.0-beta.287(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/addon-search': specifier: 0.17.0-beta.287 - version: 0.17.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.17.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/addon-unicode11': specifier: 0.10.0-beta.287 - version: 0.10.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.10.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/addon-web-links': specifier: 0.13.0-beta.287 - version: 0.13.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.13.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/addon-webgl': specifier: 0.20.0-beta.286 - version: 0.20.0-beta.286(patch_hash=6da7d7770b6427246f2a0d057d97da418040e498068b41d0c2d3c6b20bf49258)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)) + version: 0.20.0-beta.286(patch_hash=6da7d7770b6427246f2a0d057d97da418040e498068b41d0c2d3c6b20bf49258)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)) '@xterm/xterm': specifier: 6.1.0-beta.287 - version: 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + version: 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -283,8 +283,8 @@ importers: specifier: ^17.0.1 version: 17.0.6 mermaid: - specifier: ^11.15.0 - version: 11.15.0 + specifier: ^11.16.0 + version: 11.16.0 monaco-editor: specifier: ^0.55.1 version: 0.55.1 @@ -1041,8 +1041,8 @@ packages: resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} - '@mermaid-js/parser@1.1.1': - resolution: {integrity: sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==} + '@mermaid-js/parser@1.2.0': + resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==} '@modelcontextprotocol/sdk@1.29.0': resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} @@ -5211,8 +5211,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@11.15.0: - resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==} + mermaid@11.16.0: + resolution: {integrity: sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA==} micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -7511,7 +7511,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@mermaid-js/parser@1.1.1': + '@mermaid-js/parser@1.2.0': dependencies: '@chevrotain/types': 11.1.2 @@ -9582,39 +9582,39 @@ snapshots: '@xmldom/xmldom@0.8.13': {} - '@xterm/addon-fit@0.12.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-fit@0.12.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) - '@xterm/addon-ligatures@0.11.0-beta.287(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-ligatures@0.11.0-beta.287(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) lru-cache: 11.5.1 opentype.js: 2.0.0 - '@xterm/addon-search@0.17.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-search@0.17.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) - '@xterm/addon-serialize@0.15.0-beta.287(patch_hash=81575700d58b62f9262d302aa4ae43b445a6273d579cd75dd6729c8883011ab9)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-serialize@0.15.0-beta.287(patch_hash=96f70e83261df6a29ad7590feb08b988670655ced7596e77253d524f73f608dd)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) - '@xterm/addon-unicode11@0.10.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-unicode11@0.10.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) - '@xterm/addon-web-links@0.13.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-web-links@0.13.0-beta.287(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) - '@xterm/addon-webgl@0.20.0-beta.286(patch_hash=6da7d7770b6427246f2a0d057d97da418040e498068b41d0c2d3c6b20bf49258)(@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6))': + '@xterm/addon-webgl@0.20.0-beta.286(patch_hash=6da7d7770b6427246f2a0d057d97da418040e498068b41d0c2d3c6b20bf49258)(@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8))': dependencies: - '@xterm/xterm': 6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6) + '@xterm/xterm': 6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8) '@xterm/headless@6.1.0-beta.287': {} - '@xterm/xterm@6.1.0-beta.287(patch_hash=082a4e714662e81b21d386f2c1de4c9dfd13e195c2497e9162b7e87f86b6a9b6)': {} + '@xterm/xterm@6.1.0-beta.287(patch_hash=037272642db6a9bf5242c02acacf8fc41f4c6e91268d8a47ea083c98fb2535b8)': {} abbrev@4.0.0: {} @@ -11647,11 +11647,11 @@ snapshots: merge2@1.4.1: {} - mermaid@11.15.0: + mermaid@11.16.0: dependencies: '@braintree/sanitize-url': 7.1.2 '@iconify/utils': 3.1.1 - '@mermaid-js/parser': 1.1.1 + '@mermaid-js/parser': 1.2.0 '@types/d3': 7.4.3 '@upsetjs/venn.js': 2.0.0 cytoscape: 3.33.3 diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index e78652d4198..4c790282bb0 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -224,10 +224,18 @@ Wait until every expected Dispatch settles, not for a fixed number of batches: ```bash orca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json -# Process every message in the returned Delivery, then atomically ack and continue: +# Process every message. For each accepted worker_done that is not immediately reused: +orca orchestration worker-release --dispatch --json +# Acknowledge only after every message and required release decision is handled: orca orchestration check --ack --wait --types worker_done,escalation,question --timeout-ms 900000 --json ``` +After processing each accepted `worker_done`, choose the terminal's next owner before you acknowledge the Delivery or wait again. If the same exact agent has an immediate follow-up Task, read the `worker.agent_terminal_handle` field of `worker-show --dispatch --json`, then run `orca orchestration worker-start --task --terminal --json` so Orca transfers cleanup ownership to the new Dispatch. Otherwise run `orca orchestration worker-release --dispatch --json`. + +Run `worker-release` after both succeeded and failed `worker_done` reports unless the user explicitly asked to keep that worker live. Release is post-completion cleanup, not cancellation: Orca first preserves inspectable output, then closes only the exact agent terminal owned by that settled Dispatch. Reused or pre-existing terminals, setup terminals, coordinators, active workers, user-taken-over terminals, and identities Orca cannot prove are retained. If the user explicitly asks to keep the live terminal for debugging, record that exception with `orca orchestration worker-retain --dispatch --json` instead of silently skipping cleanup. When the user is finished, the same Dispatch can be passed to `worker-release`, which clears the requested retention and releases the terminal. + +Do not release a worker because of a timeout, TUI idle state, heartbeat, status, question, escalation, or rejected/stale `worker_done`. If release returns `release_pending` or `release_unknown`, do not substitute `terminal close`; follow the exact recovery action in the receipt. A replayed Delivery may repeat `worker-release` safely. + Workers report exactly once using the IDs and capability injected by Orca; they do not supply Run/server/terminal identity: ```bash @@ -364,11 +372,12 @@ Wait for `tui-idle` before dispatching. Always pass `--timeout-ms`; real coding - Workers with a valid live preamble must send `worker_done` exactly once from their own terminal with an explicit `--outcome succeeded` or `--outcome failed`: `orca orchestration send --type worker_done --subject "" --body "<3-sentence summary: what you did, what you found, what's left>" --task-id --dispatch-id --outcome succeeded --files-modified "path/a" --report-path "" --json` - A failed outcome is still a terminal report, but Orca records both the Dispatch and Task as failed. Never encode failure only in the subject/body. -- After sending `worker_done`, end your turn and idle at the agent prompt. Do not poll or keep calling `orca orchestration check`; the coordinator re-engages you with a fresh preamble + TASK block delivered as new terminal input. +- After sending `worker_done`, end your turn and idle at the agent prompt. The coordinator may reuse or release this terminal after it processes your report; do not start more work, poll, or attempt to close the terminal yourself. If it reuses you, it re-engages you with a fresh preamble + TASK block delivered as new terminal input. - For long tasks, send heartbeat/status only when the preamble asks for it, including both IDs: `orca orchestration send --type heartbeat --subject "alive" --payload '{"taskId":"","dispatchId":"","phase":"implementing"}' --json` - If blocked before completion, use `ask`; use `escalation` only when ownership is valid and the coordinator must intervene. - Treat preambles inherited through terminal history or full handoffs as stale unless the current prompt explicitly keeps that coordinator in the loop. +- Coordinators must account for every settled worker terminal before waiting again or ending the turn: immediately reuse the exact worker for a new Dispatch, explicitly retain it at the user's request with `worker-retain`, or run `worker-release`. Do not leave a completed worker live merely to inspect output; released workers remain readable through `worker-read`. - Coordinators should use `task-list --ready` as external memory, dispatch parallel waves, and avoid dependency chains deeper than 3-4 steps. ## Example @@ -383,6 +392,6 @@ orca orchestration check --wait --types worker_done,escalation,question --timeou ## Next Action -Coordinator: confirm `orca status --json`, create or bind a Run, inspect `task-list`/`dispatch-show` if inheriting state, then use the explicit supervised loop (`task-create` -> `worker-start` -> `check --wait`). Use low-level terminal creation plus `dispatch --inject` only when the composed start does not express the needed topology. +Coordinator: confirm `orca status --json`, create or bind a Run, inspect `task-list`/`dispatch-show` if inheriting state, then use the explicit supervised loop (`task-create` -> `worker-start` -> `check --wait`). Use low-level terminal creation plus `dispatch --inject` only when the composed start does not express the needed topology. After every accepted `worker_done`, either transfer the exact terminal to an immediate follow-up Dispatch or run `worker-release` before the next wait. Worker: if the current prompt contains a live dispatch preamble, do the task, use `ask` for blocking questions, and send `worker_done` once with the required payload. If the preamble is stale or absent, do not send lifecycle messages; inspect state or treat the prompt as an ordinary handoff. diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index 748d62dd1a6..0609150c458 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -30,7 +30,7 @@ const ORCA_LINEAR_MARKDOWN = "---\nname: orca-linear\ndescription: >-\n Use Orc const ORCA_PER_WORKSPACE_ENV_MARKDOWN = "---\nname: orca-per-workspace-env\ndescription: >-\n Set up, review, debug, or validate Orca per-workspace environment recipes —\n on-demand, disposable runtimes (cloud sandboxes, VMs, or local) created fresh\n for each workspace. Covers first-time setup (provider prerequisites, the\n reusable base snapshot, the coding-agent auth snapshot, credentials, and\n state), not just the per-workspace lifecycle scripts. Use to stand up\n per-workspace environments, fix an `environmentRecipes` entry in `orca.yaml`, scaffold\n provider lifecycle scripts, or resolve an `orca vm recipe doctor` failure.\n---\n\n# Per-Workspace Environments\n\nHelp a user stand up and maintain a repo-owned per-workspace environment recipe end to end. Each\nworkspace gets its own on-demand, disposable runtime (a cloud sandbox, a VM, or a local one),\ncreated fresh and torn down after.\n\nOrca is a **thin wrapper**: you guide, detect, and scaffold; you never own the user's cloud account,\nbilling, images, or credentials.\n\n- **You DO:** sequence the setup, detect what's detectable (provider CLI present/logged-in? recipe\n present? `doctor` passing?), scaffold provider-templated scripts the user fills in, drive the slow\n snapshot/auth phases with the user, and always show the next action.\n- **You DO NOT:** create accounts, choose plans/regions, invent org/project/scope ids, store or print\n secrets, or run anything that spends money without an explicit user OK.\n\nFirst-time setup has **four phases before the per-workspace recipe runs** — easy to miss, so walk\nthem in order:\n\n1. **Prerequisites** — cloud account, provider CLI, scope/project, plan limits, git token (§2).\n2. **Base snapshot** — reusable image: tools + repo + headless build, snapshotted once (§3).\n3. **Agent-auth snapshot** — boot the base, run interactive device-auth, re-snapshot (§4).\n4. **State** — thread snapshot id / scope / project / port between phases via a state file (§6).\n\nThen the **per-workspace contract** (create/suspend/resume/destroy) runs fast (§8).\n\n**The one branch that shapes everything — connection mode:** **Orca-server** (`create` runs `orca serve`\nin the env and emits a `pairingCode`; §7c/§7f) vs **SSH** (`create` runs no server and emits a\n`connection.type:\"ssh\"` block Orca dials into; §7g/§7h). Settle this first — it changes the `create`\noutput shape and half the templates.\n\n**Quick-start (happy path):** interview the user (connection mode Orca-server vs SSH, provider, agent CLI,\ngit auth — §1.2) + read the provider's CLI docs → scaffold `scripts/orca-vm/` from §7 → run the\nbase-snapshot script, then the auth script (you invoke these by hand; not via `orca.yaml`) → wire\n`environmentRecipes` in `orca.yaml` → `orca vm recipe doctor --json` (free) → then the `--provision`\nself-test loop (§9) until it passes.\n\n---\n\n## 1. Setup workflow\n\nDrive these with the user. **[CHECKPOINT]** steps need explicit confirmation — they spend money, take\na long time, or need the user at the keyboard. Never create an Orca workspace or commit unless asked.\n\n1. **Inspect the repo** for an existing `environmentRecipes` entry, `scripts/orca-vm/`, a state file, or setup\n notes. If a working recipe exists, jump to Doctor (§9) instead of rebuilding.\n2. **Interview the user up front** — gather these choices and confirm them back before scaffolding\n anything. Don't pick for them (§11); don't guess.\n - **Connection mode:** how Orca attaches to the environment — an **Orca server** (the VM runs\n `orca serve` and Orca pairs over its pairing URL; worked example §7f) or **SSH** (Orca connects to\n the host over SSH; §7g). This decides the recipe's connection shape, so settle it first.\n - **Provider:** Vercel Sandbox, Fly, Modal, an existing SSH host, … For non-obvious providers, also\n ask scope/project/region and plan limits (§2). Then **read that provider's CLI/SDK docs** (or\n ` --help`) before scaffolding — you need its exact create/exec/snapshot/remove verbs.\n If a provider advertises `ssh`, verify whether it exposes a real dialable SSH target\n (host/port/user/key or proxy command) or only a provider-mediated interactive shell; Orca SSH mode\n needs the former.\n - **Coding-agent CLI + account:** which agent runs in the VM (`codex`, `claude`, …) and that the user\n has an account for it — it gets logged in during the Phase-3 auth snapshot (§4).\n - **Git auth:** the token source for cloning a private repo (`GH_TOKEN`/`GITHUB_TOKEN` or `gh auth\n token`; §5).\n3. **Check prerequisites (§2)** — detect the provider CLI + auth and confirm the items above are in\n place before any paid step.\n4. **Scaffold scripts + state file** from §7 (worked Vercel example: §7f; SSH host: §7g; Docker SSH:\n §7h; Windows: §7i), filling in the provider's real commands. Make them executable.\n5. **[CHECKPOINT] Build the base snapshot (§3)** — paid, slow.\n6. **[CHECKPOINT] Authenticate the agent (§4)** — interactive; the user follows a URL/code. **You cannot\n drive this step** — you run commands non-interactively, so there's no TTY for `docker exec -it` /\n `ssh -t` to prompt against. The **user** runs the Phase-3 login in their own terminal (or via the\n Claude Code harness bang-prefix — `! `, with the required space after `!`); you scaffold and drive\n the non-interactive phases around it. After kicking it off, **ask the user to report back once the login\n finishes** — you can't observe it completing, and you need that confirmation before resuming the\n non-interactive steps (base/auth commit, doctor, provision).\n7. **Wire the recipe** so `orca.yaml` points create/suspend/resume/destroy at the scripts (§8). The\n workspace composer reads `environmentRecipes` from the project's primary checkout of `orca.yaml`, **not** from\n a feature branch or worktree. So a recipe added only on a branch won't appear as a \"Run on\" option\n until that `orca.yaml` change is committed and merged to the project's primary branch. Tell the user\n this up front: `doctor`/`--provision` validate the scripts from the working copy on any branch, but\n creating a workspace from the recipe in the picker needs it on primary.\n8. **Dry-run doctor** — `orca vm recipe doctor --repo-path --json` (free, static; §9).\n Fix every failure before going live.\n9. **[CHECKPOINT] Live self-test** — get the user's OK once, then run\n `orca vm recipe doctor --provision --json` as a loop: it runs create → validates →\n destroys, and on failure returns a full transcript. Read it, fix the scripts, and re-run yourself until\n it passes (§9). Spends cloud money; the one approval covers the loop.\n10. **[CHECKPOINT] Optional workspace test** — only if asked: create a workspace via the picker, then\n verify sleep/wake/delete.\n\n---\n\n## 2. Phase 1 — Prerequisites\n\nThe user's responsibility; verify what's verifiable, ask for the rest, invent nothing. State which\nitems you verified vs. which the user asserted.\n\n- **Connection mode** (Orca server vs SSH) confirmed with the user — see §1 step 2; it shapes the recipe.\n- **Cloud account + plan** that allows sandboxes/VMs. Ask.\n- **Provider CLI installed + authenticated** — detect (`command -v `), check auth (e.g.\n `vercel whoami`). If missing, point at the provider's docs; don't log them in.\n- **Scope / project / region** the sandboxes live under. Ask; flows into every script via state.\n- **Plan / timeout / RAM caps.** Record them — e.g. Vercel Hobby caps sandbox timeout at **45m**,\n which limits both the base build and per-workspace runtime (see §10).\n- **Git token for private repos** (`GH_TOKEN`/`GITHUB_TOKEN`, or the provider's git auth; can fall back\n to `gh auth token`). See §5.\n- **Coding-agent CLI choice** (`codex`, `claude`…) and that the user has an account — it gets\n authenticated into the VM in Phase 3.\n\n---\n\n## 3. Phase 2 — Base snapshot (the reusable image)\n\nBuild **once**, snapshot, and every workspace boots from it in seconds instead of rebuilding.\nProvisioning + building takes a while (often ~20–30 min), so it runs behind a checkpoint. The script\nshape is §7a; key points:\n\n- Build the **headless Electron main only** (not the renderer) so it fits in plan RAM.\n- Use the VM image's package manager (`apt`/`dnf`/`apk`, per the base distro — not the provider brand).\n- Clone with the git token via `GIT_ASKPASS` (§5).\n- **Trap errors and remove the half-built sandbox** so a crash doesn't leave a paid resource running.\n- Snapshot the stopped sandbox, parse the snapshot id, and write it + scope/project/port/repo to state.\n\n---\n\n## 4. Phase 3 — Agent-auth snapshot (interactive)\n\nThe base snapshot has the agent CLI installed but **not logged in**, and per-workspace VMs are\nephemeral — so authenticate once and bake it into a second snapshot layer. Script shape is §7b:\n\n1. Boot a sandbox from the base `snapshotId` (from state).\n2. Run the agent's login **interactively** (`--interactive --tty`); the user completes the URL/code in\n their browser. On a **headless VM this must be the device-auth flow** (e.g. `codex login --device-auth`),\n **not** plain `codex login`: the default OAuth login starts a loopback callback server on a container\n port the host browser can't reach, so it hangs. Device-auth instead prints a URL + code the user opens\n on the **host**.\n3. Verify login; **refuse to snapshot an unauthenticated VM.** Prefer the status command's **exit code**\n (most agent CLIs exit non-zero when unauthenticated). If you grep instead, agent status often goes to\n **stderr** (e.g. `codex login status` prints \"Logged in using ChatGPT\" there), so **fold stderr first**\n (`... 2>&1 | grep …`) and match the agent's **exact success line** — never `grep -qi 'logged in'`, which\n also matches \"**not** logged in\" and would commit an unauthenticated image.\n4. Re-snapshot, parse the new id, and overwrite `snapshotId` in state to the authenticated image\n (recording `authSourceSnapshotId`). Remove the auth sandbox.\n\n**You can't drive step 2 yourself** (you run commands non-interactively — no TTY). The **user** runs it in\ntheir own terminal, or via the Claude Code harness bang-prefix (`! `, with the required space after\n`!`). You scaffold/boot the sandbox and run steps 3–4, but **you cannot observe the interactive login\nfinishing** — so **ask the user to tell you when it's done** before you verify and re-snapshot.\n\nIf the agent's credentials are short-lived, warn that the snapshot may need periodic re-auth (§10).\n\nFor disposable runtimes, do **not** treat a host agent config directory (for example `~/.codex`) as the\nauth snapshot by bind-mounting or copying it wholesale. Agent homes often contain sqlite state, hook\napproval state, caches, logs, and host-specific env/config. Instead, authenticate/configure the agent\ninside the disposable runtime and snapshot/commit that runtime layer.\n\n---\n\n## 5. Credentials\n\n- **Never** commit secrets or put them in `userData`, recipe JSON, comments, docs, or the state file.\n- **Git token:** read from env (`GH_TOKEN`/`GITHUB_TOKEN`), falling back to `gh auth token`. Pass to the\n VM only via the provider's ephemeral `--env`. Inside the VM, use a `GIT_ASKPASS` helper with\n `x-access-token` (not the token in the clone URL) and `GIT_TERMINAL_PROMPT=0` so a missing token fails\n fast instead of hanging. When you write the helper from inside `bash -lc` under `set -u`, escape the\n positional arg and the token (`\\$1`, `\\$GH_TOKEN`) so they land **literally** and resolve at git-runtime\n — an unescaped `$1` aborts with \"unbound variable\", and a literal `$GH_TOKEN` keeps the real token out of\n the written file. `rm -f` the helper after the clone/fetch.\n- **Provider auth:** rely on the provider CLI's logged-in session, not checked-in keys.\n- **Agent auth:** lives in the authenticated snapshot (Phase 3) — never a file you write or commit.\n- State holds only **non-secret** wiring (snapshot ids, scope, project, port, repo url/ref).\n\n---\n\n## 6. State file\n\nA repo-local JSON file (e.g. `scripts/orca-vm/-state.json`) threads non-secret values between\nphases. Each script resolves values as **env var → state → built-in fallback**, and merges its outputs\nback. Phase 2 writes the base `snapshotId`; Phase 3 overwrites it with the authenticated snapshot;\nper-workspace `create` boots from `snapshotId`.\n\n```json\n{\n \"baseName\": \"orca-base\",\n \"snapshotId\": \"snap_authenticated_image_id\",\n \"authSourceSnapshotId\": \"snap_base_image_id\",\n \"scope\": \"\",\n \"project\": \"\",\n \"port\": 7331,\n \"repoUrl\": \"https://host/org/repo.git\",\n \"repoRef\": \"main\",\n \"projectRoot\": \"/abs/path/on/remote/repo\"\n}\n```\n\n---\n\n## 7. Script templates (provider-agnostic shapes)\n\nScaffold under `scripts/orca-vm/`. These are **shapes** — fill in the provider's real commands. All\nreserve stdout for the final JSON and log progress to stderr. Include a shared `json_value ` /\n`env_value ` reader (env → state → fallback) in each.\n\n**Where each script runs:**\n\n- **Local-side** (`create`/`suspend`/`resume`/`destroy` + the base-snapshot/auth scripts the user\n invokes) runs **on the user's desktop**, so it must run on their OS. macOS/Linux: `#!/usr/bin/env\n bash`, `set -euo pipefail`, quoted paths. **Windows:** a bare `.sh` won't run — scaffold `.ps1`/`.cmd`\n or require WSL/Git-Bash and point `orca.yaml` at the right launcher.\n- **Remote-side** (commands you `exec` *inside* the Linux VM) always runs in the VM's Linux shell, so\n bash is fine there regardless of the user's OS.\n\n### 7a. Base-snapshot (`-base-snapshot.sh`) — Phase 2\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# resolve base_name/repo_url/repo_ref/project_root/port/scope/project/timeout (env→state→fallback)\n# resolve gh token: GH_TOKEN | GITHUB_TOKEN | `gh auth token`\n# 1. provision a sandbox (timeout/vcpus/published port/snapshot retention); trap: remove on error\n# 2. remote exec (long timeout): install pkgs + gh + corepack/pnpm + agent CLI;\n# clone with GIT_ASKPASS(token); write headless main-only build config;\n# dev setup; pnpm install; build CLI; build headless electron main; smoke-check tools\n# 3. snapshot stopped sandbox; parse snapshot id (fail if unparseable)\n# 4. merge { baseName, snapshotId, projectRoot, repoUrl, repoRef, port, scope, project } into state\n# print only the state JSON to stdout\n```\n\nWorked Vercel commands for this phase are in §7f. You run this script by hand (not via `orca.yaml`),\nafter exporting the first-run inputs the state file doesn't have yet — e.g. provider scope/project, the\nrepo URL/ref, and a git token (`GH_TOKEN`); later runs read them back from state.\n\n### 7b. Auth (`-base-auth.sh`) — Phase 3\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# read source snapshot from state.snapshotId (fail if absent); auth_name=\"${base_name}-auth\"\n# 1. boot sandbox from source snapshot; trap: remove on error\n# 2. INTERACTIVE/TTY remote exec: agent login — user completes URL/code. Headless VM: MUST use the\n# device-auth flow (e.g. `codex login --device-auth`) — plain OAuth login binds a loopback callback\n# port the host can't reach and hangs. User runs this themselves (you have no interactive TTY); ask\n# them to report back when it's done before continuing.\n# 3. verify login, then refuse to snapshot if not logged in. Prefer the status command's EXIT CODE (most\n# agent CLIs exit non-zero when unauthenticated) over string-matching. If you must grep, fold stderr\n# first (`status 2>&1 | grep …` — many agents print the success line there) and match the agent's exact\n# success line; never `grep -qi 'logged in'`, which also matches \"not logged in\". Codex example: §7f.\n# 4. snapshot; parse new id\n# 5. merge { snapshotId:, authSourceSnapshotId: } into state; remove auth sandbox\n# print only the state JSON to stdout\n```\n\n### 7c. Create (`-create.sh`) — per workspace\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# read authenticated snapshotId/scope/project/port/repo*/project_root (env→state→fallback)\n# fail clearly if snapshotId is missing (point back to Phases 2–3)\n# name = orca-${ORCA_VM_RECIPE_ID}-${ORCA_VM_INSTANCE_ID} (sanitized, length-capped)\n# 1. boot sandbox from snapshotId with a published port; capture the public URL → pairing address\n# (an externally reachable wss:// URL); trap: remove sandbox on error\n# 2. remote exec: ensure repo at desired commit; rebuild only if commit changed (cache marker)\n# 3. remote exec: start orca serve in the background and read the recipe JSON it writes (see below)\n# 4. print serve's JSON to stdout, optionally enriched with userData:\n# { schemaVersion:1, pairingCode, projectRoot, userData:{ provider, resourceId:name, snapshotId } }\n```\n\n**The exact `orca serve` invocation and its output (verified — do not improvise the flags).** Inside the\nVM, run:\n\n```bash\norca serve \\\n --port \"$PORT\" \\\n --project-root \"$ABS_REPO_PATH_ON_REMOTE\" \\\n --pairing-address \"$EXTERNAL_WSS_URL\" \\\n --recipe-json\n```\n\n**Binary name:** in a VM built from source (the Phase-2 flow), run it as `pnpm exec orca-dev serve …`\nfrom the repo root — `orca-dev` is the in-repo entrypoint and is what the §7f example uses. Plain\n`orca serve …` is the same command when the built CLI is installed on the VM's PATH. The flags/output\nare identical either way.\n\nThere is **no `--host` flag**. `--project-root` must be an absolute directory on the remote. With\n`--recipe-json` the server **stays running** and prints exactly this single object to **stdout**, then\nkeeps serving:\n\n```json\n{ \"schemaVersion\": 1, \"pairingCode\": \"\", \"projectRoot\": \"\" }\n```\n\n`pairingCode` is the pairing URL, already pointing at whatever you passed as `--pairing-address` — so set\n`--pairing-address` to the externally reachable address and **pass `pairingCode` through unchanged; never\nhand-rewrite it**. Because serve runs in the foreground and doesn't exit, redirect its stdout to a file\nand poll until that file parses as JSON (and bail if the process dies — dump its stderr log). Your\n`create` script then prints that JSON (optionally merging `userData`). Concrete pattern: §7f.\n\n### 7d. Suspend / resume / destroy — per workspace\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\npayload=\"$(cat)\" # Orca passes lifecycle JSON on stdin\nresource_id=\"$(node -e 'const d=JSON.parse(process.argv[1]); process.stdout.write(d.recipeResult?.userData?.resourceId ?? \"\")' \"$payload\")\"\n[ -n \"$resource_id\" ] || { echo \"No resource id in lifecycle payload\" >&2; exit 1; }\n# suspend: provider suspend \"$resource_id\"\n# resume: provider resume \"$resource_id\"; then RE-EMIT fresh recipe JSON (pairing may change)\n# destroy: provider remove \"$resource_id\" (or set destroy: none in orca.yaml)\n```\n\n### 7e. State file — scaffold with scope/project/repo filled in and snapshot ids empty (§6).\n\n### 7f. Worked example — Vercel Sandbox (all three phases)\n\nA real, working shape (the Vercel surface is a CLI: `vercel sandbox create|exec|snapshot|remove`). Adapt\nnames; verify flags against `vercel sandbox --help` for the user's CLI version before relying on them.\nThese ground §7a (base snapshot) and §7b (auth), which are otherwise generic skeletons.\n\n**Phase 2 — base snapshot (§7a):** provision → install tools + clone + headless build → snapshot.\n\n```bash\n# provision a fresh build sandbox (retain a couple of snapshots); trap-remove on error\nvercel sandbox create --name \"$base\" --runtime node24 --timeout 30m --vcpus 4 --publish-port \"$port\" \\\n --snapshot-expiration 30d --keep-last-snapshots 2 \"${vercel_args[@]}\" >&2\n# remote build (long timeout): install pkgs+gh+pnpm+agent CLI, clone with GIT_ASKPASS (write the helper\n# with LITERAL \\$1/\\$GH_TOKEN so they resolve at git-runtime, not write-time — see §5/§7f create — then\n# `rm -f /tmp/askpass.sh`), write the headless main-only build config (drop the renderer), dev setup,\n# build CLI + headless main, smoke-check\nvercel sandbox exec \"$base\" \"${vercel_args[@]}\" --timeout 25m --env \"GH_TOKEN=$gh_token\" … -- bash -lc '…build…' >&2\n# snapshot the STOPPED sandbox and parse the id from CLI output (fail if unparseable)\nout=\"$(vercel sandbox snapshot \"$base\" --stop --expiration 30d \"${vercel_args[@]}\" 2>&1)\"; printf '%s\\n' \"$out\" >&2\nsnapshot_id=\"$(printf '%s\\n' \"$out\" | sed -nE 's/.*(snap_[A-Za-z0-9]+).*/\\1/p' | tail -1)\"\n# merge { baseName, snapshotId, scope, project, port, repoUrl, repoRef, projectRoot } into state; print state JSON\n```\n\n**Phase 3 — agent-auth snapshot (§7b):** boot the base, log the agent in interactively, re-snapshot.\n(`codex` below is an example — substitute the user's chosen agent's login/status verbs, e.g. `claude`.)\n\n```bash\nvercel sandbox create --name \"$auth\" --snapshot \"$snapshot_id\" --timeout 30m --publish-port \"$port\" \"${vercel_args[@]}\" >&2\n# INTERACTIVE — the USER runs this in their own terminal (you have no interactive TTY) and completes the\n# URL/code on the HOST. --device-auth is MANDATORY on a headless VM: plain `codex login` binds a loopback\n# callback port the host browser can't reach and hangs. Ask the user to report back when login finishes.\nvercel sandbox exec --interactive --tty \"$auth\" \"${vercel_args[@]}\" -- bash -lc 'codex login --device-auth'\n# refuse to snapshot an unauthenticated VM — fold stderr, match codex's exact success line (§4)\nvercel sandbox exec \"$auth\" \"${vercel_args[@]}\" --timeout 30s -- bash -lc 'codex login status 2>&1' | grep -Eqi 'Logged in using ChatGPT|Logged in via device' \\\n || { echo \"agent not logged in; not snapshotting\" >&2; exit 1; }\nout=\"$(vercel sandbox snapshot \"$auth\" --stop --expiration 30d \"${vercel_args[@]}\" 2>&1)\"; printf '%s\\n' \"$out\" >&2\nnew_id=\"$(printf '%s\\n' \"$out\" | sed -nE 's/.*(snap_[A-Za-z0-9]+).*/\\1/p' | tail -1)\"\n# overwrite state.snapshotId = new_id, record authSourceSnapshotId = snapshot_id; remove the auth sandbox\n```\n\n**Per-workspace `create`** (the fast path):\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# resolve from env→state→fallback: snapshot_id, scope, project, port, repo_url, repo_ref, project_root\nvercel_args=(); [ -n \"$scope\" ] && vercel_args+=(--scope \"$scope\"); [ -n \"$project\" ] && vercel_args+=(--project \"$project\")\n[ -n \"$snapshot_id\" ] || { echo \"snapshotId missing — run Phases 2–3 first\" >&2; exit 1; }\ngh_token=\"${GH_TOKEN:-${GITHUB_TOKEN:-$(command -v gh >/dev/null 2>&1 && gh auth token 2>/dev/null || true)}}\"\nname=\"orca-${ORCA_VM_RECIPE_ID:-vercel-sandbox}-${ORCA_VM_INSTANCE_ID:-$(date +%s)}\" # sanitize+cap to 63 chars\n\n# Arm cleanup BEFORE create so a failing create can't leak a half-built paid sandbox.\ncleanup_on_error() { [ \"$?\" -ne 0 ] && vercel sandbox remove \"$name\" \"${vercel_args[@]}\" >/dev/null 2>&1 || true; }\ntrap cleanup_on_error EXIT\n\n# 1. boot from the authenticated snapshot, publish the serve port\ncreate_output=\"$(vercel sandbox create --name \"$name\" --snapshot \"$snapshot_id\" \\\n --timeout 30m --publish-port \"$port\" \"${vercel_args[@]}\" 2>&1)\"; printf '%s\\n' \"$create_output\" >&2\n# Vercel prints the published https URL; derive the external wss:// pairing address from it\npublic_url=\"$(printf '%s\\n' \"$create_output\" | sed -nE 's#.*(https://[^[:space:]]+\\.vercel\\.run).*#\\1#p' | head -1)\"\n[ -n \"$public_url\" ] || { echo \"no published URL in create output\" >&2; exit 1; }\npairing_ws=\"${public_url/https:\\/\\//wss://}\"\n\n# 2. (remote) ensure the repo is at the right commit; rebuild only if the commit changed (cache marker)\nvercel sandbox exec \"$name\" \"${vercel_args[@]}\" --timeout 20m \\\n --env \"GH_TOKEN=$gh_token\" --env \"ORCA_PROJECT_ROOT=$project_root\" \\\n --env \"ORCA_REPO_URL=$repo_url\" --env \"ORCA_REPO_REF=$repo_ref\" \\\n -- bash -lc 'set -euo pipefail; cd \"$ORCA_PROJECT_ROOT\"; \\\n # Re-establish git auth for the private-repo fetch (why + full rationale: §5); else it hangs on a prompt.\n # Load-bearing escaping: \\$1 and \\$GH_TOKEN must land LITERALLY and resolve at git-runtime. Test after\n # any edit here — reformatting the nested printf/node quoting silently breaks the fetch or leaks the token.\n if [ -n \"${GH_TOKEN:-}\" ]; then \\\n printf \"%s\\n\" \"#!/usr/bin/env bash\" \"case \\\"\\$1\\\" in *Username*) echo x-access-token;; *Password*) echo \\\"\\$GH_TOKEN\\\";; esac\" > /tmp/askpass.sh; \\\n chmod 700 /tmp/askpass.sh; export GIT_ASKPASS=/tmp/askpass.sh GIT_TERMINAL_PROMPT=0; fi; \\\n git fetch origin \"$ORCA_REPO_REF\"; \\\n git checkout -B \"$ORCA_REPO_REF\" FETCH_HEAD; \\\n rm -f /tmp/askpass.sh; \\\n c=\"$(git rev-parse HEAD)\"; [ -f .orca-built ] && [ \"$(cat .orca-built)\" = \"$c\" ] || { \\\n pnpm install --prefer-offline && pnpm run build:cli && \\\n node config/scripts/run-electron-vite-build.mjs --config config/electron-vite.vm-serve.config.ts && \\\n printf \"%s\" \"$c\" > .orca-built; }' >&2\n\n# 3. (remote) start orca serve in the background, writing recipe JSON to a file; poll until it parses\nrecipe_json=\"$(vercel sandbox exec \"$name\" \"${vercel_args[@]}\" --timeout 60s \\\n --env \"ORCA_PORT=$port\" --env \"ORCA_PROJECT_ROOT=$project_root\" --env \"ORCA_PAIRING_ADDRESS=$pairing_ws\" \\\n -- bash -lc 'set -euo pipefail; cd \"$ORCA_PROJECT_ROOT\"; rm -f /tmp/orca-recipe.json /tmp/orca-serve.log; \\\n nohup pnpm exec orca-dev serve --port \"$ORCA_PORT\" --project-root \"$ORCA_PROJECT_ROOT\" \\\n --pairing-address \"$ORCA_PAIRING_ADDRESS\" --recipe-json >/tmp/orca-recipe.json 2>/tmp/orca-serve.log /dev/null 2>&1 && { cat /tmp/orca-recipe.json; exit 0; }; \\\n kill -0 \"$pid\" 2>/dev/null || { cat /tmp/orca-serve.log >&2; exit 1; }; sleep 0.25; \\\n done; cat /tmp/orca-serve.log >&2; echo \"serve recipe JSON timed out\" >&2; exit 1')\"\n\n# 4. print serve's JSON enriched with userData (single object on stdout)\nnode -e 'const p=JSON.parse(process.argv[1]); console.log(JSON.stringify({...p, schemaVersion:1,\n userData:{...p.userData, provider:\"vercel-sandbox\", resourceId:process.argv[2], snapshotId:process.argv[3]}}))' \\\n \"$recipe_json\" \"$name\" \"$snapshot_id\"\ntrap - EXIT\n```\n\n`suspend`/`resume`/`destroy` use `vercel sandbox stop|...|remove \"$resource_id\"` reading\n`userData.resourceId` from stdin (§7d). This is the **Orca-server** connection mode (the recipe emits a\npairing URL). If the user chose **SSH** in the §1 interview, use §7g instead.\n\n### 7g. Worked example — existing SSH host (SSH connection mode)\n\nSSH mode is **fundamentally different from §7c/§7f**, not a relabeling of them:\n\n- **`create` does NOT run `orca serve` and does NOT emit a `pairingCode`.** Orca itself connects to the\n host over its SSH relay, brings up the git + filesystem providers, and imports the repo. The script's\n only job is to make the host ready and **print SSH connection details** Orca will dial.\n- The result uses a `connection` block with `type: \"ssh\"` and a `target`, **not** the flat\n `pairingCode`/`projectRoot` shape. Exact shape (Orca rejects anything else):\n\n```json\n{\n \"schemaVersion\": 1,\n \"connection\": {\n \"type\": \"ssh\",\n \"projectRoot\": \"/abs/path/to/repo/on/host\",\n \"target\": {\n \"label\": \"my-box\",\n \"host\": \"192.0.2.10\",\n \"port\": 22,\n \"username\": \"ubuntu\",\n \"identityFile\": \"~/.ssh/id_ed25519\",\n \"jumpHost\": \"bastion.example.com\",\n \"proxyCommand\": \"cloudflared access ssh --hostname %h\",\n \"relayGracePeriodSeconds\": 0,\n \"portForwards\": []\n }\n }\n}\n```\n\n`label`, `host`, `port`, `username` are required; the rest are optional — omit any you don't need.\n\n**Networking → which `target` fields to set** (how *your desktop* reaches the box — there is no\n`orca serve` URL in SSH mode):\n\n- Public IP / DNS, or a Tailscale/VPN address → `host`; SSH port → `port` (usually 22).\n- Key auth → `identityFile` (add `identitiesOnly: true` if the agent has many keys).\n- Through a bastion → `jumpHost` (a `user@host` ProxyJump) **or** a full `proxyCommand` (e.g. an access\n proxy). Use one, not both.\n- A service port the workspace needs → add entries to `portForwards`.\n- `relayGracePeriodSeconds` (optional): how long Orca keeps the SSH relay alive after the workspace\n detaches before tearing it down; `0` = tear down immediately. Leave it off unless the user wants a\n reconnect grace window.\n\n**Toolchain & agent auth on a persistent (no-snapshot) host — do this ONCE, by hand, before wiring the\nrecipe** (there's no base image to bake; the host *is* the base). Run the §7f Phase-2 install steps and\nthe §7f Phase-3 ` login --device-auth` **directly over SSH on the host** (interactive, e.g.\n`ssh -t user@host ' login --device-auth'`). After that the host stays ready across workspaces.\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# resolve from env→state→fallback (default unset optionals to \"\"): ssh_username, host,\n# ssh_port (default 22), identity_file, jump_host, proxy_command, project_root, repo_url, repo_ref\n: \"${identity_file:=}\"; : \"${jump_host:=}\"; : \"${proxy_command:=}\" # avoid set -u aborts on optionals\ngh_token=\"${GH_TOKEN:-${GITHUB_TOKEN:-$(command -v gh >/dev/null 2>&1 && gh auth token 2>/dev/null || true)}}\"\nssh_target=\"${ssh_username}@${host}\"\nssh_opts=(-p \"$ssh_port\"); [ -n \"$identity_file\" ] && ssh_opts+=(-i \"$identity_file\")\n# Why: a fresh host's key isn't in known_hosts; a StrictHostKeyChecking prompt would HANG a\n# non-interactive create. Pre-add the key (or set the option) so it can't block.\nssh-keyscan -p \"$ssh_port\" \"$host\" >> \"$HOME/.ssh/known_hosts\" 2>/dev/null || true\n\n# 1. ensure the repo is present and at the right commit on the host (NO orca serve here)\nssh \"${ssh_opts[@]}\" \"$ssh_target\" \\\n \"GH_TOKEN='$gh_token' GIT_TERMINAL_PROMPT=0 bash -lc '\n set -euo pipefail\n [ -d \\\"$project_root/.git\\\" ] || git clone \\\"$repo_url\\\" \\\"$project_root\\\"\n cd \\\"$project_root\\\" && git fetch origin \\\"$repo_ref\\\" && git checkout -B \\\"$repo_ref\\\" FETCH_HEAD\n '\" >&2\n\n# 2. print the SSH connection block (NO pairingCode, NO orca serve). host/port/username tell Orca's\n# relay how to dial in; identityFile/jumpHost/proxyCommand/portForwards are emitted when set.\nnode -e 'const [host,port,user,idf,jh,pc,root]=process.argv.slice(1);\n const target={ label:\"per-workspace-host\", host, port:Number(port), username:user };\n if(idf) target.identityFile=idf; if(jh) target.jumpHost=jh; if(pc) target.proxyCommand=pc;\n // add target.portForwards=[...] here if the workspace needs forwarded service ports\n console.log(JSON.stringify({ schemaVersion:1, connection:{ type:\"ssh\", projectRoot:root, target } }))' \\\n \"$host\" \"$ssh_port\" \"$ssh_username\" \"$identity_file\" \"$jump_host\" \"$proxy_command\" \"$project_root\"\n```\n\n`suspend`/`resume`/`destroy`: on a persistent host there's usually nothing to tear down — set\n`destroy: none` and omit suspend/resume. (Orca still disconnects/reconnects its own SSH relay on\nsleep/wake/delete — that's separate from these scripts.)\n\nIf the SSH host is instead an **ephemeral/snapshot-capable VM** (your hypervisor, or a cloud VM with\nimage support), keep the §7f Phase-2/3 base-image model for provisioning, but still emit the\n`connection.type:\"ssh\"` block above instead of starting `orca serve`.\n\n### 7h. Worked example — local Docker SSH (SSH connection mode)\n\nLocal Docker can model an ephemeral SSH VM without cloud cost: build a base image with `sshd`, tools,\nrepo prerequisites, and the agent CLI; run an **interactive auth container** once; then `docker commit`\nthat container as the authenticated image used by per-workspace `create`.\n\nKey points:\n\n- Publish container SSH to a random localhost port (`-p 127.0.0.1::22`) and emit\n `connection.type:\"ssh\"` with `host:\"127.0.0.1\"`, that port, `username`, `identityFile`, and\n `identitiesOnly:true`.\n- Generate a repo-local SSH key if needed, but gitignore the private/public key files.\n- **Bake SSH host keys into the base image** (`ssh-keygen -A` at **build** time; at runtime only generate\n if absent). Ephemeral containers all present the **same** host key, so `known_hosts` on `127.0.0.1`\n doesn't churn as the published port rotates across workspaces (otherwise every container's freshly\n generated key collides on `localhost` and trips host-key-changed warnings).\n- The auth image is the Docker equivalent of Phase 3: the **user** runs the agent login **inside** the\n container (you can't drive it — you have no interactive TTY), configures proxy env/config, approves\n hooks, and you commit once they report it's done. On a headless container use the **device-auth** flow\n (§4). Verify login before committing — exit code, or fold stderr and match the exact success line (§4).\n- Do not bind-mount or copy the host's full agent home into the image. Let each container have writable\n agent state; only the committed auth image should carry reusable authenticated state.\n- If committing from an interactive shell, force the runtime entrypoint back to `sshd`:\n `docker commit --change='ENTRYPOINT [\"/usr/local/bin/orca-docker-ssh-entrypoint\"]' …`.\n- `destroy` should read `recipeResult.userData.resourceId` and run `docker rm -f \"$resource_id\"`.\n\nValidation before wiring/live use:\n\n```bash\ndocker image inspect \"$auth_image\" --format '{{json .Config.Entrypoint}}'\ndocker run -d --name \"$name\" -p 127.0.0.1::22 -e \"ORCA_SSH_PUBLIC_KEY=$pubkey\" \"$auth_image\"\ndocker ps -a --filter \"name=$name\"\ndocker logs \"$name\"\nssh -i \"$key\" -p \"$port\" -o IdentitiesOnly=yes user@127.0.0.1 'codex --version'\n```\n\nIf the container exits immediately, inspect logs before the cleanup trap removes it; a committed\ninteractive image with `ENTRYPOINT [\"bash\"]` is a common cause.\n\nAlso confirm the **host key is stable** across containers: the SSH `ssh -i … 127.0.0.1` dial should not\ntrigger a host-key-changed warning when a second container reuses the port. If it does, the host keys\nweren't baked into the base image (see the `ssh-keygen -A` point above).\n\n### 7i. Windows local-side scripts\n\nThe local-side scripts run on the user's desktop. On **Windows**, a bare `.sh` won't execute. Either\nrequire WSL/Git-Bash (and point `orca.yaml` at e.g. `bash ./scripts/orca-vm/.sh` via a `.cmd`\nlauncher), or scaffold PowerShell equivalents. Minimal PowerShell shape:\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } } (see §7g/§7h)\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe remote-side commands you run *inside* the Linux VM stay bash regardless of the desktop OS.\n\n---\n\n## 8. Per-workspace recipe contract (the fast path)\n\nOnce the authenticated snapshot exists, this runs on every workspace create. Define recipes in\n`orca.yaml`:\n\n```yaml\nenvironmentRecipes:\n - id: cloud-sandbox\n name: Cloud Sandbox\n create: ./scripts/orca-vm/cloud-sandbox-create.sh\n suspend: ./scripts/orca-vm/cloud-sandbox-suspend.sh\n resume: ./scripts/orca-vm/cloud-sandbox-resume.sh\n destroy: ./scripts/orca-vm/cloud-sandbox-destroy.sh\n```\n\n`create` runs **locally from the repo root** and prints **one** JSON object to stdout. Its shape depends\non the connection mode chosen in §1:\n\n**Orca-server mode** — boot the env, start `orca serve` in it, and print serve's result:\n\n```json\n{\n \"schemaVersion\": 1,\n \"pairingCode\": \"orca-pairing-code-or-url\",\n \"projectRoot\": \"/absolute/path/to/repo/on/remote\",\n \"userData\": { \"provider\": \"example\", \"resourceId\": \"provider-resource-id\" }\n}\n```\n\nHere `pairingCode` (from `orca serve --recipe-json`) and `projectRoot` are required; `schemaVersion` (`1`)\nand `userData` are optional.\n\n**SSH mode** — do **not** run `orca serve`; print the `connection.type:\"ssh\"` block instead (full shape +\nworked script in §7g). `pairingCode` is **not** used in SSH mode.\n\nLifecycle hooks (all run locally):\n\n- `create`: required. Prints recipe result JSON.\n- `suspend`: optional. Sleep; reads lifecycle payload on stdin.\n- `resume`: optional. Wake; reads payload on stdin and **prints fresh recipe JSON** (pairing may change).\n- `destroy`: optional unless `destroy: none`. Delete/cleanup; reads payload on stdin.\n\nStart Orca remotely with `orca serve --port \"$PORT\" --project-root \"$ABS_ROOT\" --pairing-address\n\"$EXTERNAL_WSS_URL\" --recipe-json` (exact flags + output in §7c). Set `--pairing-address` to the\nexternally reachable address so the emitted `pairingCode` is reachable; tunneling/port mapping is the\nscript's job.\n\nBackward compatibility: `command`→`create`, `cleanup`→`destroy`, `cleanup: none`→`destroy: none`.\nPrefer the lifecycle names.\n\n---\n\n## 9. Doctor and validation\n\nValidate in two stages — the cheap dry run first, then the live self-test.\n\n### Dry run (free, non-destructive) — always do this first\n\n`orca vm recipe doctor --repo-path --json` validates **static wiring only** — it does\n**not** boot anything. It checks: local-host execution (v1), repo path, recipe id exists,\ncreate/destroy/suspend/resume command paths resolve, suspend/resume are paired, and each script is\nexecutable (POSIX exec bit; skipped on Windows). Fix every failure here before spending any cloud money.\n\n### Live self-test (`--provision`) — diagnose and iterate yourself\n\n`orca vm recipe doctor --repo-path --provision --json` actually runs the recipe end\nto end: it executes `create`, validates the returned recipe JSON, then runs `destroy` to **tear the\nenvironment back down** (so the test leaves nothing running, as long as `destroy` works). It spends real\ncloud money, so get the user's OK **once** before starting — that one approval covers the whole loop\nbelow; do not re-ask before each run.\n\nOn failure, the JSON result includes a `provisionTranscript` with the **complete** captured output of\neach stage so you can self-diagnose without asking the user to relay logs:\n\n```json\n{\n \"ok\": false,\n \"checks\": [ { \"id\": \"recipe.provision\", \"status\": \"fail\", \"message\": \"…\" } ],\n \"provisionTranscript\": {\n \"provision\": { \"exitCode\": 0, \"signal\": null, \"stdout\": \"…\", \"stderr\": \"…\", \"parseError\": \"…\" },\n \"destroy\": { \"exitCode\": 0, \"signal\": null, \"stdout\": \"…\", \"stderr\": \"…\" }\n }\n}\n```\n\n**Run it as a loop:** read `provisionTranscript.provision.stderr` / `.stdout` / `.parseError` (and\n`destroy.*`), fix the script, and re-run `--provision` until `ok` is `true` — iterating on your own\nrather than waiting for the user to paste errors. Common reads: a non-empty `stderr` with `exitCode 0`\nplus a `parseError` means `create` ran but printed something other than the single recipe-result JSON on\nstdout (often a stray `echo` — route it to stderr, see §10); a non-zero `exitCode` is a provider/script\nfailure described in `stderr`. Each stream is redacted and capped (head+tail) — large logs keep both the\nsetup context and the failure.\n\nThe self-test cannot see provider-side truth beyond what the scripts print, so still confirm: state has a\npopulated **authenticated** `snapshotId` (Phases 2–3 done), and `destroy` is implemented/tested (or\nexplicitly `none` — in which case the self-test won't tear down, so clean up manually).\n\nFor SSH recipes, also smoke-test the exact emitted target before declaring success: dial the host/port\nwith the identity/proxy settings, run `pwd`, verify the repo path, check the agent binary, and confirm\n`destroy` removes the provider resource/container. For Docker, inspect the auth image entrypoint and do a\nstartup-only `docker run` before the full clone/install path.\n\n---\n\n## 10. Failure modes\n\n- **Build exceeds plan timeout (e.g. Hobby 45m).** Use enough vCPUs and a timeout covering the build;\n else split work or use a higher plan. The cap also limits per-workspace runtime — surface it.\n- **Build exceeds plan RAM.** Build the **headless main only** (drop the renderer) — the biggest fitter.\n- **Private-repo clone hangs/fails.** Wrong/missing token. Use `GIT_ASKPASS` + `GIT_TERMINAL_PROMPT=0`\n so it fails fast instead of prompting.\n- **`GIT_ASKPASS` helper aborts the clone with \"`$1: unbound variable`\".** The `printf`/heredoc that writes\n the helper inside `bash -lc` under `set -u` expanded `$1`/`$GH_TOKEN` at **write** time. Escape them\n (`\\$1`, `\\$GH_TOKEN`) so they land literally and resolve at git-runtime; this also keeps the real token\n out of the file. `rm -f` the helper afterward (§5, §7f).\n- **Agent verified as \"not logged in\" despite a good login.** `codex login status` (and similar) print\n \"Logged in …\" to **stderr**; an stdout-only `grep` misses it. Prefer the status **exit code**; if you\n grep, fold stderr first (`status 2>&1 | grep …`) and match the exact success line — not `grep -qi\n 'logged in'`, which also matches \"not logged in\".\n- **Headless agent login hangs.** Plain OAuth `login` starts a loopback callback server on a VM/container\n port the host browser can't reach. Use the **device-auth** flow (`login --device-auth`) — it prints a\n URL + code the user opens on the host.\n- **`known_hosts` host-key churn on local Docker.** Each ephemeral container regenerating its SSH host key\n collides on `127.0.0.1` as the published port rotates. Bake host keys into the base image at build time\n (`ssh-keygen -A`; runtime generates only if absent) so all containers share one stable key (§7h).\n- **Snapshot expired/evicted.** If `create` hits an unknown snapshot id, rerun Phases 2–3 and update\n `snapshotId`.\n- **Agent auth didn't persist.** Confirm `snapshotId` points at the **authenticated** snapshot; re-run\n Phase 3. Warn that short-lived tokens may need periodic re-auth.\n- **Agent auth copied from the host breaks.** Do not bind-mount/copy a full host agent home; sqlite\n files can be unwritable or host-specific, hooks may need approval again, and config may reference\n local-only env vars. Authenticate inside the runtime and snapshot/commit that layer.\n- **Docker auth image exits immediately.** Inspect `docker image inspect … .Config.Entrypoint` and\n `docker logs`. If the image was committed from an interactive shell, reset the entrypoint to the SSH\n entrypoint during `docker commit`.\n- **Leaked paid resource.** Every long script must trap errors and remove the sandbox it created.\n- **`create` emits non-JSON on stdout.** A stray `echo` corrupts the result — stdout is for the final\n JSON only; everything else to stderr. The `--provision` self-test surfaces this as `exitCode 0` + a\n `parseError` with the offending stdout in `provisionTranscript` (§9).\n\n---\n\n## 11. Boundaries\n\n- Don't create accounts, choose plans/regions, or invent scope/project/org/image/billing ids.\n- Don't invent or store credentials; no secrets in `userData`, state, comments, docs, or commits.\n- Don't run paid/long phases (base snapshot, auth, live test) without an explicit OK.\n- Don't hide provider errors behind generic messages — preserve actionable stderr.\n- Don't make Orca own provider lifecycle beyond invoking the configured scripts.\n- Don't commit or create an Orca workspace unless asked.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Use Orca orchestration for structured multi-agent coordination: threaded\n messages, blocking ask/reply flows, task dispatch, worker_done/escalation\n waits, task DAGs, decision gates, coordinator loops, or decomposing work\n across agents. Use `orca-cli` instead for full ownership handoffs, including\n requests phrased as \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", or \"another worktree\" when the user did not explicitly ask to\n supervise, monitor, wait for results, or coordinate a DAG. Use `orca-cli` for\n ordinary terminal control, lightweight terminal prompts, shell commands, Orca\n worktree management, reading or waiting on terminals, and automation of the\n browser embedded inside Orca. Use Computer Use for browser windows, webviews,\n Orca app UI, or desktop UI outside Orca's embedded browser.\n---\n\n# Orca Inter-Agent Orchestration\n\nOrchestration is Orca's structured coordination layer for agent messages, task ownership, dispatch state, and worker completion tracking.\n\nUse this skill when coordination state matters. For lightweight terminal prompts or basic worktree/terminal/built-in-browser control, use `orca-cli`.\n\n## Tool Boundary\n\nIf a task says to use Orca orchestration, the coordinator must create or bind a Run, create the Task with `orca orchestration task-create`, then attach the worker with either the preferred `orca orchestration worker-start` composition or the low-level `orca orchestration dispatch --inject` path.\n\nDo not substitute non-Orca subagent tools, generic agent-spawn APIs, or chat-only parallel worker features. Those may create useful workers, but they do not create Orca task/dispatch provenance, injected lifecycle preambles, `worker_done` authority, or decision gates.\n\nBefore claiming a worker was orchestrated, verify the task/dispatch exists:\n\n```bash\norca orchestration task-list --json\norca orchestration dispatch-show --task --json\n```\n\nIf the work was accidentally run outside Orca orchestration, say so plainly. To repair provenance, rerun or revalidate the needed work through a fresh Orca terminal plus injected dispatch; do not retroactively describe the external worker as orchestrated.\n\n## When To Use\n\n- Send/reply/ask between agent terminals with persistent messages.\n- Dispatch structured tasks to workers and wait for `worker_done` or `escalation`.\n- Track task DAGs with dependencies.\n- Run coordinator loops or decision gates.\n\nDo not use orchestration merely because the user says \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", or asks for another worktree/agent/model/effort. Those are full ownership transfers unless the user explicitly asks to supervise, monitor, wait for worker completion/results, coordinate a DAG, use decision gates, or keep a blocking ask/reply loop.\n\n## Preconditions\n\n- `orca status --json` should show a running runtime.\n- `orca` must be on PATH (`orca-ide` on Linux).\n- The orchestration experimental feature must be enabled in Settings > Experimental.\n- `orca orchestration` commands are RPC calls to the running Orca runtime.\n\n## Contract Migration\n\nOrca adopts a live pre-update orchestration assignment into an ordinary Run. Adoption preserves the existing agent process, PTY/session, terminal handle, tab/leaf/pane, worktree or folder workspace, Task, and Dispatch; it never restarts or replaces the worker. The retired scheduler is not revived, and a newly created attempt uses the current grammar.\n\nTreat the authority label on injected or formatted messages as definitive:\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported command printed with the message, using the same CLI executable and arguments that the original prompt supplied.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded, at-least-once cutover replay. Process it idempotently and acknowledge it only through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or lifecycle action.\n- An unlabeled current message uses the current guide and current grammar.\n\nAn explicitly selected current Run, attested current Run binding, current Dispatch, or federated attachment takes precedence over legacy fallback. A retained adoption record alone never turns a current command into a legacy call.\n\nDatabase provenance, an old-looking terminal, or a legacy Run ID does not prove mutation authority. If the runtime cannot prove liveness, principal ownership, capability, or the exact legacy contract, it degrades to read-only inspection and must not fall back to local execution. Exact recovery may restore the already-live PTY once in its original inactive background tab. It must not spawn, write, signal, stop, switch, focus, split, or inject a terminal. Loss of lifecycle authority does not invalidate the existing assignment, process, or filesystem work.\n\nCompatibility retries have narrow guarantees. A pending ask, a reply, a final Dispatch settlement, and a consuming check have durable recovery identities. A-era heartbeat and escalation calls remain at-least-once across a manual A-to-B retry because identical later signals may be intentional. If an A-era ask may already have been answered, run the exact non-consuming recovery check printed by the runtime first; after its answer is printed and acknowledged, a new invocation with the same question creates a new question. Never guess among multiple identical question threads.\n\nWhen a compatibility or recovery command returns structured next-step arguments, run those exact arguments with the same CLI executable. The arguments intentionally omit the executable name so the guidance works with `orca`, `orca-ide`, `orca-dev`, or another configured Orca CLI command. Do not translate the command from memory, broaden its recipient, or retry it as a current mutation unless the returned guidance explicitly says to.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The initial command durably commits the question, prints its exact `ask --resume ` command, and exits with launcher status `75`; it does not wait for the answer. Run that exact resume command after the launcher or update boundary. Resume is idempotent and read-oriented: it waits for the already-committed question and does not create another one. For a WSL process that received compatibility proof at launch, use the printed executable `orca-ide` WSL resume command so the same distro and packaged launcher authority are preserved; do not substitute a PATH-resolved local CLI. Older WSL processes that never received the hidden launch token remain lifecycle read-only after the update, even while their terminal and filesystem work continue.\n\nLegacy inspection remains available without consuming mail:\n\n```bash\norca orchestration run-list --json\n# run_legacy_local is an empty audit tombstone after adoption.\norca orchestration run-show --id run_legacy_local --json\n# In run-list, find the ordinary Run whose objective is:\n# \"Recovered orchestration work from a contract update\"\norca orchestration run-show --id --json\norca orchestration task-list --run --json\norca orchestration inbox --full --json\norca orchestration check --terminal --peek --format --json\norca terminal read --terminal --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\nIf the original coordinator is unavailable or cannot prove its retained authority, a current coordinator may explicitly take over the adopted Run from its own live agent terminal:\n\n```bash\norca orchestration run-use --id --takeover-legacy --json\norca orchestration check --run --json\n```\n\nTakeover fences only the old coordinator, binds the current one, and moves pending worker mail into current Run Delivery. It is bound to the authenticated invoking terminal; `--from` cannot name another coordinator. Live legacy workers keep their original Tasks, Dispatches, processes, filesystems, and old prompt commands; their later questions, escalations, and completion reports route to the current coordinator. Do not use takeover while the original coordinator is still actively coordinating, because its later lifecycle mutations are rejected.\n\nDo not launch a replacement editor merely because the desktop app or runtime was updated. If adoption cannot prove continuing authority, keep the original worker as the only editor until it reaches a stable handoff point, then use a new current Dispatch in a conflict-free placement for any remaining work.\n\n## Ownership\n\nNew orchestration messages and tasks belong to one explicitly bound Run. A Run is only a durable namespace and coordinator inbox; it never schedules or places workers. Lifecycle authority comes from the active Dispatch, and terminal handles remain routing metadata rather than durable identity. Send `worker_done` and `heartbeat` from the worker's own terminal; Orca routes them to that Dispatch's Run.\n\nClassify inherited context before sending lifecycle messages:\n\n- Coordinated subtask: a live coordinator owns the DAG and waits on this dispatch. Follow the preamble exactly, including `worker_done`, heartbeat/status, `ask`, and `escalation`.\n- Full handoff means ownership transfer, not supervised dispatch. The original actor is not monitoring a DAG, so do not create lifecycle obligations unless the user explicitly asks you to supervise.\n- Classify requests containing \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", \"give this to another worktree\", \"another agent\", or \"another worktree\" as full handoffs by default, even when the user names a custom model or reasoning effort.\n- Use supervised orchestration only when the user explicitly asks you to \"supervise\", \"monitor\", \"wait\", \"track completion\", \"wait for worker_done\", return results, coordinate a DAG, use a decision gate, or manage ask/reply flow.\n- Do not use `orca orchestration dispatch --inject` for full handoffs. It injects a coordinator preamble that tells the worker to send `worker_done`, heartbeat, and `ask` messages, then end its turn under the original terminal's dispatch lifecycle.\n- Do not run `orca orchestration task-create`, `orca orchestration dispatch --inject`, or `orca orchestration check --wait` for full handoffs. Do not peek at terminal output after prompt delivery to monitor progress.\n- A review-only `worker_done` reports findings; it does not authorize coordinator file edits. After a review-only completion, synthesize findings, ask a decision gate if ownership is unclear, and dispatch or hand off fixes unless the user explicitly asked the coordinator to own fixes.\n- If the user's plan names a next owner agent (for example, \"then use opencode to create a PR\"), post-review corrections and PR prep belong to that named owner. The coordinator routes, synthesizes, asks decision gates when needed, and supervises; the named owner edits files and creates the PR.\n\nIf unclear, inspect orchestration state before sending lifecycle messages:\n\n```bash\norca orchestration task-list --json\norca terminal list --json\n# If inherited context includes a task id:\norca orchestration dispatch-show --task --json\n```\n\n## Messaging\n\n```bash\norca orchestration send --subject [--to ] [--from ] [--body ] [--type ] [--priority ] [--thread-id ] [--payload ] [--json]\norca orchestration check [--terminal ] [--ack ] [--peek|--all] [--types ] [--format] [--wait] [--timeout-ms ] [--json]\norca orchestration reply --id --body [--from ] [--json]\norca orchestration ask (--question |--resume ) [--options ] [--timeout-ms ] [--from ] [--json]\norca orchestration inbox [--limit ] [--json]\n```\n\nRules:\n\n- Omit `--from` unless impersonating another terminal; Orca auto-resolves it from the current terminal.\n- A coordinator `check` returns the bound Run's oldest FIFO Delivery (up to 50 messages) and replays that exact batch until `--ack `. Process every message before acknowledging; `check --ack --wait` acknowledges, checks, and waits in one operation.\n- Use `--peek` and `--all` only for read-only history/debugging. Type filters decide when a waiter wakes; the returned actionable Delivery is still the oldest full batch.\n- Use `dispatch:` for coordinator guidance to one supervised worker. Orca routes that stable address locally or through the connected-server relay; do not substitute a remote terminal handle.\n- Terminal handles remain appropriate for low-level pre-Dispatch messaging. Prefer `agentTerminalHandle` from the create response, fall back to `startupTerminal.handle` for older runtimes, then re-resolve with `orca terminal list --worktree ... --json` if missing or stale. Continue with the replacement handle only; never dual-send to old and new handles.\n- `orca orchestration check --peek --format --json` returns locally formatted unread mail without consuming it; it never writes to terminal input or remotely wakes another terminal. Use `orchestration dispatch --inject` to deliver a tracked task, or `terminal send` when an existing agent needs a free-form prompt.\n- While supervising workers manually, use `check --wait --types worker_done,escalation,question --timeout-ms ` instead of sleep/poll loops. Process the whole Delivery, reply to `question` messages with `orca orchestration reply --id --body --json`, then acknowledge and keep waiting.\n- Treat a `check --wait` timeout or `{count:0}` as a checkpoint, not a worker failure. Long coding tasks routinely run 15-60 minutes; keep using rolling waits unless you receive `worker_done`/`escalation`, the terminal exits or disappears, or the user explicitly asks you to stop.\n- Heartbeats and visible terminal activity mean the worker is alive, not done. Do not stop, close, kill, or restart a worker just because it has not produced a completion message yet.\n- Use `ask` when a worker needs a blocking answer from the coordinator; it defaults to the active Dispatch's Run. Timeout or disconnect leaves the question pending, so resume by its original message ID instead of asking again.\n- `check --wait` returns one bounded Delivery, not every future completion. Process every message, acknowledge it, then keep waiting until every expected Dispatch settles.\n- Group addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`, `@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`.\n- Message types include `status`, `dispatch`, `worker_done`, `merge_ready`, `escalation`, `handoff`, `question`, `decision_gate` (legacy/gates), and `heartbeat`.\n- Use group addresses only for messages that are genuinely useful to many terminals, such as `status` broadcasts or intentional fan-out questions. Do not send dispatch lifecycle messages to groups.\n- `worker_done` belongs to the active Dispatch and defaults to its Run mailbox; never target a group.\n- A valid `worker_done` for the active `taskId` + `dispatchId` marks the task and dispatch completed automatically. Do not follow it with `task-update --status completed`; reserve manual updates for explicit recovery or overrides.\n- `heartbeat` is also Dispatch-scoped. Include both IDs and omit `--to` so Orca uses the owning Run; use `status` for broad progress updates.\n\n## Tasks And Dispatch\n\nA Run is the namespace/inbox, a Task is the work item, and a Dispatch assigns one Task attempt to a terminal. Create or bind a Run once before the common loop.\n\n```bash\norca orchestration run-create --objective --json\norca orchestration task-create --spec [--deps ] [--parent ] [--json]\norca orchestration task-list [--status ] [--ready] [--brief] [--json]\norca orchestration task-update --id --status [--result ] [--json]\norca orchestration dispatch --task --to [--from ] [--inject] [--json]\norca orchestration dispatch-show --task [--json]\n```\n\nTask statuses: `pending`, `ready`, `dispatched`, `completed`, `failed`, `blocked`.\n\nDispatch rules:\n\n- `--inject` sends the task spec plus preamble into a recognized agent CLI so it can report `worker_done`.\n- If the target is a bare shell, omit `--inject`, dispatch for tracking if needed, then send the prompt manually with `orca terminal send --terminal --text --enter --json`.\n- After 3 consecutive failures on one task, the dispatch context circuit-breaks and the task is marked failed.\n- Use `task-list --brief --json` for coordinator sweeps; it collapses whitespace and caps each echoed spec at 160 characters (`spec_truncated` marks shortened rows). Omit `--brief` when the full spec is required, or when an older CLI rejects it as an unknown flag.\n\n## Preferred Supervised Worker Loop\n\nUse `worker-start` for the normal supervised path. It composes the existing worktree, terminal, readiness, and dispatch primitives while returning exact created/reused effects. Agents still choose placement and concurrency; Orca does not schedule workers or infer conflicts.\n\nCreate the Run and every independent Task first, then start all independent workers before waiting:\n\n```bash\norca orchestration run-create --objective \"\" --json\norca orchestration task-create --spec \"\" --json\norca orchestration task-create --spec \"\" --json\norca orchestration worker-start --task --worktree current --agent codex --json\norca orchestration worker-start --task --worktree current --agent claude --json\n```\n\n`current` and exact existing worktrees create a fresh agent terminal and do not rerun setup. Reuse an existing agent only with `--terminal `.\n\nFor a new worktree, setup runs by default and agent-first creation reuses the returned startup agent terminal:\n\n```bash\norca orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n# Independent/top-level:\norca orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nSetup normally starts alongside the agent. Only a repository explicitly configured with `wait-for-setup` delays agent launch until setup succeeds. Use `--setup skip` or `--setup inherit` only for a concrete reason.\n\nRead the returned receipt before continuing: `ready` plus setup `running` is normal for start-immediately, while wait-for-setup returns setup `succeeded` before accepting task input. A failed or unknown start exits nonzero; inspect its `stage`, `effects`, and `residualResources` instead of guessing or automatically retrying. A wait-for-setup timeout can honestly leave setup `running`, which is not proof of failure.\n\nTo run the worker on another connected Orca server, add `--on `. The Run and Tasks remain authoritative on the current server; later commands route by Dispatch ID, so never repeat `--on`:\n\n```bash\n# Mac Run home -> Windows worker (the reverse is identical from a Windows Run home)\norca orchestration worker-start --task --on windows --worktree new-top-level --repo --name --agent codex --setup run --json\norca orchestration worker-show --dispatch --json\norca orchestration worker-read --dispatch --limit 50 --json\norca orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nRemote `current` and `new-child` are intentionally invalid because those words are ambiguous across servers. Use an exact discovered remote worktree selector or `new-top-level` with an explicit remote repo selector.\n\nThe follow-up is structured inbox mail, not prompt injection. The worker's next\n`orchestration check` receives it even when the Dispatch is on another connected Orca server.\n\n`worker-read` defaults to `--source auto`: Orca returns the exact hook-reported Codex, Claude, OpenClaude, or Grok transcript when it can prove the worker session, otherwise it returns bounded terminal output with `source: \"terminal\"` and a typed `fallbackReason`. Continue with the returned top-level `cursor`; it stays pinned to that exact source. If Orca reports `source_changed`, start a fresh read without the old cursor. Never supply or guess a provider session ID or transcript path.\n\nWait until every expected Dispatch settles, not for a fixed number of batches:\n\n```bash\norca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n# Process every message in the returned Delivery, then atomically ack and continue:\norca orchestration check --ack --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n```\n\nWorkers report exactly once using the IDs and capability injected by Orca; they do not supply Run/server/terminal identity:\n\n```bash\norca orchestration send --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded --files-modified \"path/a,path/b\" --json\n# On failure, use --outcome failed; never encode failure only in prose.\n```\n\nA worker question defaults to its owning Run. Timeout leaves it pending:\n\n```bash\norca orchestration ask --question \"\" --options \"yes,no\" --timeout-ms 600000 --json\norca orchestration ask --resume --timeout-ms 600000 --json\n# Coordinator:\norca orchestration reply --id --body \"\" --json\n```\n\nRecovery is conditional, never a fixed destructive sequence:\n\n- `worker-show --dispatch ` says `ready`: keep waiting or read bounded output.\n- It proves `failed` or `stopped`: start a replacement with `worker-start --task --retry-of ` plus an explicit `--on`/`--worktree` and `--agent`/`--terminal` choice. Retry does not silently inherit placement.\n- It remains `outcome_unknown`: either `worker-stop --dispatch ` and inspect again, or explicitly `worker-abandon --dispatch ` while accepting that resources may still be live. Abandon performs no remote, process, or filesystem action.\n- `worker-stop` closes only the exact supervised agent terminal. It never deletes the worktree, setup terminal, configured tabs, or unrelated processes.\n\nLow-level `worktree create`, `terminal create`, and `dispatch --inject` remain valid recipes for custom argv or topology that `worker-start` does not express.\n\n## Gates And Legacy Inspection\n\n```bash\norca orchestration gate-create --task --question [--options ] [--json]\norca orchestration gate-resolve --id --resolution [--json]\norca orchestration gate-list [--task ] [--status ] [--json]\n```\n\nUse `ask` for worker-to-coordinator questions; it creates a `question` message that the coordinator answers with `reply`. Use `gate-create` only for coordinator-managed task DAG decisions, not for answering a worker's `ask`.\n\n`coordinator-start`, `coordinator-stop`, `run`, and `run-stop` are retired scheduler commands. They perform no effects and return the current-skill recovery action. They are not aliases for lightweight Run creation or binding.\n\nRecovery only: `orca orchestration reset --tasks|--messages|--all --json` clears the selected local orchestration database state. Do not run it during active coordination unless explicitly abandoning that state.\n\n## Full Handoffs\n\nFor full ownership transfer, use non-lifecycle terminal/worktree commands and then stop monitoring unless the user asks for supervision.\n\nTreat these as full handoff requests by default: \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", \"give this to another worktree\", \"send this to another agent\", \"another agent\", \"another worktree\", or \"launch another agent to own this.\" Custom model or reasoning effort words such as `gpt-5.5`, `high`, or `xhigh` do not make the handoff supervised.\n\nSupervised orchestration remains available only when the user explicitly asks for supervision or coordination: \"supervise\", \"monitor\", \"wait for worker_done\", \"wait for results\", \"track completion\", \"DAG\", \"decision gate\", \"ask/reply\", or \"coordinate workers.\"\n\nDo not run `orca orchestration task-create`, `orca orchestration dispatch --inject`, or `orca orchestration check --wait` for full handoffs. `task-create` is also forbidden because it records coordinator-owned tracking state; if a task row is needed, the user asked for supervised orchestration. Do not create a `taskId`/`dispatchId`, inject a lifecycle preamble, wait for completion, or read the worker terminal after prompt delivery except to avoid losing the initial prompt.\n\nNew top-level worktree handoff:\n\n```bash\norca worktree create --name --no-parent --agent codex --prompt \"\" --setup run --json\n```\n\nBefore creating a new worktree from an active feature branch, decide and state whether the desired Orca lineage is child or top-level. Use child worktree lineage only when the new work is conceptually stacked under or dependent on the active worktree. For independent repo-wide fixes, standalone feature work, or unrelated follow-up tasks, create a top-level worktree with `--no-parent`.\n\nExisting terminal handoff:\n\n```bash\norca terminal send --terminal --text \"\" --enter --json\n```\n\nCustom Codex model/effort handoff:\n\n`orca worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. When the user asks for a specific Codex model or effort, create the independent worktree first, launch Codex with the requested command in that worktree, wait only for TUI readiness if prompt delivery would otherwise race startup, send the prompt, and stop.\n\nThe two-step custom-argv path cannot enforce a repository's explicit `wait-for-setup` startup policy because the later `terminal create` is not the startup owned by `worktree create`. Use it only when the repository starts agents immediately. If the repository requires `wait-for-setup`, use an agent-first configured launcher that can preserve sequencing, or stop and ask rather than silently bypassing the policy.\n\nNote: when no repo default-terminal configuration supplies a primary terminal, bare create opens a fallback shell before `terminal create` adds the agent. Configured default tabs are materialized instead and may run real commands. Prefer `--agent` whenever custom argv is not required. With the two-step path, target only the agent handle; close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell.\n\nUse the exact full `::` worktree id returned by `orca worktree create --json`; a bare repo id cannot target the new worktree.\n\n```bash\norca worktree create --name --no-parent --setup run --json\norca terminal create --worktree id: --title --command 'codex --model gpt-5.5 -c model_reasoning_effort=\"xhigh\"' --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca terminal send --terminal --text \"\" --enter --json\n```\n\nWait only for `tui-idle` when needed to avoid losing the prompt. Do not monitor task completion.\n\n`--no-parent` only controls Orca lineage; it does not choose the Git base. If the work should start from the repo default base, omit `--base-branch` so Orca uses that default, or explicitly pass the repo default base (`origin/main`, `origin/master`, or the `orca repo show --repo --json` value); never base it on the current feature branch unless the user explicitly asks for stacked work or \"branch from current\". Put current-branch context in the prompt instead.\n\n## Worker Terminals\n\nChoose the worker location before creating a terminal. `Fresh worker` means a fresh agent session, not a new git worktree. For parallel work, create one fresh agent terminal per worker in the same required worktree, falling back to the active worktree when none is named. If the task says current worktree only, depends on uncommitted files/artifacts, or must validate/PR the current branch, keep every worker in the active worktree:\n\n```bash\norca terminal create --worktree active --title --command \"codex\" --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration dispatch --task --to --inject --json\n```\n\nReuse an idle agent in the required worktree only if the prompt allows reuse; otherwise create a fresh terminal there. Create a new worktree only when the user explicitly requests one or a concrete checkout or filesystem conflict makes sharing unsafe or impossible; if the user did not request it, state that conflict before running `worktree create`. Independent tasks, parallel execution, convenience, or a preference for separate checkouts are not isolation requirements.\n\nWhen a new worktree is allowed, use child lineage for isolated work that is stacked under or dependent on the active worktree, and use `--no-parent` when it is not stacked. Decide the Git base separately: `--no-parent` makes the worktree top-level in Orca, while omitted `--base-branch` uses the repo default base.\n\nFor every new worktree, pass `--setup run` so any configured repository setup hook runs. This does not mean waiting for setup before agent launch: preserve the repository's startup policy, whose default starts setup and the agent side by side. Use `--setup skip` or `--setup inherit` only when there is a concrete task-specific reason, and state that reason before creating the worktree. This rule does not rerun setup for current or existing worktrees.\n\n```bash\norca worktree create --name --agent codex --setup run --json\n# or: --agent claude | omp | pi | grok | ...\n# Read from agentTerminalHandle, falling back to startupTerminal.handle.\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration dispatch --task --to --inject --json\n```\n\nFor new-worktree workers, read the id and `agentTerminalHandle` from `worktree create`, falling back to `startupTerminal.handle` for older runtimes. Use that as the sole worker handle when present; otherwise use `terminal list` to resolve the agent handle. Omit `--repo` only inside an Orca-managed worktree; otherwise pass `--repo `.\n\n**For an allowed new worktree, use agent-first:** `--agent` reveals the new worktree and launches the selected agent **in its first terminal**, without adding a separate fallback shell for that worker. Pass `--setup run`; repo setup and default-terminal settings may add intentional tabs or splits. Do **not** run bare `worktree create` and then `terminal create --command ` for the same worker when agent-first create is available: without configured default tabs, that two-step path leaves a fallback shell + agent pair. Only use it when custom agent argv is required (for example Codex model/effort flags) or when an older CLI rejects `--agent`; if you must, message only the agent handle. Configured default tabs are intentional surfaces, so close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell. Do not run `worktree create` when the task must stay in the current worktree.\n\nUse `orca worktree create --prompt ...` or `orca terminal send ...` for full handoffs or untracked/lightweight prompts. Those paths do not attach `taskId`/`dispatchId`; the worker should not send lifecycle messages unless the prompt supplies a live orchestration preamble.\n\nSidebar lineage and orchestration lifecycle are related but not identical. A same-worktree worker may appear as a peer under that worktree in the sidebar while remaining a child dispatch in orchestration state; only an actual child worktree creates visible parent/child worktree lineage.\n\nOther terminal commands coordinators often need:\n\n```bash\norca terminal list [--worktree ] [--json]\norca terminal create [--worktree ] [--title ] [--command ] [--json]\norca terminal split --terminal [--direction horizontal|vertical] [--command ] [--json]\norca terminal wait --terminal --for tui-idle --timeout-ms --json\norca terminal read --terminal --json\norca terminal send --terminal --text --enter --json\n```\n\nIf an older CLI rejects `worktree create --agent`, create the worktree normally, then run `orca terminal create --worktree --command \"codex\" --json` or `--command \"claude\"`.\n\nWait for `tui-idle` before dispatching. Always pass `--timeout-ms`; real coding tasks can take 15-60 minutes. During supervision, use rolling `check --wait` windows. If a window returns no matching message, inspect `task-list`, `terminal read`, or `terminal wait --for tui-idle` as a liveness checkpoint; if the terminal is still working or producing activity, keep waiting instead of retrying the task.\n\n## Agent Guidance\n\n- Workers with a valid live preamble must send `worker_done` exactly once from their own terminal with an explicit `--outcome succeeded` or `--outcome failed`:\n `orca orchestration send --type worker_done --subject \"\" --body \"<3-sentence summary: what you did, what you found, what's left>\" --task-id --dispatch-id --outcome succeeded --files-modified \"path/a\" --report-path \"\" --json`\n- A failed outcome is still a terminal report, but Orca records both the Dispatch and Task as failed. Never encode failure only in the subject/body.\n- After sending `worker_done`, end your turn and idle at the agent prompt. Do not poll or keep calling `orca orchestration check`; the coordinator re-engages you with a fresh preamble + TASK block delivered as new terminal input.\n- For long tasks, send heartbeat/status only when the preamble asks for it, including both IDs:\n `orca orchestration send --type heartbeat --subject \"alive\" --payload '{\"taskId\":\"\",\"dispatchId\":\"\",\"phase\":\"implementing\"}' --json`\n- If blocked before completion, use `ask`; use `escalation` only when ownership is valid and the coordinator must intervene.\n- Treat preambles inherited through terminal history or full handoffs as stale unless the current prompt explicitly keeps that coordinator in the loop.\n- Coordinators should use `task-list --ready` as external memory, dispatch parallel waves, and avoid dependency chains deeper than 3-4 steps.\n\n## Example\n\n```bash\norca terminal create --worktree active --title login-css-worker --command \"claude\" --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration task-create --spec \"Fix the login button CSS\" --json\norca orchestration dispatch --task --to --inject --json\norca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n```\n\n## Next Action\n\nCoordinator: confirm `orca status --json`, create or bind a Run, inspect `task-list`/`dispatch-show` if inheriting state, then use the explicit supervised loop (`task-create` -> `worker-start` -> `check --wait`). Use low-level terminal creation plus `dispatch --inject` only when the composed start does not express the needed topology.\n\nWorker: if the current prompt contains a live dispatch preamble, do the task, use `ask` for blocking questions, and send `worker_done` once with the required payload. If the preamble is stale or absent, do not send lifecycle messages; inspect state or treat the prompt as an ordinary handoff.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Use Orca orchestration for structured multi-agent coordination: threaded\n messages, blocking ask/reply flows, task dispatch, worker_done/escalation\n waits, task DAGs, decision gates, coordinator loops, or decomposing work\n across agents. Use `orca-cli` instead for full ownership handoffs, including\n requests phrased as \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", or \"another worktree\" when the user did not explicitly ask to\n supervise, monitor, wait for results, or coordinate a DAG. Use `orca-cli` for\n ordinary terminal control, lightweight terminal prompts, shell commands, Orca\n worktree management, reading or waiting on terminals, and automation of the\n browser embedded inside Orca. Use Computer Use for browser windows, webviews,\n Orca app UI, or desktop UI outside Orca's embedded browser.\n---\n\n# Orca Inter-Agent Orchestration\n\nOrchestration is Orca's structured coordination layer for agent messages, task ownership, dispatch state, and worker completion tracking.\n\nUse this skill when coordination state matters. For lightweight terminal prompts or basic worktree/terminal/built-in-browser control, use `orca-cli`.\n\n## Tool Boundary\n\nIf a task says to use Orca orchestration, the coordinator must create or bind a Run, create the Task with `orca orchestration task-create`, then attach the worker with either the preferred `orca orchestration worker-start` composition or the low-level `orca orchestration dispatch --inject` path.\n\nDo not substitute non-Orca subagent tools, generic agent-spawn APIs, or chat-only parallel worker features. Those may create useful workers, but they do not create Orca task/dispatch provenance, injected lifecycle preambles, `worker_done` authority, or decision gates.\n\nBefore claiming a worker was orchestrated, verify the task/dispatch exists:\n\n```bash\norca orchestration task-list --json\norca orchestration dispatch-show --task --json\n```\n\nIf the work was accidentally run outside Orca orchestration, say so plainly. To repair provenance, rerun or revalidate the needed work through a fresh Orca terminal plus injected dispatch; do not retroactively describe the external worker as orchestrated.\n\n## When To Use\n\n- Send/reply/ask between agent terminals with persistent messages.\n- Dispatch structured tasks to workers and wait for `worker_done` or `escalation`.\n- Track task DAGs with dependencies.\n- Run coordinator loops or decision gates.\n\nDo not use orchestration merely because the user says \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", or asks for another worktree/agent/model/effort. Those are full ownership transfers unless the user explicitly asks to supervise, monitor, wait for worker completion/results, coordinate a DAG, use decision gates, or keep a blocking ask/reply loop.\n\n## Preconditions\n\n- `orca status --json` should show a running runtime.\n- `orca` must be on PATH (`orca-ide` on Linux).\n- The orchestration experimental feature must be enabled in Settings > Experimental.\n- `orca orchestration` commands are RPC calls to the running Orca runtime.\n\n## Contract Migration\n\nOrca adopts a live pre-update orchestration assignment into an ordinary Run. Adoption preserves the existing agent process, PTY/session, terminal handle, tab/leaf/pane, worktree or folder workspace, Task, and Dispatch; it never restarts or replaces the worker. The retired scheduler is not revived, and a newly created attempt uses the current grammar.\n\nTreat the authority label on injected or formatted messages as definitive:\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported command printed with the message, using the same CLI executable and arguments that the original prompt supplied.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded, at-least-once cutover replay. Process it idempotently and acknowledge it only through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or lifecycle action.\n- An unlabeled current message uses the current guide and current grammar.\n\nAn explicitly selected current Run, attested current Run binding, current Dispatch, or federated attachment takes precedence over legacy fallback. A retained adoption record alone never turns a current command into a legacy call.\n\nDatabase provenance, an old-looking terminal, or a legacy Run ID does not prove mutation authority. If the runtime cannot prove liveness, principal ownership, capability, or the exact legacy contract, it degrades to read-only inspection and must not fall back to local execution. Exact recovery may restore the already-live PTY once in its original inactive background tab. It must not spawn, write, signal, stop, switch, focus, split, or inject a terminal. Loss of lifecycle authority does not invalidate the existing assignment, process, or filesystem work.\n\nCompatibility retries have narrow guarantees. A pending ask, a reply, a final Dispatch settlement, and a consuming check have durable recovery identities. A-era heartbeat and escalation calls remain at-least-once across a manual A-to-B retry because identical later signals may be intentional. If an A-era ask may already have been answered, run the exact non-consuming recovery check printed by the runtime first; after its answer is printed and acknowledged, a new invocation with the same question creates a new question. Never guess among multiple identical question threads.\n\nWhen a compatibility or recovery command returns structured next-step arguments, run those exact arguments with the same CLI executable. The arguments intentionally omit the executable name so the guidance works with `orca`, `orca-ide`, `orca-dev`, or another configured Orca CLI command. Do not translate the command from memory, broaden its recipient, or retry it as a current mutation unless the returned guidance explicitly says to.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The initial command durably commits the question, prints its exact `ask --resume ` command, and exits with launcher status `75`; it does not wait for the answer. Run that exact resume command after the launcher or update boundary. Resume is idempotent and read-oriented: it waits for the already-committed question and does not create another one. For a WSL process that received compatibility proof at launch, use the printed executable `orca-ide` WSL resume command so the same distro and packaged launcher authority are preserved; do not substitute a PATH-resolved local CLI. Older WSL processes that never received the hidden launch token remain lifecycle read-only after the update, even while their terminal and filesystem work continue.\n\nLegacy inspection remains available without consuming mail:\n\n```bash\norca orchestration run-list --json\n# run_legacy_local is an empty audit tombstone after adoption.\norca orchestration run-show --id run_legacy_local --json\n# In run-list, find the ordinary Run whose objective is:\n# \"Recovered orchestration work from a contract update\"\norca orchestration run-show --id --json\norca orchestration task-list --run --json\norca orchestration inbox --full --json\norca orchestration check --terminal --peek --format --json\norca terminal read --terminal --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\nIf the original coordinator is unavailable or cannot prove its retained authority, a current coordinator may explicitly take over the adopted Run from its own live agent terminal:\n\n```bash\norca orchestration run-use --id --takeover-legacy --json\norca orchestration check --run --json\n```\n\nTakeover fences only the old coordinator, binds the current one, and moves pending worker mail into current Run Delivery. It is bound to the authenticated invoking terminal; `--from` cannot name another coordinator. Live legacy workers keep their original Tasks, Dispatches, processes, filesystems, and old prompt commands; their later questions, escalations, and completion reports route to the current coordinator. Do not use takeover while the original coordinator is still actively coordinating, because its later lifecycle mutations are rejected.\n\nDo not launch a replacement editor merely because the desktop app or runtime was updated. If adoption cannot prove continuing authority, keep the original worker as the only editor until it reaches a stable handoff point, then use a new current Dispatch in a conflict-free placement for any remaining work.\n\n## Ownership\n\nNew orchestration messages and tasks belong to one explicitly bound Run. A Run is only a durable namespace and coordinator inbox; it never schedules or places workers. Lifecycle authority comes from the active Dispatch, and terminal handles remain routing metadata rather than durable identity. Send `worker_done` and `heartbeat` from the worker's own terminal; Orca routes them to that Dispatch's Run.\n\nClassify inherited context before sending lifecycle messages:\n\n- Coordinated subtask: a live coordinator owns the DAG and waits on this dispatch. Follow the preamble exactly, including `worker_done`, heartbeat/status, `ask`, and `escalation`.\n- Full handoff means ownership transfer, not supervised dispatch. The original actor is not monitoring a DAG, so do not create lifecycle obligations unless the user explicitly asks you to supervise.\n- Classify requests containing \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", \"give this to another worktree\", \"another agent\", or \"another worktree\" as full handoffs by default, even when the user names a custom model or reasoning effort.\n- Use supervised orchestration only when the user explicitly asks you to \"supervise\", \"monitor\", \"wait\", \"track completion\", \"wait for worker_done\", return results, coordinate a DAG, use a decision gate, or manage ask/reply flow.\n- Do not use `orca orchestration dispatch --inject` for full handoffs. It injects a coordinator preamble that tells the worker to send `worker_done`, heartbeat, and `ask` messages, then end its turn under the original terminal's dispatch lifecycle.\n- Do not run `orca orchestration task-create`, `orca orchestration dispatch --inject`, or `orca orchestration check --wait` for full handoffs. Do not peek at terminal output after prompt delivery to monitor progress.\n- A review-only `worker_done` reports findings; it does not authorize coordinator file edits. After a review-only completion, synthesize findings, ask a decision gate if ownership is unclear, and dispatch or hand off fixes unless the user explicitly asked the coordinator to own fixes.\n- If the user's plan names a next owner agent (for example, \"then use opencode to create a PR\"), post-review corrections and PR prep belong to that named owner. The coordinator routes, synthesizes, asks decision gates when needed, and supervises; the named owner edits files and creates the PR.\n\nIf unclear, inspect orchestration state before sending lifecycle messages:\n\n```bash\norca orchestration task-list --json\norca terminal list --json\n# If inherited context includes a task id:\norca orchestration dispatch-show --task --json\n```\n\n## Messaging\n\n```bash\norca orchestration send --subject [--to ] [--from ] [--body ] [--type ] [--priority ] [--thread-id ] [--payload ] [--json]\norca orchestration check [--terminal ] [--ack ] [--peek|--all] [--types ] [--format] [--wait] [--timeout-ms ] [--json]\norca orchestration reply --id --body [--from ] [--json]\norca orchestration ask (--question |--resume ) [--options ] [--timeout-ms ] [--from ] [--json]\norca orchestration inbox [--limit ] [--json]\n```\n\nRules:\n\n- Omit `--from` unless impersonating another terminal; Orca auto-resolves it from the current terminal.\n- A coordinator `check` returns the bound Run's oldest FIFO Delivery (up to 50 messages) and replays that exact batch until `--ack `. Process every message before acknowledging; `check --ack --wait` acknowledges, checks, and waits in one operation.\n- Use `--peek` and `--all` only for read-only history/debugging. Type filters decide when a waiter wakes; the returned actionable Delivery is still the oldest full batch.\n- Use `dispatch:` for coordinator guidance to one supervised worker. Orca routes that stable address locally or through the connected-server relay; do not substitute a remote terminal handle.\n- Terminal handles remain appropriate for low-level pre-Dispatch messaging. Prefer `agentTerminalHandle` from the create response, fall back to `startupTerminal.handle` for older runtimes, then re-resolve with `orca terminal list --worktree ... --json` if missing or stale. Continue with the replacement handle only; never dual-send to old and new handles.\n- `orca orchestration check --peek --format --json` returns locally formatted unread mail without consuming it; it never writes to terminal input or remotely wakes another terminal. Use `orchestration dispatch --inject` to deliver a tracked task, or `terminal send` when an existing agent needs a free-form prompt.\n- While supervising workers manually, use `check --wait --types worker_done,escalation,question --timeout-ms ` instead of sleep/poll loops. Process the whole Delivery, reply to `question` messages with `orca orchestration reply --id --body --json`, then acknowledge and keep waiting.\n- Treat a `check --wait` timeout or `{count:0}` as a checkpoint, not a worker failure. Long coding tasks routinely run 15-60 minutes; keep using rolling waits unless you receive `worker_done`/`escalation`, the terminal exits or disappears, or the user explicitly asks you to stop.\n- Heartbeats and visible terminal activity mean the worker is alive, not done. Do not stop, close, kill, or restart a worker just because it has not produced a completion message yet.\n- Use `ask` when a worker needs a blocking answer from the coordinator; it defaults to the active Dispatch's Run. Timeout or disconnect leaves the question pending, so resume by its original message ID instead of asking again.\n- `check --wait` returns one bounded Delivery, not every future completion. Process every message, acknowledge it, then keep waiting until every expected Dispatch settles.\n- Group addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`, `@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`.\n- Message types include `status`, `dispatch`, `worker_done`, `merge_ready`, `escalation`, `handoff`, `question`, `decision_gate` (legacy/gates), and `heartbeat`.\n- Use group addresses only for messages that are genuinely useful to many terminals, such as `status` broadcasts or intentional fan-out questions. Do not send dispatch lifecycle messages to groups.\n- `worker_done` belongs to the active Dispatch and defaults to its Run mailbox; never target a group.\n- A valid `worker_done` for the active `taskId` + `dispatchId` marks the task and dispatch completed automatically. Do not follow it with `task-update --status completed`; reserve manual updates for explicit recovery or overrides.\n- `heartbeat` is also Dispatch-scoped. Include both IDs and omit `--to` so Orca uses the owning Run; use `status` for broad progress updates.\n\n## Tasks And Dispatch\n\nA Run is the namespace/inbox, a Task is the work item, and a Dispatch assigns one Task attempt to a terminal. Create or bind a Run once before the common loop.\n\n```bash\norca orchestration run-create --objective --json\norca orchestration task-create --spec [--deps ] [--parent ] [--json]\norca orchestration task-list [--status ] [--ready] [--brief] [--json]\norca orchestration task-update --id --status [--result ] [--json]\norca orchestration dispatch --task --to [--from ] [--inject] [--json]\norca orchestration dispatch-show --task [--json]\n```\n\nTask statuses: `pending`, `ready`, `dispatched`, `completed`, `failed`, `blocked`.\n\nDispatch rules:\n\n- `--inject` sends the task spec plus preamble into a recognized agent CLI so it can report `worker_done`.\n- If the target is a bare shell, omit `--inject`, dispatch for tracking if needed, then send the prompt manually with `orca terminal send --terminal --text --enter --json`.\n- After 3 consecutive failures on one task, the dispatch context circuit-breaks and the task is marked failed.\n- Use `task-list --brief --json` for coordinator sweeps; it collapses whitespace and caps each echoed spec at 160 characters (`spec_truncated` marks shortened rows). Omit `--brief` when the full spec is required, or when an older CLI rejects it as an unknown flag.\n\n## Preferred Supervised Worker Loop\n\nUse `worker-start` for the normal supervised path. It composes the existing worktree, terminal, readiness, and dispatch primitives while returning exact created/reused effects. Agents still choose placement and concurrency; Orca does not schedule workers or infer conflicts.\n\nCreate the Run and every independent Task first, then start all independent workers before waiting:\n\n```bash\norca orchestration run-create --objective \"\" --json\norca orchestration task-create --spec \"\" --json\norca orchestration task-create --spec \"\" --json\norca orchestration worker-start --task --worktree current --agent codex --json\norca orchestration worker-start --task --worktree current --agent claude --json\n```\n\n`current` and exact existing worktrees create a fresh agent terminal and do not rerun setup. Reuse an existing agent only with `--terminal `.\n\nFor a new worktree, setup runs by default and agent-first creation reuses the returned startup agent terminal:\n\n```bash\norca orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n# Independent/top-level:\norca orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nSetup normally starts alongside the agent. Only a repository explicitly configured with `wait-for-setup` delays agent launch until setup succeeds. Use `--setup skip` or `--setup inherit` only for a concrete reason.\n\nRead the returned receipt before continuing: `ready` plus setup `running` is normal for start-immediately, while wait-for-setup returns setup `succeeded` before accepting task input. A failed or unknown start exits nonzero; inspect its `stage`, `effects`, and `residualResources` instead of guessing or automatically retrying. A wait-for-setup timeout can honestly leave setup `running`, which is not proof of failure.\n\nTo run the worker on another connected Orca server, add `--on `. The Run and Tasks remain authoritative on the current server; later commands route by Dispatch ID, so never repeat `--on`:\n\n```bash\n# Mac Run home -> Windows worker (the reverse is identical from a Windows Run home)\norca orchestration worker-start --task --on windows --worktree new-top-level --repo --name --agent codex --setup run --json\norca orchestration worker-show --dispatch --json\norca orchestration worker-read --dispatch --limit 50 --json\norca orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nRemote `current` and `new-child` are intentionally invalid because those words are ambiguous across servers. Use an exact discovered remote worktree selector or `new-top-level` with an explicit remote repo selector.\n\nThe follow-up is structured inbox mail, not prompt injection. The worker's next\n`orchestration check` receives it even when the Dispatch is on another connected Orca server.\n\n`worker-read` defaults to `--source auto`: Orca returns the exact hook-reported Codex, Claude, OpenClaude, or Grok transcript when it can prove the worker session, otherwise it returns bounded terminal output with `source: \"terminal\"` and a typed `fallbackReason`. Continue with the returned top-level `cursor`; it stays pinned to that exact source. If Orca reports `source_changed`, start a fresh read without the old cursor. Never supply or guess a provider session ID or transcript path.\n\nWait until every expected Dispatch settles, not for a fixed number of batches:\n\n```bash\norca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n# Process every message. For each accepted worker_done that is not immediately reused:\norca orchestration worker-release --dispatch --json\n# Acknowledge only after every message and required release decision is handled:\norca orchestration check --ack --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n```\n\nAfter processing each accepted `worker_done`, choose the terminal's next owner before you acknowledge the Delivery or wait again. If the same exact agent has an immediate follow-up Task, read the `worker.agent_terminal_handle` field of `worker-show --dispatch --json`, then run `orca orchestration worker-start --task --terminal --json` so Orca transfers cleanup ownership to the new Dispatch. Otherwise run `orca orchestration worker-release --dispatch --json`.\n\nRun `worker-release` after both succeeded and failed `worker_done` reports unless the user explicitly asked to keep that worker live. Release is post-completion cleanup, not cancellation: Orca first preserves inspectable output, then closes only the exact agent terminal owned by that settled Dispatch. Reused or pre-existing terminals, setup terminals, coordinators, active workers, user-taken-over terminals, and identities Orca cannot prove are retained. If the user explicitly asks to keep the live terminal for debugging, record that exception with `orca orchestration worker-retain --dispatch --json` instead of silently skipping cleanup. When the user is finished, the same Dispatch can be passed to `worker-release`, which clears the requested retention and releases the terminal.\n\nDo not release a worker because of a timeout, TUI idle state, heartbeat, status, question, escalation, or rejected/stale `worker_done`. If release returns `release_pending` or `release_unknown`, do not substitute `terminal close`; follow the exact recovery action in the receipt. A replayed Delivery may repeat `worker-release` safely.\n\nWorkers report exactly once using the IDs and capability injected by Orca; they do not supply Run/server/terminal identity:\n\n```bash\norca orchestration send --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded --files-modified \"path/a,path/b\" --json\n# On failure, use --outcome failed; never encode failure only in prose.\n```\n\nA worker question defaults to its owning Run. Timeout leaves it pending:\n\n```bash\norca orchestration ask --question \"\" --options \"yes,no\" --timeout-ms 600000 --json\norca orchestration ask --resume --timeout-ms 600000 --json\n# Coordinator:\norca orchestration reply --id --body \"\" --json\n```\n\nRecovery is conditional, never a fixed destructive sequence:\n\n- `worker-show --dispatch ` says `ready`: keep waiting or read bounded output.\n- It proves `failed` or `stopped`: start a replacement with `worker-start --task --retry-of ` plus an explicit `--on`/`--worktree` and `--agent`/`--terminal` choice. Retry does not silently inherit placement.\n- It remains `outcome_unknown`: either `worker-stop --dispatch ` and inspect again, or explicitly `worker-abandon --dispatch ` while accepting that resources may still be live. Abandon performs no remote, process, or filesystem action.\n- `worker-stop` closes only the exact supervised agent terminal. It never deletes the worktree, setup terminal, configured tabs, or unrelated processes.\n\nLow-level `worktree create`, `terminal create`, and `dispatch --inject` remain valid recipes for custom argv or topology that `worker-start` does not express.\n\n## Gates And Legacy Inspection\n\n```bash\norca orchestration gate-create --task --question [--options ] [--json]\norca orchestration gate-resolve --id --resolution [--json]\norca orchestration gate-list [--task ] [--status ] [--json]\n```\n\nUse `ask` for worker-to-coordinator questions; it creates a `question` message that the coordinator answers with `reply`. Use `gate-create` only for coordinator-managed task DAG decisions, not for answering a worker's `ask`.\n\n`coordinator-start`, `coordinator-stop`, `run`, and `run-stop` are retired scheduler commands. They perform no effects and return the current-skill recovery action. They are not aliases for lightweight Run creation or binding.\n\nRecovery only: `orca orchestration reset --tasks|--messages|--all --json` clears the selected local orchestration database state. Do not run it during active coordination unless explicitly abandoning that state.\n\n## Full Handoffs\n\nFor full ownership transfer, use non-lifecycle terminal/worktree commands and then stop monitoring unless the user asks for supervision.\n\nTreat these as full handoff requests by default: \"hand off\", \"handoff\", \"handover\", \"give this to another agent\", \"give this to another worktree\", \"send this to another agent\", \"another agent\", \"another worktree\", or \"launch another agent to own this.\" Custom model or reasoning effort words such as `gpt-5.5`, `high`, or `xhigh` do not make the handoff supervised.\n\nSupervised orchestration remains available only when the user explicitly asks for supervision or coordination: \"supervise\", \"monitor\", \"wait for worker_done\", \"wait for results\", \"track completion\", \"DAG\", \"decision gate\", \"ask/reply\", or \"coordinate workers.\"\n\nDo not run `orca orchestration task-create`, `orca orchestration dispatch --inject`, or `orca orchestration check --wait` for full handoffs. `task-create` is also forbidden because it records coordinator-owned tracking state; if a task row is needed, the user asked for supervised orchestration. Do not create a `taskId`/`dispatchId`, inject a lifecycle preamble, wait for completion, or read the worker terminal after prompt delivery except to avoid losing the initial prompt.\n\nNew top-level worktree handoff:\n\n```bash\norca worktree create --name --no-parent --agent codex --prompt \"\" --setup run --json\n```\n\nBefore creating a new worktree from an active feature branch, decide and state whether the desired Orca lineage is child or top-level. Use child worktree lineage only when the new work is conceptually stacked under or dependent on the active worktree. For independent repo-wide fixes, standalone feature work, or unrelated follow-up tasks, create a top-level worktree with `--no-parent`.\n\nExisting terminal handoff:\n\n```bash\norca terminal send --terminal --text \"\" --enter --json\n```\n\nCustom Codex model/effort handoff:\n\n`orca worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. When the user asks for a specific Codex model or effort, create the independent worktree first, launch Codex with the requested command in that worktree, wait only for TUI readiness if prompt delivery would otherwise race startup, send the prompt, and stop.\n\nThe two-step custom-argv path cannot enforce a repository's explicit `wait-for-setup` startup policy because the later `terminal create` is not the startup owned by `worktree create`. Use it only when the repository starts agents immediately. If the repository requires `wait-for-setup`, use an agent-first configured launcher that can preserve sequencing, or stop and ask rather than silently bypassing the policy.\n\nNote: when no repo default-terminal configuration supplies a primary terminal, bare create opens a fallback shell before `terminal create` adds the agent. Configured default tabs are materialized instead and may run real commands. Prefer `--agent` whenever custom argv is not required. With the two-step path, target only the agent handle; close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell.\n\nUse the exact full `::` worktree id returned by `orca worktree create --json`; a bare repo id cannot target the new worktree.\n\n```bash\norca worktree create --name --no-parent --setup run --json\norca terminal create --worktree id: --title --command 'codex --model gpt-5.5 -c model_reasoning_effort=\"xhigh\"' --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca terminal send --terminal --text \"\" --enter --json\n```\n\nWait only for `tui-idle` when needed to avoid losing the prompt. Do not monitor task completion.\n\n`--no-parent` only controls Orca lineage; it does not choose the Git base. If the work should start from the repo default base, omit `--base-branch` so Orca uses that default, or explicitly pass the repo default base (`origin/main`, `origin/master`, or the `orca repo show --repo --json` value); never base it on the current feature branch unless the user explicitly asks for stacked work or \"branch from current\". Put current-branch context in the prompt instead.\n\n## Worker Terminals\n\nChoose the worker location before creating a terminal. `Fresh worker` means a fresh agent session, not a new git worktree. For parallel work, create one fresh agent terminal per worker in the same required worktree, falling back to the active worktree when none is named. If the task says current worktree only, depends on uncommitted files/artifacts, or must validate/PR the current branch, keep every worker in the active worktree:\n\n```bash\norca terminal create --worktree active --title --command \"codex\" --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration dispatch --task --to --inject --json\n```\n\nReuse an idle agent in the required worktree only if the prompt allows reuse; otherwise create a fresh terminal there. Create a new worktree only when the user explicitly requests one or a concrete checkout or filesystem conflict makes sharing unsafe or impossible; if the user did not request it, state that conflict before running `worktree create`. Independent tasks, parallel execution, convenience, or a preference for separate checkouts are not isolation requirements.\n\nWhen a new worktree is allowed, use child lineage for isolated work that is stacked under or dependent on the active worktree, and use `--no-parent` when it is not stacked. Decide the Git base separately: `--no-parent` makes the worktree top-level in Orca, while omitted `--base-branch` uses the repo default base.\n\nFor every new worktree, pass `--setup run` so any configured repository setup hook runs. This does not mean waiting for setup before agent launch: preserve the repository's startup policy, whose default starts setup and the agent side by side. Use `--setup skip` or `--setup inherit` only when there is a concrete task-specific reason, and state that reason before creating the worktree. This rule does not rerun setup for current or existing worktrees.\n\n```bash\norca worktree create --name --agent codex --setup run --json\n# or: --agent claude | omp | pi | grok | ...\n# Read from agentTerminalHandle, falling back to startupTerminal.handle.\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration dispatch --task --to --inject --json\n```\n\nFor new-worktree workers, read the id and `agentTerminalHandle` from `worktree create`, falling back to `startupTerminal.handle` for older runtimes. Use that as the sole worker handle when present; otherwise use `terminal list` to resolve the agent handle. Omit `--repo` only inside an Orca-managed worktree; otherwise pass `--repo `.\n\n**For an allowed new worktree, use agent-first:** `--agent` reveals the new worktree and launches the selected agent **in its first terminal**, without adding a separate fallback shell for that worker. Pass `--setup run`; repo setup and default-terminal settings may add intentional tabs or splits. Do **not** run bare `worktree create` and then `terminal create --command ` for the same worker when agent-first create is available: without configured default tabs, that two-step path leaves a fallback shell + agent pair. Only use it when custom agent argv is required (for example Codex model/effort flags) or when an older CLI rejects `--agent`; if you must, message only the agent handle. Configured default tabs are intentional surfaces, so close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell. Do not run `worktree create` when the task must stay in the current worktree.\n\nUse `orca worktree create --prompt ...` or `orca terminal send ...` for full handoffs or untracked/lightweight prompts. Those paths do not attach `taskId`/`dispatchId`; the worker should not send lifecycle messages unless the prompt supplies a live orchestration preamble.\n\nSidebar lineage and orchestration lifecycle are related but not identical. A same-worktree worker may appear as a peer under that worktree in the sidebar while remaining a child dispatch in orchestration state; only an actual child worktree creates visible parent/child worktree lineage.\n\nOther terminal commands coordinators often need:\n\n```bash\norca terminal list [--worktree ] [--json]\norca terminal create [--worktree ] [--title ] [--command ] [--json]\norca terminal split --terminal [--direction horizontal|vertical] [--command ] [--json]\norca terminal wait --terminal --for tui-idle --timeout-ms --json\norca terminal read --terminal --json\norca terminal send --terminal --text --enter --json\n```\n\nIf an older CLI rejects `worktree create --agent`, create the worktree normally, then run `orca terminal create --worktree --command \"codex\" --json` or `--command \"claude\"`.\n\nWait for `tui-idle` before dispatching. Always pass `--timeout-ms`; real coding tasks can take 15-60 minutes. During supervision, use rolling `check --wait` windows. If a window returns no matching message, inspect `task-list`, `terminal read`, or `terminal wait --for tui-idle` as a liveness checkpoint; if the terminal is still working or producing activity, keep waiting instead of retrying the task.\n\n## Agent Guidance\n\n- Workers with a valid live preamble must send `worker_done` exactly once from their own terminal with an explicit `--outcome succeeded` or `--outcome failed`:\n `orca orchestration send --type worker_done --subject \"\" --body \"<3-sentence summary: what you did, what you found, what's left>\" --task-id --dispatch-id --outcome succeeded --files-modified \"path/a\" --report-path \"\" --json`\n- A failed outcome is still a terminal report, but Orca records both the Dispatch and Task as failed. Never encode failure only in the subject/body.\n- After sending `worker_done`, end your turn and idle at the agent prompt. The coordinator may reuse or release this terminal after it processes your report; do not start more work, poll, or attempt to close the terminal yourself. If it reuses you, it re-engages you with a fresh preamble + TASK block delivered as new terminal input.\n- For long tasks, send heartbeat/status only when the preamble asks for it, including both IDs:\n `orca orchestration send --type heartbeat --subject \"alive\" --payload '{\"taskId\":\"\",\"dispatchId\":\"\",\"phase\":\"implementing\"}' --json`\n- If blocked before completion, use `ask`; use `escalation` only when ownership is valid and the coordinator must intervene.\n- Treat preambles inherited through terminal history or full handoffs as stale unless the current prompt explicitly keeps that coordinator in the loop.\n- Coordinators must account for every settled worker terminal before waiting again or ending the turn: immediately reuse the exact worker for a new Dispatch, explicitly retain it at the user's request with `worker-retain`, or run `worker-release`. Do not leave a completed worker live merely to inspect output; released workers remain readable through `worker-read`.\n- Coordinators should use `task-list --ready` as external memory, dispatch parallel waves, and avoid dependency chains deeper than 3-4 steps.\n\n## Example\n\n```bash\norca terminal create --worktree active --title login-css-worker --command \"claude\" --json\norca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\norca orchestration task-create --spec \"Fix the login button CSS\" --json\norca orchestration dispatch --task --to --inject --json\norca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json\n```\n\n## Next Action\n\nCoordinator: confirm `orca status --json`, create or bind a Run, inspect `task-list`/`dispatch-show` if inheriting state, then use the explicit supervised loop (`task-create` -> `worker-start` -> `check --wait`). Use low-level terminal creation plus `dispatch --inject` only when the composed start does not express the needed topology. After every accepted `worker_done`, either transfer the exact terminal to an immediate follow-up Dispatch or run `worker-release` before the next wait.\n\nWorker: if the current prompt contains a live dispatch preamble, do the task, use `ask` for blocking questions, and send `worker_done` once with the required payload. If the preamble is stale or absent, do not send lifecycle messages; inspect state or treat the prompt as an ordinary handoff.\n" // Why: no current guide has bundled reference documents, so --full is byte-identical for now. // oxfmt-ignore diff --git a/src/cli/handler-group-manifest.ts b/src/cli/handler-group-manifest.ts index 1cafa87cb95..346105d8732 100644 --- a/src/cli/handler-group-manifest.ts +++ b/src/cli/handler-group-manifest.ts @@ -109,6 +109,9 @@ export const HANDLER_GROUPS: readonly HandlerGroup[] = [ 'orchestration worker-read', 'orchestration worker-stop', 'orchestration worker-abandon', + 'orchestration worker-release', + 'orchestration worker-retain', + 'orchestration worker-list', 'orchestration dispatch', 'orchestration ask', 'orchestration dispatch-show', diff --git a/src/cli/handlers/orchestration.ts b/src/cli/handlers/orchestration.ts index 0b7ccdb7d6b..f9cbdb8a41a 100644 --- a/src/cli/handlers/orchestration.ts +++ b/src/cli/handlers/orchestration.ts @@ -79,6 +79,16 @@ const TASK_STATUS_VALUES = [ 'blocked' ] as const +// Why: mirrors WorkerTerminalListState (orchestration/types.ts) so a bad --terminal-state fails before the RPC. +const WORKER_TERMINAL_LIST_STATES = [ + 'active', + 'reclaimable', + 'retained', + 'release_pending', + 'release_unknown', + 'released' +] as const + type LifecycleSendRejection = { action: 'rejected' code: string @@ -422,6 +432,33 @@ function formatWorkerTranscriptMessage(message: NativeChatMessage): string { return `[${message.role}] ${blocks.join('\n')}`.trimEnd() } +type WorkerReleaseReceipt = { + dispatchId: string + state: string + reason?: string + processAction: string + archive: { source: string | null; status: string | null } | null + recovery?: string + lastError?: string +} + +function formatWorkerRelease(value: WorkerReleaseReceipt): string { + const head = `Worker ${value.dispatchId} terminal [${value.state}]` + const lines = [ + `${head}${value.reason ? ` reason=${value.reason}` : ''} process=${value.processAction}` + ] + if (value.archive) { + lines.push(`archive ${value.archive.source ?? 'none'} [${value.archive.status ?? 'unknown'}]`) + } + if (value.lastError) { + lines.push(value.lastError) + } + if (value.recovery) { + lines.push(value.recovery) + } + return lines.join('\n') +} + function safeJson(value: unknown): string { try { return JSON.stringify(value) @@ -930,6 +967,79 @@ export const ORCHESTRATION_HANDLERS: Record = { ) }, + 'orchestration worker-release': async ({ flags, client, json }) => { + const result = await callMutation( + client, + flags, + 'orchestration.workerRelease', + { dispatch: getRequiredStringFlag(flags, 'dispatch') } + ) + // Why: only an unprovable close is a failure; retained/pending/already-released are settled answers. + if (result.result.state === 'release_unknown') { + process.exitCode = 1 + } + printResult(result, json, formatWorkerRelease) + }, + + 'orchestration worker-retain': async ({ flags, client, json }) => { + const result = await callMutation( + client, + flags, + 'orchestration.workerRetain', + { dispatch: getRequiredStringFlag(flags, 'dispatch') } + ) + if (result.result.state === 'release_unknown') { + process.exitCode = 1 + } + printResult(result, json, formatWorkerRelease) + }, + + 'orchestration worker-list': async ({ flags, client, json }) => { + const terminalState = getOptionalStringFlag(flags, 'terminal-state') + if ( + terminalState && + !WORKER_TERMINAL_LIST_STATES.includes( + terminalState as (typeof WORKER_TERMINAL_LIST_STATES)[number] + ) + ) { + throw new RuntimeClientError( + 'invalid_argument', + `invalid --terminal-state '${terminalState}', expected one of: ${WORKER_TERMINAL_LIST_STATES.join(', ')}` + ) + } + const result = await client.call<{ + workers: { + dispatchId: string + taskId: string + runId: string + workerState: string + dispatchStatus: string + agentTerminalHandle: string | null + terminalState: string | null + resource: unknown + }[] + counts: Record + }>('orchestration.workerList', { + run: getOptionalStringFlag(flags, 'run'), + terminalState + }) + printResult(result, json, (r) => { + if (r.workers.length === 0) { + return 'No workers found.' + } + const rows = r.workers + .map( + (w) => + `${w.dispatchId} task=${w.taskId} [${w.workerState}] terminal=${w.terminalState ?? 'none'}` + ) + .join('\n') + const counts = Object.entries(r.counts) + .map(([state, count]) => `${state}=${count}`) + .join(' ') + return counts ? `${rows}\nTerminals: ${counts}` : rows + }) + }, + 'orchestration dispatch': async ({ flags, client, cwd, json }) => { const from = await resolveCoordinatorTerminalHandle(flags, cwd, client) const dryRun = flags.has('dry-run') ? true : undefined diff --git a/src/cli/handlers/worktree.ts b/src/cli/handlers/worktree.ts index 597ee437e10..51614029a99 100644 --- a/src/cli/handlers/worktree.ts +++ b/src/cli/handlers/worktree.ts @@ -280,6 +280,8 @@ export const WORKTREE_HANDLERS: Record = { const result = await client.call('worktree.rm', { worktree: await getRequiredWorktreeSelector(flags, 'worktree', cwd, client), force: flags.get('force') === true, + // Why (#11960): --force is explicit here, so it may also waive PTY-stop proof. + allowUnverifiedPtyStop: flags.get('force') === true, runHooks: flags.get('run-hooks') === true }) printHookWarning(result.result, json) diff --git a/src/cli/help.ts b/src/cli/help.ts index d85a318cb39..2ffa3ecd8df 100644 --- a/src/cli/help.ts +++ b/src/cli/help.ts @@ -111,6 +111,9 @@ Orchestration: orchestration worker-read Read bounded output from one supervised worker orchestration worker-stop Stop one supervised worker orchestration worker-abandon Fence an uncertain worker without claiming it stopped + orchestration worker-release Release a settled worker's terminal after archiving its output + orchestration worker-retain Keep a worker terminal live for debugging + orchestration worker-list Report worker terminal resource accounting orchestration coordinator-start Start the legacy automatic coordinator loop orchestration coordinator-stop Stop the legacy automatic coordinator loop orchestration gate-create Create a decision gate blocking a task @@ -444,6 +447,9 @@ function formatCommandFlagHelp(flag: string, commandPath: string[]): string { if (command === 'orchestration worker-read' && flag === 'cursor') { return '--cursor Opaque cursor returned by a previous worker-read page' } + if (command === 'orchestration worker-list' && flag === 'terminal-state') { + return '--terminal-state Terminal accounting filter: active, reclaimable, retained, release_pending, release_unknown, or released' + } if (command === 'linear list-issues' && flag === 'workspace') { return '--workspace Connected Linear workspace id, or all' } diff --git a/src/cli/index.test.ts b/src/cli/index.test.ts index 6eb064bee28..bca1910cb10 100644 --- a/src/cli/index.test.ts +++ b/src/cli/index.test.ts @@ -362,6 +362,15 @@ describe('orca root help', () => { expect(logSpy.mock.calls[0][0]).toContain( 'orchestration worker-abandon Fence an uncertain worker without claiming it stopped' ) + expect(logSpy.mock.calls[0][0]).toContain( + "orchestration worker-release Release a settled worker's terminal after archiving its output" + ) + expect(logSpy.mock.calls[0][0]).toContain( + 'orchestration worker-retain Keep a worker terminal live for debugging' + ) + expect(logSpy.mock.calls[0][0]).toContain( + 'orchestration worker-list Report worker terminal resource accounting' + ) expect(callMock).not.toHaveBeenCalled() }) diff --git a/src/cli/specs/orchestration-worker-specs.ts b/src/cli/specs/orchestration-worker-specs.ts index 2b05853e058..a8d8b2411f5 100644 --- a/src/cli/specs/orchestration-worker-specs.ts +++ b/src/cli/specs/orchestration-worker-specs.ts @@ -67,5 +67,39 @@ export const ORCHESTRATION_WORKER_COMMAND_SPECS: CommandSpec[] = [ 'orca orchestration worker-abandon --dispatch [--retry-request ] [--json]', allowedFlags: [...GLOBAL_FLAGS, 'dispatch', 'retry-request'], notes: ['Retains all possibly-live resources and performs no process or filesystem action.'] + }, + { + path: ['orchestration', 'worker-release'], + summary: 'Release the terminal of one settled supervised worker', + usage: + 'orca orchestration worker-release --dispatch [--retry-request ] [--json]', + allowedFlags: [...GLOBAL_FLAGS, 'dispatch', 'retry-request'], + notes: [ + 'Post-completion cleanup for a settled (succeeded or failed) worker; closes only the exact coordinator-owned agent terminal of that worker.', + 'An inspectable output archive is preserved before the terminal closes, so worker-read still returns output afterwards.', + 'Never closes setup terminals, configured tabs, reused or pre-existing terminals, user-taken-over terminals, or unproven identities.', + 'Idempotent: repeating the call reports already_released. Only release_unknown exits 1; retained, release_pending, and already_released exit 0.' + ] + }, + { + path: ['orchestration', 'worker-retain'], + summary: 'Keep one supervised worker terminal live for debugging', + usage: + 'orca orchestration worker-retain --dispatch [--retry-request ] [--json]', + allowedFlags: [...GLOBAL_FLAGS, 'dispatch', 'retry-request'], + notes: [ + 'Records a durable user-requested exception; a later explicit worker-release clears it and releases the terminal.', + 'Performs no process or filesystem action.' + ] + }, + { + path: ['orchestration', 'worker-list'], + summary: 'List supervised worker terminal resource accounting', + usage: + 'orca orchestration worker-list [--run ] [--terminal-state ] [--json]', + allowedFlags: [...GLOBAL_FLAGS, 'run', 'terminal-state'], + notes: [ + 'Terminal state is process accounting and is reported separately from Task status; a completed Task can still own a live terminal.' + ] } ] diff --git a/src/cli/terminal-format.test.ts b/src/cli/terminal-format.test.ts new file mode 100644 index 00000000000..014f6339823 --- /dev/null +++ b/src/cli/terminal-format.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest' +import { formatTerminalFocus } from './terminal-format' + +describe('formatTerminalFocus', () => { + it('distinguishes superseded navigation from a winning focus', () => { + expect( + formatTerminalFocus({ + focus: { + handle: 'term_stale', + tabId: 'tab-stale', + worktreeId: 'worktree-1', + navigated: false + } + }) + ).toBe( + 'Focus request for terminal term_stale was superseded or host navigation was skipped (tab tab-stale).' + ) + expect( + formatTerminalFocus({ + focus: { handle: 'term_winner', tabId: 'tab-winner', worktreeId: 'worktree-1' } + }) + ).toBe('Focused terminal term_winner (tab tab-winner).') + }) +}) diff --git a/src/cli/terminal-format.ts b/src/cli/terminal-format.ts index a6fbd6a9514..ae126fa6001 100644 --- a/src/cli/terminal-format.ts +++ b/src/cli/terminal-format.ts @@ -164,6 +164,9 @@ export function formatTerminalSplit(result: { split: RuntimeTerminalSplit }): st } export function formatTerminalFocus(result: { focus: RuntimeTerminalFocus }): string { + if (result.focus.navigated === false) { + return `Focus request for terminal ${result.focus.handle} was superseded or host navigation was skipped (tab ${result.focus.tabId}).` + } return `Focused terminal ${result.focus.handle} (tab ${result.focus.tabId}).` } diff --git a/src/main/agent-hooks/restored-subagent-liveness-sweep.test.ts b/src/main/agent-hooks/restored-subagent-liveness-sweep.test.ts index 9caf7966c83..9811773eb07 100644 --- a/src/main/agent-hooks/restored-subagent-liveness-sweep.test.ts +++ b/src/main/agent-hooks/restored-subagent-liveness-sweep.test.ts @@ -119,6 +119,7 @@ describe('restored subagent liveness sweep', () => { try { expect(paneStatus(server)).toEqual({ state: 'working', subagents: [WORKING_CHILD] }) const previous = server.getStatusSnapshotForPane(PANE)[0] + expect(previous?.restoredUnconfirmed).toBe(true) const previousReceivedAt = previous?.receivedAt ?? 0 const reconciledAt = previousReceivedAt + 1 const now = vi.spyOn(Date, 'now').mockReturnValue(previousReceivedAt) @@ -130,6 +131,8 @@ describe('restored subagent liveness sweep', () => { receivedAt: reconciledAt, stateStartedAt: reconciledAt }) + // Why: the reconciled `done` is process-probe-verified, so it must shed the hydrated-unconfirmed marker. + expect(server.getStatusSnapshotForPane(PANE)[0]?.restoredUnconfirmed).toBeUndefined() now.mockRestore() } finally { server.stop() @@ -163,7 +166,9 @@ describe('restored subagent liveness sweep', () => { state: 'waiting', subagents: undefined, receivedAt: previous?.receivedAt, - stateStartedAt: previous?.stateStartedAt + stateStartedAt: previous?.stateStartedAt, + // Why: a still-nonterminal reconciled row remains unconfirmed — only hooks or a terminal fact confirm it. + restoredUnconfirmed: true }) } finally { server.stop() diff --git a/src/main/agent-hooks/server.test.ts b/src/main/agent-hooks/server.test.ts index b3ff89ab355..96bb121c7e7 100644 --- a/src/main/agent-hooks/server.test.ts +++ b/src/main/agent-hooks/server.test.ts @@ -7026,6 +7026,294 @@ describe('Last-status persistence', () => { } }) + it('restores hydrated nonterminal statuses as unconfirmed until a live event lands', async () => { + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + payload: { state: 'working', prompt: 'may finish offline', agentType: 'claude' } + }, + 'conn-1' + ) + firstServer.ingestRemote( + { + paneKey: GOOD_PANE, + tabId: 'tab-good', + worktreeId: 'wt-1', + payload: { state: 'done', prompt: 'finished before restart', agentType: 'claude' } + }, + 'conn-1' + ) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + const listener = vi.fn() + server.setListener(listener) + expect(listener).toHaveBeenCalledWith( + expect.objectContaining({ paneKey: PANE, restoredUnconfirmed: true }) + ) + const byPane = new Map(server.getStatusSnapshot().map((entry) => [entry.paneKey, entry])) + expect(byPane.get(PANE)).toMatchObject({ state: 'working', restoredUnconfirmed: true }) + // Why: `done` is a terminal fact — no later transition can have been missed, so it restores confirmed. + expect(byPane.get(GOOD_PANE)?.restoredUnconfirmed).toBeUndefined() + + server.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + payload: { state: 'done', prompt: 'confirmed live', agentType: 'codex' } + }, + 'conn-1' + ) + const confirmed = server.getStatusSnapshot().find((entry) => entry.paneKey === PANE) + expect(confirmed).toMatchObject({ + state: 'done', + prompt: 'confirmed live', + agentType: 'codex' + }) + expect(confirmed?.restoredUnconfirmed).toBeUndefined() + } finally { + server.stop() + } + }) + + it('lets an identical live OSC observation confirm a hydrated row', async () => { + const payload = { + state: 'working' as const, + prompt: 'still running', + agentType: 'claude' as const + } + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestTerminalStatus({ + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + connectionId: null, + payload + }) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + const restored = server.getStatusSnapshot()[0] + if (!restored) { + throw new Error('expected hydrated status') + } + expect(restored?.restoredUnconfirmed).toBe(true) + vi.spyOn(Date, 'now').mockReturnValue(restored.receivedAt - 1_000) + server.ingestTerminalStatus({ + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + connectionId: null, + payload + }) + const confirmed = server.getStatusSnapshot()[0] + expect(confirmed?.restoredUnconfirmed).toBeUndefined() + expect(confirmed?.receivedAt).toBe(restored.receivedAt + 1) + } finally { + server.stop() + } + }) + + it('does not let a hydrated Claude permission suppress the first live working event', async () => { + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + hookEventName: 'PermissionRequest', + payload: { + state: 'waiting', + prompt: 'review command', + agentType: 'claude', + toolName: 'Bash', + toolInput: 'dangerous command' + } + }, + 'conn-1' + ) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + server.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + hookEventName: 'PreToolUse', + payload: { + state: 'working', + prompt: 'review command', + agentType: 'claude', + toolName: 'Read', + toolInput: 'package.json' + } + }, + 'conn-1' + ) + expect(server.getStatusSnapshot()[0]).toMatchObject({ + state: 'working', + toolName: 'Read' + }) + expect(server.getStatusSnapshot()[0]?.restoredUnconfirmed).toBeUndefined() + } finally { + server.stop() + } + }) + + it('does not inherit a stale tool id from hydrated Claude progress', async () => { + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + hookEventName: 'PreToolUse', + toolUseId: 'tool-old', + toolAgentType: 'main', + payload: { + state: 'working', + prompt: 'run tests', + agentType: 'claude', + toolName: 'Bash', + toolInput: 'pnpm test' + } + }, + 'conn-1' + ) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + server.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + hookEventName: 'PermissionRequest', + toolAgentType: 'main', + payload: { + state: 'waiting', + prompt: 'run tests', + agentType: 'claude', + toolName: 'Bash', + toolInput: 'pnpm test' + } + }, + 'conn-1' + ) + server.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + hookEventName: 'PostToolUse', + toolUseId: 'tool-new', + toolAgentType: 'main', + payload: { + state: 'working', + prompt: 'run tests', + agentType: 'claude', + toolName: 'Bash', + toolInput: 'pnpm test' + } + }, + 'conn-1' + ) + expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'working' }) + } finally { + server.stop() + } + }) + + it('never persists the unconfirmed flag and re-stamps it on every hydrate', async () => { + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + payload: { state: 'working', prompt: 'still running', agentType: 'claude' } + }, + 'conn-1' + ) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const secondServer = new AgentHookServer() + await secondServer.start({ env: 'production', userDataPath }) + secondServer.flushStatusPersistSync() + secondServer.stop() + expect(readFileSync(lastStatusPath(), 'utf8')).not.toContain('restoredUnconfirmed') + + const thirdServer = new AgentHookServer() + await thirdServer.start({ env: 'production', userDataPath }) + try { + expect(thirdServer.getStatusSnapshot()).toEqual([ + expect.objectContaining({ paneKey: PANE, state: 'working', restoredUnconfirmed: true }) + ]) + } finally { + thirdServer.stop() + } + }) + + it('refuses interrupt inference on an unconfirmed hydrated row', async () => { + const firstServer = new AgentHookServer() + await firstServer.start({ env: 'production', userDataPath }) + firstServer.ingestRemote( + { + paneKey: PANE, + tabId: 'tab-1', + worktreeId: 'wt-1', + payload: { state: 'working', prompt: 'long task', agentType: 'codex' } + }, + 'conn-1' + ) + firstServer.flushStatusPersistSync() + firstServer.stop() + + const server = new AgentHookServer() + await server.start({ env: 'production', userDataPath }) + try { + const baseline = server.getStatusSnapshot()[0] + expect(baseline).toMatchObject({ paneKey: PANE, restoredUnconfirmed: true }) + const applied = server.inferInterrupt({ + paneKey: PANE, + baselineUpdatedAt: baseline.receivedAt, + baselineStateStartedAt: baseline.stateStartedAt, + baselinePrompt: 'long task', + baselineAgentType: 'codex', + intent: 'plain-escape' + }) + // Why: synthesizing `done` onto a never-confirmed `working` would fabricate a transition from stale disk state. + expect(applied).toBe(false) + expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'working' }) + expect(server.getStatusSnapshot()[0]?.interrupted).toBeUndefined() + } finally { + server.stop() + } + }) + it('keeps SSH status ordering monotonic across hydration and clock rollback', async () => { const now = 1_700_000_000_000 vi.spyOn(Date, 'now').mockReturnValue(now) diff --git a/src/main/agent-hooks/server.ts b/src/main/agent-hooks/server.ts index 0f99f2cae9d..71fa1a6a0fc 100644 --- a/src/main/agent-hooks/server.ts +++ b/src/main/agent-hooks/server.ts @@ -83,6 +83,8 @@ export type { AgentHookSource } type EnrichedAgentHookEventPayload = AgentHookEventPayload & { receivedAt: number stateStartedAt: number + /** Stamped at hydrate for nonterminal states; never persisted (hydrate re-stamps) and cleared by any accepted live event replacing the entry. */ + restoredUnconfirmed?: true } type NormalizedLocalHook = { @@ -92,7 +94,7 @@ type NormalizedLocalHook = { type PersistedAgentHookEventPayload = Omit< EnrichedAgentHookEventPayload, - 'claudeRunningNonAgentTask' | 'launchToken' | 'promptInteractionKey' + 'claudeRunningNonAgentTask' | 'launchToken' | 'promptInteractionKey' | 'restoredUnconfirmed' > & { launchTokenHash?: string } @@ -378,6 +380,7 @@ function toAgentStatusIpcPayload(entry: EnrichedAgentHookEventPayload): AgentSta ...(entry.providerSession ? { providerSession: entry.providerSession } : {}), ...(entry.providerSessionOnly ? { providerSessionOnly: true } : {}), ...(entry.promptInteractionKey ? { promptInteractionKey: entry.promptInteractionKey } : {}), + ...(entry.restoredUnconfirmed ? { restoredUnconfirmed: true } : {}), ...entry.payload } } @@ -434,6 +437,9 @@ function shouldKeepClaudePermissionVisible( previous: EnrichedAgentHookEventPayload | undefined, next: AgentHookEventPayload ): boolean { + if (previous?.restoredUnconfirmed) { + return false + } if ( previous?.payload.agentType !== 'claude' || previous.payload.state !== 'waiting' || @@ -507,6 +513,7 @@ function shouldInheritClaudeToolUseIdForPermission( next: AgentHookEventPayload ): boolean { if ( + previous?.restoredUnconfirmed || previous?.payload.agentType !== 'claude' || previous.payload.state !== 'working' || previous.hookEventName !== 'PreToolUse' || @@ -728,6 +735,10 @@ export class AgentHookServer { if (existing.providerSessionOnly) { return false } + // Why: inference must not fabricate a `done` onto a row whose `working` was never confirmed this runtime. + if (existing.restoredUnconfirmed) { + return false + } const payload = existing.payload const agentType: AgentType | undefined = payload.agentType // Why: Droid's Ctrl+C exits the CLI (handled by PTY lifecycle) rather than interrupting the current turn. @@ -816,6 +827,10 @@ export class AgentHookServer { if (!existing) { return false } + // Why: inference must not fabricate a transition onto a row whose state was never confirmed this runtime. + if (existing.restoredUnconfirmed) { + return false + } const payload = existing.payload // Why: only Claude's interactive question clears on typed input — tool name (not hook event) discriminates; real permission waits stay sticky. if ( @@ -1069,8 +1084,13 @@ export class AgentHookServer { const connectionClearWatermark = payload.connectionId ? this.connectionTimestampWatermarkById.get(payload.connectionId) : undefined - // Why: Date.now() can repeat across reconnect; a remote replay must sort strictly after its connection's transient clear. - const now = Math.max(Date.now(), (connectionClearWatermark ?? -1) + 1) + // Why: renderer ordering rejects older rows; live evidence must sort after reconnect clears and restored rows across clock rollback. + const restoredStatusWatermark = previous?.restoredUnconfirmed ? previous.receivedAt : undefined + const now = Math.max( + Date.now(), + (connectionClearWatermark ?? -1) + 1, + (restoredStatusWatermark ?? -1) + 1 + ) if (payload.connectionId) { this.connectionTimestampWatermarkById.set(payload.connectionId, now) } @@ -1128,7 +1148,8 @@ export class AgentHookServer { ? { agentType: previous.payload.agentType, state: previous.payload.state, - updatedAt: previous.receivedAt + updatedAt: previous.receivedAt, + restoredUnconfirmed: previous.restoredUnconfirmed } : undefined, incoming: rootContextPreservingPayload.payload.agentType, @@ -1740,6 +1761,7 @@ export class AgentHookServer { | EnrichedAgentHookEventPayload | undefined if ( + !previous?.restoredUnconfirmed && previous?.connectionId === connectionId && previous.tabId === tabId && previous.worktreeId === worktreeId && @@ -2371,8 +2393,12 @@ export class AgentHookServer { const reconciledAt = stateChanged ? Math.max(Date.now(), enriched.receivedAt + 1) : enriched.receivedAt + // Why: a reconciled `done` is process-probe-verified, not hydrated guesswork — carrying + // restoredUnconfirmed onto it would make freshness gates suppress a legitimate completion. + const { restoredUnconfirmed, ...reconciledBase } = enriched const reconciled: EnrichedAgentHookEventPayload = { - ...enriched, + ...reconciledBase, + ...(state !== 'done' && restoredUnconfirmed ? { restoredUnconfirmed: true } : {}), receivedAt: reconciledAt, stateStartedAt: stateChanged ? reconciledAt : enriched.stateStartedAt, payload: { ...enriched.payload, state, subagents } @@ -2505,6 +2531,10 @@ export class AgentHookServer { (entry.payload.subagents?.length ?? 0) - (hydratedPayload.subagents?.length ?? 0) entry.payload = hydratedPayload } + if (entry.payload.state !== 'done') { + // Why: the terminal transition may have fired while no receiver was up; restore as unconfirmed, never as live truth. + entry.restoredUnconfirmed = true + } this.state.lastStatusByPaneKey.set(resolvedPaneKey, entry) if (entry.connectionId) { // Why: a restart can see an earlier wall clock; seed ordering so new events stay after disk state. @@ -2621,6 +2651,8 @@ export class AgentHookServer { const { claudeRunningNonAgentTask: _claudeRunningNonAgentTask, promptInteractionKey: _promptInteractionKey, + // Why: never persisted — hydrate re-stamps it, so a stored copy could only drift. + restoredUnconfirmed: _restoredUnconfirmed, launchToken, ...persistedPayload } = payload as EnrichedAgentHookEventPayload diff --git a/src/main/agent-hooks/wsl-hook-relay-sentinel.test.ts b/src/main/agent-hooks/wsl-hook-relay-sentinel.test.ts index b57be2544b6..d8f504beca3 100644 --- a/src/main/agent-hooks/wsl-hook-relay-sentinel.test.ts +++ b/src/main/agent-hooks/wsl-hook-relay-sentinel.test.ts @@ -21,7 +21,11 @@ function fakeChild(): FakeChild { resume: ReturnType } stderr: EventEmitter - stdin: EventEmitter & { write: ReturnType } + stdin: EventEmitter & { + write: ReturnType + destroyed: boolean + writable: boolean + } kill: ReturnType } child.stdout = Object.assign(new EventEmitter(), { @@ -29,7 +33,18 @@ function fakeChild(): FakeChild { resume: vi.fn() }) child.stderr = new EventEmitter() - child.stdin = Object.assign(new EventEmitter(), { write: vi.fn(() => true) }) + const stdin = new EventEmitter() as EventEmitter & { + write: ReturnType + destroyed: boolean + writable: boolean + } + stdin.write = vi.fn((_data, onWritten?: (error?: Error | null) => void) => { + onWritten?.(null) + return true + }) + stdin.destroyed = false + stdin.writable = true + child.stdin = stdin child.kill = vi.fn() return child as unknown as FakeChild } @@ -166,7 +181,7 @@ describe('waitForWslRelaySentinel', () => { const drain = vi.fn() const writeMock = child.stdin.write as ReturnType writeMock.mockImplementation((_data, onWritten) => { - onWritten(null) + onWritten?.(null) return false }) const promise = waitForWslRelaySentinel(child) @@ -180,4 +195,16 @@ describe('waitForWslRelaySentinel', () => { expect(drain).toHaveBeenCalledOnce() expect(transport.supportsWriteSettlement).toBe(true) }) + + it('swallows async stdin EPIPE after the guest dies so it is not uncaught', async () => { + const child = fakeChild() + const promise = waitForWslRelaySentinel(child) + emitStdout(child, RELAY_SENTINEL) + await promise + // Real pipes emit EPIPE on the stream after a failed write; without a + // listener Node surfaces that as an unhandled exception (CI flake). + expect(() => { + child.stdin.emit('error', Object.assign(new Error('write EPIPE'), { code: 'EPIPE' })) + }).not.toThrow() + }) }) diff --git a/src/main/agent-hooks/wsl-hook-relay-sentinel.ts b/src/main/agent-hooks/wsl-hook-relay-sentinel.ts index 5e1b5b5a872..41e6ebe9683 100644 --- a/src/main/agent-hooks/wsl-hook-relay-sentinel.ts +++ b/src/main/agent-hooks/wsl-hook-relay-sentinel.ts @@ -88,6 +88,12 @@ export function waitForWslRelaySentinel( child.on('error', (err) => fail({ kind: 'exit', code: null, stderr: `${stderrOutput}\n${err.message}` }) ) + // Why: stdin.write() surfaces EPIPE asynchronously when the guest dies + // mid-flight (try/catch only covers the sync throw). Without a listener + // Node treats that as an uncaught exception and fails the whole process. + child.stdin.on('error', () => { + // Channel already closing — mux close handling takes over. + }) child.on('exit', (code) => { exitCode = code }) diff --git a/src/main/ai-vault/ai-vault-scan-cancellation.test.ts b/src/main/ai-vault/ai-vault-scan-cancellation.test.ts new file mode 100644 index 00000000000..74bf27bdc74 --- /dev/null +++ b/src/main/ai-vault/ai-vault-scan-cancellation.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, it } from 'vitest' +import { abandonRemoteSessionScanOnCancel } from './ai-vault-scan-cancellation' + +describe('abandonRemoteSessionScanOnCancel', () => { + it('stops waiting on a scan that has no transport-level abort', async () => { + const controller = new AbortController() + const pending = abandonRemoteSessionScanOnCancel( + new Promise(() => {}), + controller.signal + ) + + controller.abort() + + await expect(pending).rejects.toMatchObject({ name: 'AbortError' }) + }) + + it('rejects immediately when the caller already cancelled', async () => { + const controller = new AbortController() + controller.abort() + + await expect( + abandonRemoteSessionScanOnCancel(Promise.resolve('scanned'), controller.signal) + ).rejects.toMatchObject({ name: 'AbortError' }) + }) + + it('passes the scan result through without a signal', async () => { + await expect(abandonRemoteSessionScanOnCancel(Promise.resolve('scanned'))).resolves.toBe( + 'scanned' + ) + }) +}) diff --git a/src/main/ai-vault/ai-vault-scan-cancellation.ts b/src/main/ai-vault/ai-vault-scan-cancellation.ts new file mode 100644 index 00000000000..65ecf772cc3 --- /dev/null +++ b/src/main/ai-vault/ai-vault-scan-cancellation.ts @@ -0,0 +1,47 @@ +import { AI_VAULT_SCAN_CANCELLED_MESSAGE } from '../../shared/ai-vault-types' + +export function throwIfAiVaultScanCancelled(signal?: AbortSignal): void { + if (!signal?.aborted) { + return + } + throw createAiVaultScanCancelledError() +} + +// Why: the runtime RPC transport has no abort hook, so cancellation can only +// stop the caller waiting on it — the in-flight request settles on its own +// timeout instead of holding an 'all'-scope merge open after every waiter left. +export function abandonRemoteSessionScanOnCancel( + promise: Promise, + signal?: AbortSignal +): Promise { + if (!signal) { + return promise + } + return new Promise((resolve, reject) => { + if (signal.aborted) { + // The scanner promise already exists; observe it so its later failure is + // not an unhandled rejection after this caller walked away. + void promise.catch(() => undefined) + reject(createAiVaultScanCancelledError()) + return + } + const onAbort = (): void => reject(createAiVaultScanCancelledError()) + signal.addEventListener('abort', onAbort, { once: true }) + void promise.then( + (value) => { + signal.removeEventListener('abort', onAbort) + resolve(value) + }, + (error: unknown) => { + signal.removeEventListener('abort', onAbort) + reject(error) + } + ) + }) +} + +export function createAiVaultScanCancelledError(): Error { + const error = new Error(AI_VAULT_SCAN_CANCELLED_MESSAGE) + error.name = 'AbortError' + return error +} diff --git a/src/main/ai-vault/ai-vault-scan-coordinator.test.ts b/src/main/ai-vault/ai-vault-scan-coordinator.test.ts new file mode 100644 index 00000000000..6464770d516 --- /dev/null +++ b/src/main/ai-vault/ai-vault-scan-coordinator.test.ts @@ -0,0 +1,148 @@ +import { describe, expect, it, vi } from 'vitest' +import { AiVaultScanCoordinator } from './ai-vault-scan-coordinator' + +const EMPTY_RESULT = { sessions: [], issues: [], scannedAt: '2026-07-27T00:00:00.000Z' } + +describe('AiVaultScanCoordinator', () => { + it('keeps a shared scan alive when only one caller cancels', async () => { + const coordinator = new AiVaultScanCoordinator() + let resolveScan: ((result: typeof EMPTY_RESULT) => void) | undefined + let sharedSignal: AbortSignal | undefined + const start = vi.fn( + (signal: AbortSignal) => + new Promise((resolve) => { + sharedSignal = signal + resolveScan = resolve + }) + ) + const controller = new AbortController() + const first = coordinator.run({ key: 'scope', signal: controller.signal, start }) + const second = coordinator.run({ key: 'scope', start }) + await Promise.resolve() + + controller.abort() + + await expect(first).rejects.toMatchObject({ name: 'AbortError' }) + expect(sharedSignal?.aborted).toBe(false) + resolveScan?.(EMPTY_RESULT) + await expect(second).resolves.toEqual(EMPTY_RESULT) + expect(start).toHaveBeenCalledTimes(1) + }) + + it('preempts a non-forced scan and re-joins its caller onto the forced scan', async () => { + const coordinator = new AiVaultScanCoordinator() + const signals: AbortSignal[] = [] + let resolveForced: ((result: typeof EMPTY_RESULT) => void) | undefined + const start = vi.fn((signal: AbortSignal) => { + signals.push(signal) + return new Promise((resolve) => { + if (signals.length === 1) { + signal.addEventListener('abort', () => resolve(EMPTY_RESULT), { once: true }) + } else { + resolveForced = resolve + } + }) + }) + const first = coordinator.run({ key: 'scope', start }) + await Promise.resolve() + + const forced = coordinator.run({ key: 'scope', force: true, start }) + const joined = coordinator.run({ key: 'scope', force: true, start }) + await Promise.resolve() + + expect(signals[0]?.aborted).toBe(true) + expect(start).toHaveBeenCalledTimes(2) + resolveForced?.(EMPTY_RESULT) + // The first caller never asked to cancel, so someone else's Refresh must + // hand it the replacement's result instead of a spurious cancellation. + await expect(Promise.all([first, forced, joined])).resolves.toEqual([ + EMPTY_RESULT, + EMPTY_RESULT, + EMPTY_RESULT + ]) + }) + + it('keeps coalescing forced callers onto a forced scan that is still fresh', async () => { + vi.useFakeTimers() + try { + const coordinator = new AiVaultScanCoordinator() + let resolveScan: ((result: typeof EMPTY_RESULT) => void) | undefined + const start = vi.fn( + () => + new Promise((resolve) => { + resolveScan = resolve + }) + ) + const first = coordinator.run({ key: 'scope', force: true, start }) + await Promise.resolve() + + vi.advanceTimersByTime(4_999) + const second = coordinator.run({ key: 'scope', force: true, start }) + await Promise.resolve() + + expect(start).toHaveBeenCalledTimes(1) + resolveScan?.(EMPTY_RESULT) + // Both callers settle off the single shared scan instead of preempting it. + await expect(Promise.all([first, second])).resolves.toEqual([EMPTY_RESULT, EMPTY_RESULT]) + } finally { + vi.useRealTimers() + } + }) + + it('lets a forced refresh preempt a forced scan that hung past the coalescing window', async () => { + vi.useFakeTimers() + try { + const coordinator = new AiVaultScanCoordinator() + const signals: AbortSignal[] = [] + let resolveSecond: ((result: typeof EMPTY_RESULT) => void) | undefined + const start = vi.fn((signal: AbortSignal) => { + signals.push(signal) + return new Promise((resolve) => { + if (signals.length > 1) { + resolveSecond = resolve + } + }) + }) + const stuck = coordinator.run({ key: 'scope', force: true, start }) + await Promise.resolve() + + vi.advanceTimersByTime(5_000) + const retry = coordinator.run({ key: 'scope', force: true, start }) + await Promise.resolve() + + expect(signals[0]?.aborted).toBe(true) + expect(start).toHaveBeenCalledTimes(2) + resolveSecond?.(EMPTY_RESULT) + // The caller stranded on the hung scan rides the replacement out rather + // than being told its own refresh was cancelled. + await expect(Promise.all([stuck, retry])).resolves.toEqual([EMPTY_RESULT, EMPTY_RESULT]) + } finally { + vi.useRealTimers() + } + }) + + it('starts a fresh scan after every waiter cancels', async () => { + const coordinator = new AiVaultScanCoordinator() + const signals: AbortSignal[] = [] + const start = vi.fn((signal: AbortSignal) => { + signals.push(signal) + if (signals.length > 1) { + return Promise.resolve(EMPTY_RESULT) + } + return new Promise((resolve) => { + signal.addEventListener('abort', () => resolve(EMPTY_RESULT), { once: true }) + }) + }) + const controller = new AbortController() + const first = coordinator.run({ key: 'scope', signal: controller.signal, start }) + await Promise.resolve() + controller.abort() + await expect(first).rejects.toMatchObject({ name: 'AbortError' }) + + const second = coordinator.run({ key: 'scope', start }) + + await expect(second).resolves.toEqual(EMPTY_RESULT) + expect(start).toHaveBeenCalledTimes(2) + expect(signals[0]?.aborted).toBe(true) + }) +}) diff --git a/src/main/ai-vault/ai-vault-scan-coordinator.ts b/src/main/ai-vault/ai-vault-scan-coordinator.ts new file mode 100644 index 00000000000..7e704e4b820 --- /dev/null +++ b/src/main/ai-vault/ai-vault-scan-coordinator.ts @@ -0,0 +1,155 @@ +import { + AI_VAULT_SCAN_CANCELLED_MESSAGE, + type AiVaultListResult +} from '../../shared/ai-vault-types' + +// Matches the renderer's forced-rescan throttle: forced callers that arrive +// inside this window share one scan, later ones may preempt a scan that hung. +const FORCED_SCAN_PREEMPT_AFTER_MS = 5_000 + +type ScanEntry = { + controller: AbortController + force: boolean + startedAt: number + promise: Promise + waiterCount: number + // The last waiter leaving must not abort a scan that already finished. + settled: boolean + // Set when a forced caller replaced this entry, so its waiters re-join the + // replacement instead of surfacing someone else's refresh as their own cancel. + preemptedBy: ScanEntry | null +} + +export class AiVaultScanCoordinator { + private readonly entries = new Map() + + run(args: { + key: string + force?: boolean + signal?: AbortSignal + start: (signal: AbortSignal) => Promise + }): Promise { + if (args.signal?.aborted) { + return Promise.reject(scanCancellationError()) + } + let entry = this.entries.get(args.key) + const preempted = entry && args.force === true && canPreemptForForcedScan(entry) ? entry : null + if (preempted) { + this.removeEntry(args.key, preempted) + entry = undefined + } + if (!entry) { + entry = this.createEntry(args.key, args.force === true, args.start) + this.entries.set(args.key, entry) + } + if (preempted) { + // The replacement must be registered before the abort lands: waiters of + // the old scan re-join it synchronously from their abort listener. + preempted.preemptedBy = entry + preempted.controller.abort() + } + return this.attach(args.key, entry, args.signal) + } + + private createEntry( + key: string, + force: boolean, + start: (signal: AbortSignal) => Promise + ): ScanEntry { + const controller = new AbortController() + const entry: ScanEntry = { + controller, + force, + startedAt: Date.now(), + promise: Promise.resolve().then(() => { + if (controller.signal.aborted) { + throw scanCancellationError() + } + return start(controller.signal) + }), + waiterCount: 0, + settled: false, + preemptedBy: null + } + const onSettled = (): void => { + entry.settled = true + this.removeEntry(key, entry) + } + void entry.promise.then(onSettled, onSettled) + return entry + } + + private attach(key: string, entry: ScanEntry, signal?: AbortSignal): Promise { + entry.waiterCount++ + return new Promise((resolve, reject) => { + let attached = true + const detach = (): void => { + if (!attached) { + return + } + attached = false + signal?.removeEventListener('abort', onAbort) + entry.controller.signal.removeEventListener('abort', onAbort) + entry.waiterCount-- + if (entry.waiterCount === 0 && !entry.settled && !entry.controller.signal.aborted) { + this.removeEntry(key, entry) + entry.controller.abort() + } + } + const onAbort = (): void => { + if (!attached) { + return + } + // Why: a forced refresh aborts the shared entry, but the other waiters + // never asked to cancel — rejecting them turns one window's Refresh into + // a cancelled multi-host merge somewhere else. Re-join the replacement. + const replacement = signal?.aborted ? null : entry.preemptedBy + detach() + if (!replacement) { + reject(scanCancellationError()) + return + } + void this.attach(key, replacement, signal).then(resolve, reject) + } + signal?.addEventListener('abort', onAbort, { once: true }) + entry.controller.signal.addEventListener('abort', onAbort, { once: true }) + if (signal?.aborted || entry.controller.signal.aborted) { + onAbort() + return + } + void entry.promise.then( + (result) => { + if (attached) { + detach() + resolve(result) + } + }, + (error) => { + if (attached) { + detach() + reject(error) + } + } + ) + }) + } + + private removeEntry(key: string, entry: ScanEntry): void { + if (this.entries.get(key) === entry) { + this.entries.delete(key) + } + } +} + +// Why: without this a forced scan that never settles (no inactivity timer on the +// legacy SSH file-stream reader, see #11364) makes every later Refresh join the +// dead promise, so the panel stays empty until the app restarts. +function canPreemptForForcedScan(entry: ScanEntry): boolean { + return !entry.force || Date.now() - entry.startedAt >= FORCED_SCAN_PREEMPT_AFTER_MS +} + +function scanCancellationError(): Error { + const error = new Error(AI_VAULT_SCAN_CANCELLED_MESSAGE) + error.name = 'AbortError' + return error +} diff --git a/src/main/ai-vault/cached-session-list.ts b/src/main/ai-vault/cached-session-list.ts index 4b39e75eb72..facf417cdbb 100644 --- a/src/main/ai-vault/cached-session-list.ts +++ b/src/main/ai-vault/cached-session-list.ts @@ -3,6 +3,13 @@ import { scanAiVaultSessions } from './session-scanner' import { getWslHomeAsync, listWslDistrosAsync } from '../wsl' import type { AiVaultListArgs, AiVaultListResult } from '../../shared/ai-vault-types' import { LOCAL_EXECUTION_HOST_ID } from '../../shared/execution-host' +import { AiVaultScanCoordinator } from './ai-vault-scan-coordinator' +import { + aiVaultSessionDepthCovers, + requestedAiVaultSessionDepth, + truncateAiVaultListResult, + type AiVaultSessionDepth +} from '../../shared/ai-vault-session-depth' // Why: ONE module owns the scan cache so the desktop IPC handler AND the runtime // RPC method share a single cache instance — opening the desktop panel and the @@ -19,65 +26,77 @@ export type AiVaultSessionSources = { type CachedAiVaultList = { key: string + depth: AiVaultSessionDepth result: AiVaultListResult expiresAt: number } let cachedList: CachedAiVaultList | null = null -let inflightList: Promise | null = null -let inflightKey: string | null = null +let scanCoordinator = new AiVaultScanCoordinator() let sources: AiVaultSessionSources = {} export function configureAiVaultSessionSources(next: AiVaultSessionSources): void { sources = next } -export async function listAiVaultSessions(args?: AiVaultListArgs): Promise { +export async function listAiVaultSessions( + args?: AiVaultListArgs, + options: { signal?: AbortSignal } = {} +): Promise { // Scope paths change the result set, so they must be part of the cache key. - const key = JSON.stringify({ - limit: args?.limit ?? 'default', - scopePaths: args?.scopePaths ?? [] - }) + const key = JSON.stringify({ scopePaths: [...new Set(args?.scopePaths ?? [])].sort() }) + const depth = requestedAiVaultSessionDepth(args) + const scanKey = JSON.stringify({ key, depth }) const now = Date.now() // Why: opening this panel repeatedly should not re-parse hundreds of JSONL - // transcripts; explicit refreshes bypass the cache but not an active scan. - if (args?.force !== true && cachedList?.key === key && cachedList.expiresAt > now) { - return cachedList.result + // transcripts; explicit refreshes bypass the cache and preempt stale scans. + if ( + args?.force !== true && + cachedList?.key === key && + cachedList.expiresAt > now && + aiVaultSessionDepthCovers(cachedList.depth, depth) + ) { + return truncateAiVaultListResult(cachedList.result, depth, args?.scopePaths) } - if (inflightList && inflightKey === key) { - return inflightList - } - - inflightKey = key - const additionalCodexSessionsDirs = - sources.getAdditionalCodexHomePaths?.().map((homePath) => join(homePath, 'sessions')) ?? [] - inflightList = (async () => - scanAiVaultSessions({ - limit: args?.limit, - scopePaths: args?.scopePaths, - additionalCodexSessionsDirs, - wslHomeDirs: await getAiVaultWslHomeDirs(), - // Why: this scan is always host-local; callers addressing this host by a - // runtime id get the result restamped at the RPC edge, never rescanned. - executionHostId: LOCAL_EXECUTION_HOST_ID - }))() - .then((result) => { - cachedList = { - key, - result, - expiresAt: Date.now() + AI_VAULT_CACHE_TTL_MS + return scanCoordinator.run({ + key: scanKey, + force: args?.force, + signal: options.signal, + start: async (scanSignal) => { + const additionalCodexSessionsDirs = + sources.getAdditionalCodexHomePaths?.().map((homePath) => join(homePath, 'sessions')) ?? [] + const result = await scanAiVaultSessions({ + limit: args?.limit, + unlimited: args?.unlimited, + scopePaths: args?.scopePaths, + additionalCodexSessionsDirs, + wslHomeDirs: await getAiVaultWslHomeDirs(), + // Cancelled/superseded callers must stop the parse, not just stop + // waiting for it — the scan owns hundreds of transcript reads. + signal: scanSignal, + // Why: this scan is always host-local; callers addressing this host by a + // runtime id get the result restamped at the RPC edge, never rescanned. + executionHostId: LOCAL_EXECUTION_HOST_ID + }) + if (!scanSignal.aborted) { + const current = cachedList + if ( + args?.force === true || + current?.key !== key || + current.expiresAt <= Date.now() || + !aiVaultSessionDepthCovers(current.depth, depth) + ) { + cachedList = { + key, + depth, + result, + expiresAt: Date.now() + AI_VAULT_CACHE_TTL_MS + } + } } return result - }) - .finally(() => { - // Only clear tracking if it still refers to this request: a concurrent - // different-key scan may have replaced it and must stay dedupable. - if (inflightKey === key) { - inflightKey = null - inflightList = null - } - }) - return inflightList + } + }) } // Exported for the subagent-transcript IPC path, which validates @@ -95,7 +114,6 @@ export async function getAiVaultWslHomeDirs(): Promise { // Why: tests reset module-level cache/source state between cases. export function resetAiVaultSessionListCacheForTests(): void { cachedList = null - inflightList = null - inflightKey = null + scanCoordinator = new AiVaultScanCoordinator() sources = {} } diff --git a/src/main/ai-vault/remote-session-content-lines.ts b/src/main/ai-vault/remote-session-content-lines.ts new file mode 100644 index 00000000000..9a107fd1ef3 --- /dev/null +++ b/src/main/ai-vault/remote-session-content-lines.ts @@ -0,0 +1,47 @@ +import { setImmediate as yieldToEventLoop } from 'node:timers/promises' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' + +const REMOTE_CONTENT_YIELD_LINE_COUNT = 200 +const REMOTE_CONTENT_YIELD_CHAR_COUNT = 256 * 1024 + +/** Splits transcript content into lines. Without a signal there is nothing to + * observe, so it splits in one pass; with one it yields to the event loop so a + * cancelled scan stops mid-transcript instead of parsing megabytes for a caller + * that already left. */ +export function remoteSessionContentLines( + content: string, + signal?: AbortSignal +): Iterable | AsyncIterable { + return signal ? cancellableContentLines(content, signal) : content.split(/\r?\n/) +} + +async function* cancellableContentLines( + content: string, + signal: AbortSignal +): AsyncGenerator { + // Content below one yield window would otherwise never observe cancellation. + throwIfAiVaultScanCancelled(signal) + let lineStart = 0 + let yieldStart = 0 + let linesSinceYield = 0 + + for (let index = 0; index <= content.length; index++) { + if (index < content.length && content.charCodeAt(index) !== 10) { + continue + } + const lineEnd = index > lineStart && content.charCodeAt(index - 1) === 13 ? index - 1 : index + yield content.slice(lineStart, lineEnd) + lineStart = index + 1 + linesSinceYield++ + if ( + linesSinceYield >= REMOTE_CONTENT_YIELD_LINE_COUNT || + index - yieldStart >= REMOTE_CONTENT_YIELD_CHAR_COUNT + ) { + throwIfAiVaultScanCancelled(signal) + await yieldToEventLoop() + throwIfAiVaultScanCancelled(signal) + linesSinceYield = 0 + yieldStart = index + } + } +} diff --git a/src/main/ai-vault/remote-session-file-stat.ts b/src/main/ai-vault/remote-session-file-stat.ts index 238ea13aa65..aa5809a776d 100644 --- a/src/main/ai-vault/remote-session-file-stat.ts +++ b/src/main/ai-vault/remote-session-file-stat.ts @@ -1,19 +1,24 @@ import type { AiVaultAgent, AiVaultScanIssue } from '../../shared/ai-vault-types' import type { ExecutionHostId } from '../../shared/execution-host' -import type { FileStat, IFilesystemProvider } from '../providers/types' +import type { FileStat } from '../providers/types' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' +import { recordRemoteSessionScanIssue } from './remote-session-scan-issues' +import type { RemoteSessionFilesystemProvider } from './remote-session-scanner-types' import type { FileWithMtime } from './session-scanner-types' import { errorMessage } from './session-scanner-values' export async function statRemoteSessionFile( - provider: IFilesystemProvider, + provider: RemoteSessionFilesystemProvider, path: string, agent: AiVaultAgent, executionHostId: ExecutionHostId, issues: AiVaultScanIssue[], - options?: { missingIsExpected?: boolean } + options?: { missingIsExpected?: boolean; signal?: AbortSignal } ): Promise { try { + throwIfAiVaultScanCancelled(options?.signal) const stat = await provider.stat(path) + throwIfAiVaultScanCancelled(options?.signal) const mtimeMs = remoteSessionMtimeMs(stat) return { path, @@ -25,8 +30,14 @@ export async function statRemoteSessionFile( ...(typeof stat.nlink === 'number' ? { nlink: stat.nlink } : {}) } } catch (error) { + throwIfAiVaultScanCancelled(options?.signal) if (!options?.missingIsExpected || !isMissingRemoteSessionPathError(error)) { - issues.push({ executionHostId, agent, path, message: errorMessage(error) }) + recordRemoteSessionScanIssue(issues, { + executionHostId, + agent, + path, + message: errorMessage(error) + }) } return null } diff --git a/src/main/ai-vault/remote-session-scan-batching.test.ts b/src/main/ai-vault/remote-session-scan-batching.test.ts new file mode 100644 index 00000000000..da9ee87601c --- /dev/null +++ b/src/main/ai-vault/remote-session-scan-batching.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from 'vitest' +import { mapRemoteScanBatches } from './remote-session-scan-batching' + +describe('mapRemoteScanBatches', () => { + it('observes an abort that lands while the final batch yields', async () => { + const controller = new AbortController() + + await expect( + mapRemoteScanBatches( + ['a', 'b'], + 2, + async (item) => { + controller.abort() + return item + }, + controller.signal + ) + ).rejects.toMatchObject({ name: 'AbortError' }) + }) + + it('observes an abort for empty inputs that never enter the loop', async () => { + const controller = new AbortController() + controller.abort() + + await expect( + mapRemoteScanBatches([], 8, async (item) => item, controller.signal) + ).rejects.toMatchObject({ name: 'AbortError' }) + }) + + it('returns every batch result when nothing cancels', async () => { + expect(await mapRemoteScanBatches([1, 2, 3], 2, async (item) => item * 2)).toEqual([2, 4, 6]) + }) +}) diff --git a/src/main/ai-vault/remote-session-scan-batching.ts b/src/main/ai-vault/remote-session-scan-batching.ts new file mode 100644 index 00000000000..d51703e1b15 --- /dev/null +++ b/src/main/ai-vault/remote-session-scan-batching.ts @@ -0,0 +1,22 @@ +import { setImmediate as yieldToEventLoop } from 'node:timers/promises' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' + +// Batching bounds concurrent remote round trips; the yield between batches keeps +// the process responsive, and the batch boundary is where cancellation lands. +export async function mapRemoteScanBatches( + items: readonly T[], + concurrency: number, + mapper: (item: T) => Promise, + signal?: AbortSignal +): Promise { + const results: U[] = [] + for (let index = 0; index < items.length; index += concurrency) { + throwIfAiVaultScanCancelled(signal) + results.push(...(await Promise.all(items.slice(index, index + concurrency).map(mapper)))) + await yieldToEventLoop() + } + // An abort can land while the last batch yields, and empty inputs never enter + // the loop at all — observe it here so neither path returns as a success. + throwIfAiVaultScanCancelled(signal) + return results +} diff --git a/src/main/ai-vault/remote-session-scan-concurrency.ts b/src/main/ai-vault/remote-session-scan-concurrency.ts new file mode 100644 index 00000000000..77b8e371b51 --- /dev/null +++ b/src/main/ai-vault/remote-session-scan-concurrency.ts @@ -0,0 +1,47 @@ +import type { RemoteSessionFilesystemProvider } from './remote-session-scanner-types' + +// Why: discovery batches (8 sources) each stat in batches of 8, and parse +// batches read whole transcripts — nested fan-out put ~64 filesystem round +// trips on one SSH mux or relay event loop at once, blowing the scan budget and +// starving pty/fs/hook traffic. Every scan shares one in-flight ceiling. +const REMOTE_SCAN_FILESYSTEM_CONCURRENCY = 8 + +/** Wraps a provider so all of one scan's filesystem calls share a single + * in-flight ceiling, regardless of how the callers nest their batches. */ +export function limitRemoteScanFilesystemConcurrency( + provider: RemoteSessionFilesystemProvider, + maxInFlight: number = REMOTE_SCAN_FILESYSTEM_CONCURRENCY +): RemoteSessionFilesystemProvider { + const gate = createConcurrencyGate(maxInFlight) + return { + readDir: (dirPath) => gate(() => provider.readDir(dirPath)), + readFile: (filePath) => gate(() => provider.readFile(filePath)), + stat: (filePath) => gate(() => provider.stat(filePath)) + } +} + +function createConcurrencyGate(maxInFlight: number): (run: () => Promise) => Promise { + const limit = Math.max(1, Math.floor(maxInFlight)) + const waiting: (() => void)[] = [] + let inFlight = 0 + + return async (run: () => Promise): Promise => { + if (inFlight < limit) { + inFlight++ + } else { + // The releasing call hands its slot over directly, so a queued caller can + // never race a fresh one into an over-limit slot. + await new Promise((resolve) => waiting.push(resolve)) + } + try { + return await run() + } finally { + const next = waiting.shift() + if (next) { + next() + } else { + inFlight-- + } + } + } +} diff --git a/src/main/ai-vault/remote-session-scan-issues.ts b/src/main/ai-vault/remote-session-scan-issues.ts new file mode 100644 index 00000000000..aee229f443c --- /dev/null +++ b/src/main/ai-vault/remote-session-scan-issues.ts @@ -0,0 +1,24 @@ +import type { AiVaultScanIssue } from '../../shared/ai-vault-types' + +const REMOTE_SCAN_ISSUE_LIMIT = 500 + +export function recordRemoteSessionScanIssue( + issues: AiVaultScanIssue[], + issue: AiVaultScanIssue +): void { + if (issues.length < REMOTE_SCAN_ISSUE_LIMIT - 1) { + issues.push(issue) + return + } + if (issues.length === REMOTE_SCAN_ISSUE_LIMIT - 1) { + // Kinded: this row is a scan notice, not a skipped transcript — the panel + // counts unkinded issues as skipped transcript files. + issues.push({ + executionHostId: issue.executionHostId, + agent: issue.agent, + kind: 'notice', + path: 'Agent Session History scan', + message: 'Additional scan issues were omitted.' + }) + } +} diff --git a/src/main/ai-vault/remote-session-scanner-codex-index.ts b/src/main/ai-vault/remote-session-scanner-codex-index.ts index d6a305ba4cf..8f5ec3c1bbb 100644 --- a/src/main/ai-vault/remote-session-scanner-codex-index.ts +++ b/src/main/ai-vault/remote-session-scanner-codex-index.ts @@ -1,39 +1,50 @@ -import type { IFilesystemProvider } from '../providers/types' import type { RemoteHostPlatform } from '../ssh/ssh-remote-platform' import { joinRemotePath } from '../ssh/ssh-remote-platform' import { extractString, normalizeTitleText, parseJsonObject } from './session-scanner-values' +import { remoteSessionContentLines } from './remote-session-content-lines' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' +import type { RemoteSessionFilesystemProvider } from './remote-session-scanner-types' const CODEX_SESSION_INDEX_FILE = 'session_index.jsonl' export async function remoteCodexIndexTitles(args: { - provider: IFilesystemProvider + provider: RemoteSessionFilesystemProvider codexHome: string hostPlatform: RemoteHostPlatform titleCaches: Map>> + signal?: AbortSignal }): Promise> { const cached = args.titleCaches.get(args.codexHome) if (cached) { return cached } - const pending = readRemoteCodexIndexTitles(args.provider, args.codexHome, args.hostPlatform) + const pending = readRemoteCodexIndexTitles( + args.provider, + args.codexHome, + args.hostPlatform, + args.signal + ) args.titleCaches.set(args.codexHome, pending) return pending } async function readRemoteCodexIndexTitles( - provider: IFilesystemProvider, + provider: RemoteSessionFilesystemProvider, codexHome: string, - hostPlatform: RemoteHostPlatform + hostPlatform: RemoteHostPlatform, + signal?: AbortSignal ): Promise> { const titleBySessionId = new Map() try { + throwIfAiVaultScanCancelled(signal) const { content, isBinary } = await provider.readFile( joinRemotePath(hostPlatform, codexHome, CODEX_SESSION_INDEX_FILE) ) + throwIfAiVaultScanCancelled(signal) if (isBinary) { return titleBySessionId } - for (const line of content.split(/\r?\n/)) { + for await (const line of remoteSessionContentLines(content, signal)) { const record = parseJsonObject(line) if (!record) { continue @@ -45,6 +56,7 @@ async function readRemoteCodexIndexTitles( } } } catch { + throwIfAiVaultScanCancelled(signal) // Codex indexes are opportunistic; raw transcripts remain sufficient. } return titleBySessionId diff --git a/src/main/ai-vault/remote-session-scanner-discovery.ts b/src/main/ai-vault/remote-session-scanner-discovery.ts index 14a47f36559..a309f51077b 100644 --- a/src/main/ai-vault/remote-session-scanner-discovery.ts +++ b/src/main/ai-vault/remote-session-scanner-discovery.ts @@ -6,6 +6,9 @@ import { isMissingRemoteSessionPathError, statRemoteSessionFile } from './remote import { partitionSubagentTranscriptPaths } from './session-scanner-subagent-transcripts' import type { FileWithMtime } from './session-scanner-types' import { errorMessage } from './session-scanner-values' +import { mapRemoteScanBatches } from './remote-session-scan-batching' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' +import { recordRemoteSessionScanIssue } from './remote-session-scan-issues' import type { RemoteScannerContext, RemoteSessionCandidate, @@ -26,15 +29,22 @@ export async function discoverRemoteSourceCandidates(args: { ? partitionSubagentTranscriptPaths(walked) : null const paths = partition ? partition.sessionFilePaths : walked - const files = await mapDiscoveryConcurrently(paths, (path) => - statRemoteSessionFile( - args.context.provider, - path, - args.source.agent, - args.context.executionHostId, - args.issues, - { missingIsExpected: Boolean(args.source.fixedChildFileSegments) } - ) + const files = await mapRemoteScanBatches( + paths, + REMOTE_DISCOVERY_CONCURRENCY, + (path) => + statRemoteSessionFile( + args.context.provider, + path, + args.source.agent, + args.context.executionHostId, + args.issues, + { + missingIsExpected: Boolean(args.source.fixedChildFileSegments), + signal: args.context.signal + } + ), + args.context.signal ) return files .filter((file): file is FileWithMtime => Boolean(file)) @@ -50,10 +60,12 @@ async function listRemoteFixedChildFiles( context: RemoteScannerContext, issues: AiVaultScanIssue[] ): Promise { + throwIfAiVaultScanCancelled(context.signal) let entries try { entries = await context.provider.readDir(source.rootDir) } catch (err) { + throwIfAiVaultScanCancelled(context.signal) recordRemoteDirectoryIssue(source, context.executionHostId, issues, source.rootDir, err) return [] } @@ -73,10 +85,12 @@ async function walkRemoteSessionFiles( dirPath = source.rootDir, depth = 0 ): Promise { + throwIfAiVaultScanCancelled(context.signal) let entries try { entries = await context.provider.readDir(dirPath) } catch (err) { + throwIfAiVaultScanCancelled(context.signal) recordRemoteDirectoryIssue(source, context.executionHostId, issues, dirPath, err) return [] } @@ -84,6 +98,7 @@ async function walkRemoteSessionFiles( const extensions = new Set(source.extensions) const files: string[] = [] for (const entry of entries) { + throwIfAiVaultScanCancelled(context.signal) const fullPath = joinRemotePath(context.hostPlatform, dirPath, entry.name) if ( entry.isDirectory && @@ -112,18 +127,12 @@ function recordRemoteDirectoryIssue( err: unknown ): void { if (!isMissingRemoteSessionPathError(err)) { - issues.push({ executionHostId, agent: source.agent, path, message: errorMessage(err) }) + recordRemoteSessionScanIssue(issues, { + executionHostId, + agent: source.agent, + kind: 'host', + path, + message: errorMessage(err) + }) } } - -async function mapDiscoveryConcurrently( - items: readonly T[], - mapper: (item: T) => Promise -): Promise { - const results: U[] = [] - for (let index = 0; index < items.length; index += REMOTE_DISCOVERY_CONCURRENCY) { - const batch = items.slice(index, index + REMOTE_DISCOVERY_CONCURRENCY) - results.push(...(await Promise.all(batch.map(mapper)))) - } - return results -} diff --git a/src/main/ai-vault/remote-session-scanner-sources.ts b/src/main/ai-vault/remote-session-scanner-sources.ts index f68ba32d6c1..d704c2da671 100644 --- a/src/main/ai-vault/remote-session-scanner-sources.ts +++ b/src/main/ai-vault/remote-session-scanner-sources.ts @@ -9,11 +9,9 @@ import { parseDroidSessionContent } from './session-scanner-droid-parser' import { parseMessageGraphSessionContent } from './session-scanner-graph-parsers' import { parseClaudeSessionContent } from './session-scanner-primary-parsers' import { parseGeminiSessionContent } from './session-scanner-gemini-parsers' -import { - parseCopilotSessionContent, - parseCursorSessionContent, - parseHermesSessionContent -} from './session-scanner-secondary-parsers' +import { parseCopilotSessionContent } from './session-scanner-copilot-parser' +import { parseCursorSessionContent } from './session-scanner-cursor-parser' +import { parseHermesSessionContent } from './session-scanner-hermes-parser' import type { FileWithMtime } from './session-scanner-types' import { normalizeAgentSessionsDir } from './session-scanner-values' import { remoteCodexIndexTitles } from './remote-session-scanner-codex-index' @@ -27,7 +25,9 @@ type RemoteContentParser = ( file: FileWithMtime, content: string, platform: NodeJS.Platform, - options: RemoteParserOptions + options: RemoteParserOptions, + // Line-based parsers iterate cancellably; whole-document parsers ignore it. + signal?: AbortSignal ) => Promise | AiVaultSession | null export function remoteSessionSources( @@ -128,7 +128,8 @@ function remoteAntigravitySource( file, content, context.hostPlatform.os, - parserOptions(context) + parserOptions(context), + context.signal ) return session ? context.antigravityWorkspaceResolver.enrich(session, historyPath) : null } @@ -152,7 +153,9 @@ function source( filePredicate, directoryPredicate, parse: (file, content, context) => - Promise.resolve(parseContent(file, content, context.hostPlatform.os, parserOptions(context))) + Promise.resolve( + parseContent(file, content, context.hostPlatform.os, parserOptions(context), context.signal) + ) } } @@ -195,13 +198,15 @@ function remoteCodexSources( codexHome, executionHostId: context.executionHostId, executionHostPlatform: context.hostPlatform.os, + signal: context.signal, readIndexedTitle: async (sessionId) => ( await remoteCodexIndexTitles({ provider: context.provider, codexHome, hostPlatform, - titleCaches: context.titleCaches + titleCaches: context.titleCaches, + signal: context.signal }) ).get(sessionId) ?? null }) @@ -235,27 +240,30 @@ function piParser( file: FileWithMtime, content: string, platform: NodeJS.Platform, - options: RemoteParserOptions + options: RemoteParserOptions, + signal?: AbortSignal ): Promise { - return parseMessageGraphSessionContent('pi', file, content, platform, options) + return parseMessageGraphSessionContent('pi', file, content, platform, options, signal) } function ompParser( file: FileWithMtime, content: string, platform: NodeJS.Platform, - options: RemoteParserOptions + options: RemoteParserOptions, + signal?: AbortSignal ): Promise { - return parseMessageGraphSessionContent('omp', file, content, platform, options) + return parseMessageGraphSessionContent('omp', file, content, platform, options, signal) } function openClawParser( file: FileWithMtime, content: string, platform: NodeJS.Platform, - options: RemoteParserOptions + options: RemoteParserOptions, + signal?: AbortSignal ): Promise { - return parseMessageGraphSessionContent('openclaw', file, content, platform, options) + return parseMessageGraphSessionContent('openclaw', file, content, platform, options, signal) } function remotePathSegments(path: string): string[] { diff --git a/src/main/ai-vault/remote-session-scanner-types.ts b/src/main/ai-vault/remote-session-scanner-types.ts index 77806f38be6..58fb255e3cc 100644 --- a/src/main/ai-vault/remote-session-scanner-types.ts +++ b/src/main/ai-vault/remote-session-scanner-types.ts @@ -6,13 +6,19 @@ import type { FileWithMtime } from './session-scanner-types' import type { AntigravityWorkspaceResolver } from './session-scanner-antigravity-history' export type RemoteScannerContext = { - provider: IFilesystemProvider + provider: RemoteSessionFilesystemProvider executionHostId: ExecutionHostId hostPlatform: RemoteHostPlatform + signal?: AbortSignal titleCaches: Map>> antigravityWorkspaceResolver: AntigravityWorkspaceResolver } +export type RemoteSessionFilesystemProvider = Pick< + IFilesystemProvider, + 'readDir' | 'readFile' | 'stat' +> + export type RemoteParserOptions = { executionHostId: ExecutionHostId executionHostPlatform: NodeJS.Platform diff --git a/src/main/ai-vault/remote-session-scanner.test.ts b/src/main/ai-vault/remote-session-scanner.test.ts index 4ba3bd4d647..a4705ee1bfb 100644 --- a/src/main/ai-vault/remote-session-scanner.test.ts +++ b/src/main/ai-vault/remote-session-scanner.test.ts @@ -153,7 +153,9 @@ describe('scanRemoteAiVaultSessions', () => { provider, executionHostId: 'ssh:dev-box', remoteHome: '/home/ada', - hostPlatform: getRemoteHostPlatform('linux-x64') + hostPlatform: getRemoteHostPlatform('linux-x64'), + limit: 1, + unlimited: true }) expect(result.issues).toEqual([]) @@ -404,11 +406,13 @@ describe('scanRemoteAiVaultSessions', () => { expect.arrayContaining([ expect.objectContaining({ agent: 'antigravity', + kind: 'host', path: brainDir, message: expect.stringContaining('EACCES') }), expect.objectContaining({ agent: 'claude', + kind: 'host', path: claudeProjectDir, message: expect.stringContaining('ECONNRESET') }) @@ -706,6 +710,93 @@ describe('scanRemoteAiVaultSessions', () => { 'scoped-session' ]) }) + + it('keeps looking past newer out-of-scope candidates during scoped backfill', async () => { + const provider = new MemoryRemoteProvider() + for (const [sessionId, mtimeMs, hour] of [ + ['other-newest', 50, '05'], + ['other-newer', 40, '04'] + ] as const) { + provider.addFile( + `/home/ada/.codex/sessions/${sessionId}.jsonl`, + codexTranscript({ + sessionId, + title: sessionId, + cwd: '/home/ada/other', + timestamp: `2026-07-04T${hour}:00:00.000Z` + }), + mtimeMs + ) + } + provider.addFile( + '/home/ada/.codex/sessions/scoped.jsonl', + codexTranscript({ + sessionId: 'scoped-session', + title: 'Scoped workspace', + cwd: '/home/ada/repo', + timestamp: '2026-07-04T01:00:00.000Z' + }), + 10 + ) + + const result = await scanRemoteAiVaultSessions({ + provider, + executionHostId: 'ssh:dev-box', + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + limit: 1, + scopePaths: ['/home/ada/repo'] + }) + + expect(result.issues).toEqual([]) + expect(result.sessions.map((session) => session.sessionId)).toEqual([ + 'other-newest', + 'scoped-session' + ]) + }) + + it('caps scoped backfill at the requested limit', async () => { + const provider = new MemoryRemoteProvider() + provider.addFile( + '/home/ada/.codex/sessions/other.jsonl', + codexTranscript({ + sessionId: 'other-session', + title: 'Other workspace', + cwd: '/home/ada/other', + timestamp: '2026-07-04T05:00:00.000Z' + }), + 50 + ) + for (const [sessionId, mtimeMs] of [ + ['newer-scoped', 30], + ['older-scoped', 20] + ] as const) { + provider.addFile( + `/home/ada/.codex/sessions/${sessionId}.jsonl`, + codexTranscript({ + sessionId, + title: sessionId, + cwd: '/home/ada/repo', + timestamp: `2026-07-04T0${mtimeMs / 10}:00:00.000Z` + }), + mtimeMs + ) + } + + const result = await scanRemoteAiVaultSessions({ + provider, + executionHostId: 'ssh:dev-box', + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + limit: 1, + scopePaths: ['/home/ada/repo'] + }) + + expect(result.sessions.map((session) => session.sessionId)).toEqual([ + 'other-session', + 'newer-scoped' + ]) + }) }) function codexTranscript(args: { diff --git a/src/main/ai-vault/remote-session-scanner.ts b/src/main/ai-vault/remote-session-scanner.ts index 0ad894214e1..2523cd22a43 100644 --- a/src/main/ai-vault/remote-session-scanner.ts +++ b/src/main/ai-vault/remote-session-scanner.ts @@ -5,7 +5,7 @@ import type { } from '../../shared/ai-vault-types' import { isPathInsideOrEqual } from '../../shared/cross-platform-path' import type { ExecutionHostId } from '../../shared/execution-host' -import type { IFilesystemProvider } from '../providers/types' +import { setImmediate as yieldToEventLoop } from 'node:timers/promises' import type { RemoteHostPlatform } from '../ssh/ssh-remote-platform' import { codexRolloutHardlinkIdentity, @@ -14,44 +14,71 @@ import { } from './codex-session-root-dedup' import { discoverRemoteSourceCandidates } from './remote-session-scanner-discovery' import { remoteSessionSources } from './remote-session-scanner-sources' -import type { RemoteScannerContext, RemoteSessionCandidate } from './remote-session-scanner-types' +import type { + RemoteScannerContext, + RemoteSessionCandidate, + RemoteSessionFilesystemProvider +} from './remote-session-scanner-types' import { sessionSortTime } from './session-scanner-accumulator' import { createAntigravityWorkspaceResolver } from './session-scanner-antigravity-history' import { errorMessage } from './session-scanner-values' +import { mapRemoteScanBatches } from './remote-session-scan-batching' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' +import { recordRemoteSessionScanIssue } from './remote-session-scan-issues' +import { limitRemoteScanFilesystemConcurrency } from './remote-session-scan-concurrency' +import { aiVaultScanLimit } from '../../shared/ai-vault-session-depth' -const DEFAULT_REMOTE_SCAN_LIMIT = 1000 const REMOTE_SCAN_CONCURRENCY = 8 -const REMOTE_SCOPE_PARSE_LIMIT = 2000 +const REMOTE_PARSE_CANDIDATE_MULTIPLIER = 2 +// Remote scope membership is only known after a transcript is read, so the scope +// backfill carries its own ceiling on remote reads instead of borrowing the +// recency cap — under the cap, newer out-of-scope files ate the scope budget and +// silently dropped older in-scope sessions the scope contract guarantees. +const REMOTE_SCOPE_PARSE_CANDIDATE_LIMIT = 1000 export async function scanRemoteAiVaultSessions(args: { - provider: IFilesystemProvider + provider: RemoteSessionFilesystemProvider executionHostId: ExecutionHostId remoteHome: string hostPlatform: RemoteHostPlatform limit?: number + unlimited?: boolean scopePaths?: readonly string[] + signal?: AbortSignal }): Promise { - const limit = args.limit && args.limit > 0 ? Math.floor(args.limit) : DEFAULT_REMOTE_SCAN_LIMIT + throwIfAiVaultScanCancelled(args.signal) + const limit = aiVaultScanLimit(args) const issues: AiVaultScanIssue[] = [] + // One ceiling for the whole scan: discovery walks, stats and transcript reads + // all queue behind it instead of multiplying into a nested fan-out. + const provider = limitRemoteScanFilesystemConcurrency(args.provider) const context: RemoteScannerContext = { - provider: args.provider, + provider, executionHostId: args.executionHostId, hostPlatform: args.hostPlatform, + signal: args.signal, titleCaches: new Map(), antigravityWorkspaceResolver: createAntigravityWorkspaceResolver(async (historyPath) => { try { - const read = await args.provider.readFile(historyPath) + throwIfAiVaultScanCancelled(args.signal) + const read = await provider.readFile(historyPath) + throwIfAiVaultScanCancelled(args.signal) return read.isBinary ? null : read.content - } catch { + } catch (error) { + if (error instanceof Error && error.name === 'AbortError') { + throw error + } return null } }) } const candidates = dedupeCodexRolloutFileAliases( ( - await mapRemoteScanConcurrently( + await mapRemoteScanBatches( remoteSessionSources(args.remoteHome, args.hostPlatform), - (source) => discoverRemoteSourceCandidates({ source, context, issues }) + REMOTE_SCAN_CONCURRENCY, + (source) => discoverRemoteSourceCandidates({ source, context, issues }), + args.signal ) ) .flat() @@ -64,7 +91,12 @@ export async function scanRemoteAiVaultSessions(args: { } ) - const parsed = await parseRemoteSessionCandidates({ candidates, context, issues, limit }) + const parsed = await parseRemoteSessionCandidates({ + candidates: candidates.slice(0, limit * REMOTE_PARSE_CANDIDATE_MULTIPLIER), + context, + issues, + limit + }) const parsedSessions = dedupeCodexSessionsBySessionId(parsed.sessions) const cappedSessions = parsedSessions .sort((left, right) => sessionSortTime(right) - sessionSortTime(left)) @@ -78,12 +110,15 @@ export async function scanRemoteAiVaultSessions(args: { context, issues, scopePaths, + limit, alreadyParsedFilePaths: parsed.parsedFilePaths }) const scopeSessions = dedupeCodexSessionsBySessionId([ ...parsedScopeSessions, ...extraScopeSessions ]) + .sort((left, right) => sessionSortTime(right) - sessionSortTime(left)) + .slice(0, limit) return { sessions: mergeRemoteSessions(cappedSessions, scopeSessions), @@ -107,19 +142,27 @@ async function parseRemoteSessionCandidates(args: { break } - const batch = args.candidates.slice(index, index + REMOTE_SCAN_CONCURRENCY) + const remaining = args.candidates.length - index + const needed = Math.max(args.limit - sessions.length, 1) + const batchSize = Math.min(REMOTE_SCAN_CONCURRENCY, needed, remaining) + const batch = args.candidates.slice(index, index + batchSize) for (const candidate of batch) { parsedFilePaths.add(candidate.file.path) } + throwIfAiVaultScanCancelled(args.context.signal) const results = await Promise.all( batch.map((candidate) => parseRemoteSessionCandidate(candidate, args.context, args.issues)) ) sessions.push(...results.filter(isAiVaultSession)) const uniqueSessions = dedupeCodexSessionsBySessionId(sessions) sessions.splice(0, sessions.length, ...uniqueSessions) - index += batch.length + index += batchSize + await yieldToEventLoop() } + // The loop can terminate on the yield after its final batch, so re-check + // rather than letting a cancelled scan return a partial parse as a success. + throwIfAiVaultScanCancelled(args.context.signal) return { sessions, parsedFilePaths } } @@ -128,21 +171,29 @@ async function scanRemoteInScopeSessions(args: { context: RemoteScannerContext issues: AiVaultScanIssue[] scopePaths: readonly string[] + limit: number alreadyParsedFilePaths: ReadonlySet }): Promise { if (args.scopePaths.length === 0) { return [] } - const candidates = args.candidates - .filter((candidate) => !args.alreadyParsedFilePaths.has(candidate.file.path)) - .slice(0, REMOTE_SCOPE_PARSE_LIMIT) + const candidates = args.candidates.filter( + (candidate) => !args.alreadyParsedFilePaths.has(candidate.file.path) + ) + const bound = Math.min(candidates.length, REMOTE_SCOPE_PARSE_CANDIDATE_LIMIT) const sessions: AiVaultSession[] = [] + let index = 0 - for (let index = 0; index < candidates.length; index += REMOTE_SCAN_CONCURRENCY) { - const batch = candidates.slice(index, index + REMOTE_SCAN_CONCURRENCY) - const results = await Promise.all( - batch.map((candidate) => parseRemoteSessionCandidate(candidate, args.context, args.issues)) + // Keep reading newest-first until the scope has its requested number of + // sessions; out-of-scope candidates no longer end the search. + while (index < bound && sessions.length < args.limit) { + const batchEnd = Math.min(index + REMOTE_SCAN_CONCURRENCY, bound) + const results = await mapRemoteScanBatches( + candidates.slice(index, batchEnd), + REMOTE_SCAN_CONCURRENCY, + (candidate) => parseRemoteSessionCandidate(candidate, args.context, args.issues), + args.context.signal ) sessions.push( ...results.filter( @@ -150,6 +201,17 @@ async function scanRemoteInScopeSessions(args: { isAiVaultSession(session) && isRemoteSessionInScope(session, args.scopePaths) ) ) + index = batchEnd + } + + if (index < candidates.length && sessions.length < args.limit) { + recordRemoteSessionScanIssue(args.issues, { + executionHostId: args.context.executionHostId, + agent: 'codex', + kind: 'scope', + path: 'Agent Session History scan', + message: `Only the ${REMOTE_SCOPE_PARSE_CANDIDATE_LIMIT} most recent remote transcripts were checked for this workspace; older sessions may be missing.` + }) } return sessions @@ -161,11 +223,14 @@ async function parseRemoteSessionCandidate( issues: AiVaultScanIssue[] ): Promise { try { + throwIfAiVaultScanCancelled(context.signal) const read = await context.provider.readFile(candidate.file.path) + throwIfAiVaultScanCancelled(context.signal) if (read.isBinary) { return null } const session = await candidate.source.parse(candidate.file, read.content, context) + throwIfAiVaultScanCancelled(context.signal) // Mirror the local rule: every session carries its sibling subagent // transcript count (row badge; recoverable signal at zero turns). The // walk listing supplies it — the parser can't readdir a remote disk. @@ -175,7 +240,8 @@ async function parseRemoteSessionCandidate( } return session } catch (err) { - issues.push({ + throwIfAiVaultScanCancelled(context.signal) + recordRemoteSessionScanIssue(issues, { executionHostId: context.executionHostId, agent: candidate.source.agent, path: candidate.file.path, @@ -232,15 +298,3 @@ function canStopParsingRemoteSessions( function isAiVaultSession(session: AiVaultSession | null): session is AiVaultSession { return Boolean(session) } - -async function mapRemoteScanConcurrently( - items: readonly T[], - mapper: (item: T) => Promise -): Promise { - const results: U[] = [] - for (let index = 0; index < items.length; index += REMOTE_SCAN_CONCURRENCY) { - const batch = items.slice(index, index + REMOTE_SCAN_CONCURRENCY) - results.push(...(await Promise.all(batch.map(mapper)))) - } - return results -} diff --git a/src/main/ai-vault/runtime-session-scanner.test.ts b/src/main/ai-vault/runtime-session-scanner.test.ts index 1c77130c528..922a6af96d7 100644 --- a/src/main/ai-vault/runtime-session-scanner.test.ts +++ b/src/main/ai-vault/runtime-session-scanner.test.ts @@ -68,6 +68,21 @@ describe('runtime AI Vault session scanner', () => { ) }) + it('surfaces project scope truncation from the runtime transport bound', async () => { + const scopePaths = Array.from({ length: 80 }, (_, index) => `/srv/repo-${index}`) + + const scanResult = await scanRuntimeAiVaultSessions('/user-data', 'env-1', { + scopePaths + }) + + expect(scanResult.issues).toContainEqual( + expect.objectContaining({ + kind: 'scope', + message: expect.stringContaining('first 64 project paths') + }) + ) + }) + it('stamps sessions and issues returned for a different execution host', async () => { mocks.callRuntimeEnvironment.mockResolvedValueOnce({ ok: true, diff --git a/src/main/ai-vault/runtime-session-scanner.ts b/src/main/ai-vault/runtime-session-scanner.ts index 014a511cea2..1c1c248ee31 100644 --- a/src/main/ai-vault/runtime-session-scanner.ts +++ b/src/main/ai-vault/runtime-session-scanner.ts @@ -1,18 +1,18 @@ import { z } from 'zod' import { - AI_VAULT_AGENTS, AI_VAULT_SCOPE_PATHS_MAX_COUNT, type AiVaultListArgs, type AiVaultListResult, type AiVaultSession } from '../../shared/ai-vault-types' -import { normalizeExecutionHostId, toRuntimeExecutionHostId } from '../../shared/execution-host' +import { toRuntimeExecutionHostId } from '../../shared/execution-host' import { listEnvironments } from '../../shared/runtime-environment-store' import { callRuntimeEnvironment } from '../ipc/runtime-environment-transport-routing' import type { AiVaultPrepareSessionResumeArgs, AiVaultPrepareSessionResumeResult } from '../../shared/ai-vault-resume-preparation' +import { parseAiVaultListResult } from './session-list-result-validation' export type RuntimeAiVaultHostInfo = { environmentId: string @@ -23,89 +23,6 @@ export type RuntimeAiVaultScanOptions = { timeoutMs?: number } -const nodePlatformSchema = z.enum([ - 'aix', - 'android', - 'darwin', - 'freebsd', - 'haiku', - 'linux', - 'openbsd', - 'sunos', - 'win32', - 'cygwin', - 'netbsd' -] satisfies NodeJS.Platform[]) - -const aiVaultSessionPreviewMessageSchema = z.object({ - role: z.enum(['user', 'assistant', 'system', 'tool', 'unknown']), - text: z.string(), - timestamp: z.string().nullable() -}) - -const executionHostIdSchema = z.string().transform((value, ctx) => { - const normalized = normalizeExecutionHostId(value) - if (normalized) { - return normalized - } - ctx.addIssue({ - code: 'custom', - message: 'Invalid execution host id' - }) - return z.NEVER -}) - -const aiVaultListResultSchema = z.object({ - sessions: z.array( - z.object({ - id: z.string(), - executionHostId: executionHostIdSchema, - executionHostPlatform: nodePlatformSchema.nullable().optional(), - agent: z.enum(AI_VAULT_AGENTS), - sessionId: z.string(), - title: z.string(), - cwd: z.string().nullable(), - branch: z.string().nullable(), - model: z.string().nullable(), - filePath: z.string(), - codexHome: z.string().nullable(), - createdAt: z.string().nullable(), - updatedAt: z.string().nullable(), - modifiedAt: z.string(), - messageCount: z.number(), - totalTokens: z.number(), - previewMessages: z.array(aiVaultSessionPreviewMessageSchema), - // Optional keeps paired hosts on older builds compatible. - firstUserPrompt: z.string().nullable().optional(), - lastUserPrompt: z.string().nullable().optional(), - // Default keeps remote hosts running an older build (no recoverable-signal - // fields) parseable; they simply report no recoverable-empty sessions. - queuedMessageCount: z.number().default(0), - subagentTranscriptCount: z.number().default(0), - resumeCommand: z.string(), - // The default keeps remote hosts running an older build (no subagent - // field) parseable; scanned top-level sessions carry null anyway. - subagent: z - .object({ - parentSessionId: z.string(), - agentType: z.string().nullable(), - status: z.enum(['running', 'completed', 'failed', 'stopped']).nullable() - }) - .nullable() - .default(null) - }) - ), - issues: z.array( - z.object({ - executionHostId: executionHostIdSchema.optional(), - agent: z.enum(AI_VAULT_AGENTS), - path: z.string(), - message: z.string() - }) - ), - scannedAt: z.string() -}) - // Why: zod strips unknown keys, so the repin home must be declared or the // parent would silently drop it and resume under the wrong account's home. const aiVaultPrepareSessionResumeResultSchema = z.object({ @@ -135,6 +52,7 @@ export async function scanRuntimeAiVaultSessions( 'aiVault.listSessions', { limit: args.limit, + unlimited: args.unlimited, force: args.force, // Why: cap here so the set of scanned paths is explicit on this side — // the RPC schema CLAMPS to the same bound anyway (older hosts had no @@ -146,17 +64,36 @@ export async function scanRuntimeAiVaultSessions( options.timeoutMs ) if (response.ok === true) { - const parsed = aiVaultListResultSchema.safeParse(response.result) - if (parsed.success) { - return withRuntimeExecutionHost(parsed.data, executionHostId) + try { + const result = withRuntimeExecutionHost( + parseAiVaultListResult(response.result), + executionHostId + ) + if (!args.scopePaths || args.scopePaths.length <= AI_VAULT_SCOPE_PATHS_MAX_COUNT) { + return result + } + return { + ...result, + issues: [ + ...result.issues, + { + executionHostId, + agent: 'codex', + kind: 'scope', + path: environmentId, + message: `Only the first ${AI_VAULT_SCOPE_PATHS_MAX_COUNT} project paths were scanned.` + } + ] + } + } catch (error) { + return runtimeScanIssueResult({ + executionHostId, + environmentId, + message: `Invalid aiVault.listSessions response: ${ + error instanceof Error ? error.message : 'unexpected result shape' + }` + }) } - return runtimeScanIssueResult({ - executionHostId, - environmentId, - message: `Invalid aiVault.listSessions response: ${ - parsed.error.issues[0]?.message ?? 'unexpected result shape' - }` - }) } return runtimeScanIssueResult({ executionHostId, @@ -223,6 +160,7 @@ function runtimeScanIssueResult(args: { { executionHostId: args.executionHostId, agent: 'codex', + kind: 'host', path: args.environmentId, message: args.message } diff --git a/src/main/ai-vault/session-first-user-prompt-read.test.ts b/src/main/ai-vault/session-first-user-prompt-read.test.ts index 5213c49ab3e..b6b8ee4eee5 100644 --- a/src/main/ai-vault/session-first-user-prompt-read.test.ts +++ b/src/main/ai-vault/session-first-user-prompt-read.test.ts @@ -134,4 +134,30 @@ describe('readAiVaultFirstUserPrompt', () => { readAiVaultFirstUserPrompt({ agent: 'grok', filePath: summaryPath }) ).resolves.toEqual({ prompt: null }) }) + + // The web preload fallback and the renderer's canLoadFullFirstPrompt guard both + // rely on remote hosts never reading a local transcript body. + it('returns null for a non-local execution host', async () => { + const root = await mkdtemp(join(tmpdir(), 'orca-first-prompt-remote-')) + tempRoots.push(root) + const filePath = join(root, 'session.jsonl') + await writeFile( + filePath, + JSON.stringify({ + type: 'user', + sessionId: 'remote-session', + timestamp: '2026-05-01T10:00:00.000Z', + cwd: '/repo/app', + message: { role: 'user', content: 'Should not be returned' } + }) + ) + + await expect( + readAiVaultFirstUserPrompt({ + agent: 'claude', + filePath, + executionHostId: 'ssh:build-box' + }) + ).resolves.toEqual({ prompt: null }) + }) }) diff --git a/src/main/ai-vault/session-first-user-prompt-read.ts b/src/main/ai-vault/session-first-user-prompt-read.ts index 2023303e4e6..b656494f61c 100644 --- a/src/main/ai-vault/session-first-user-prompt-read.ts +++ b/src/main/ai-vault/session-first-user-prompt-read.ts @@ -104,7 +104,7 @@ async function parseSessionForFullFirstUserPrompt(args: { } } - const file = await fileWithMtimeForPath(args.filePath) + const file = await fileWithMtimeForPath(args.filePath, args.agent) if (!file) { return null } @@ -119,10 +119,14 @@ async function parseSessionForFullFirstUserPrompt(args: { ) } -async function fileWithMtimeForPath(filePath: string): Promise { +async function fileWithMtimeForPath( + filePath: string, + agent: AiVaultAgent +): Promise { // OpenCode SQLite candidates use a synthetic `dbPath#sessionId` path that is // not a real filesystem object; parsers that need it accept the path as-is. - if (filePath.includes('#')) { + // `#` is legal in real filenames, so gate on the agent and the synthetic shape. + if (agent === 'opencode' && splitOpenCodeSqliteCandidate(filePath)) { return { path: filePath, mtimeMs: 0, diff --git a/src/main/ai-vault/session-list-result-validation.test.ts b/src/main/ai-vault/session-list-result-validation.test.ts new file mode 100644 index 00000000000..9cdc22a8fb4 --- /dev/null +++ b/src/main/ai-vault/session-list-result-validation.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it } from 'vitest' +import { parseAiVaultListResult } from './session-list-result-validation' + +describe('parseAiVaultListResult', () => { + it('keeps valid sessions when another wire entry is malformed', () => { + const parsed = parseAiVaultListResult({ + sessions: [validSession(), { id: 42 }], + issues: [], + scannedAt: '2026-07-27T00:00:00.000Z' + }) + + expect(parsed.sessions).toHaveLength(1) + expect(parsed.sessions[0]?.sessionId).toBe('session-1') + expect(parsed.issues).toContainEqual( + expect.objectContaining({ + path: 'aiVault.listSessions', + message: expect.stringContaining('Skipped 1 invalid') + }) + ) + }) + + it('preserves the optional session fields the panel renders', () => { + const parsed = parseAiVaultListResult({ + sessions: [ + { + ...validSession(), + previewMessagesTruncated: true, + firstUserPrompt: 'first', + lastUserPrompt: 'last' + } + ], + issues: [], + scannedAt: '2026-07-27T00:00:00.000Z' + }) + + expect(parsed.sessions[0]).toMatchObject({ + previewMessagesTruncated: true, + firstUserPrompt: 'first', + lastUserPrompt: 'last' + }) + }) + + it('rejects a malformed result envelope', () => { + expect(() => parseAiVaultListResult({ sessions: [] })).toThrow() + }) + + it('rejects a nonempty sessions array when every row is invalid', () => { + expect(() => + parseAiVaultListResult({ + sessions: [{ id: 42 }, null], + issues: [], + scannedAt: '2026-07-27T00:00:00.000Z' + }) + ).toThrow('all supplied Agent Session History sessions were invalid') + }) +}) + +function validSession(): Record { + return { + id: 'local:codex:session-1:/tmp/session-1.jsonl', + executionHostId: 'local', + executionHostPlatform: 'linux', + agent: 'codex', + sessionId: 'session-1', + title: 'Session one', + cwd: '/repo', + branch: null, + model: null, + filePath: '/tmp/session-1.jsonl', + codexHome: null, + createdAt: null, + updatedAt: null, + modifiedAt: '2026-07-27T00:00:00.000Z', + messageCount: 1, + totalTokens: 0, + previewMessages: [], + queuedMessageCount: 0, + subagentTranscriptCount: 0, + resumeCommand: 'codex resume session-1', + subagent: null + } +} diff --git a/src/main/ai-vault/session-list-result-validation.ts b/src/main/ai-vault/session-list-result-validation.ts new file mode 100644 index 00000000000..6d69a06af45 --- /dev/null +++ b/src/main/ai-vault/session-list-result-validation.ts @@ -0,0 +1,108 @@ +import { z } from 'zod' +import { AI_VAULT_AGENTS, type AiVaultListResult } from '../../shared/ai-vault-types' +import { normalizeExecutionHostId } from '../../shared/execution-host' + +const nodePlatformSchema = z.enum([ + 'aix', + 'android', + 'darwin', + 'freebsd', + 'haiku', + 'linux', + 'openbsd', + 'sunos', + 'win32', + 'cygwin', + 'netbsd' +] satisfies NodeJS.Platform[]) + +const executionHostIdSchema = z.string().transform((value, ctx) => { + const normalized = normalizeExecutionHostId(value) + if (normalized) { + return normalized + } + ctx.addIssue({ code: 'custom', message: 'Invalid execution host id' }) + return z.NEVER +}) + +const sessionPreviewMessageSchema = z.object({ + role: z.enum(['user', 'assistant', 'system', 'tool', 'unknown']), + text: z.string(), + timestamp: z.string().nullable() +}) + +const aiVaultSessionSchema = z.object({ + id: z.string(), + executionHostId: executionHostIdSchema, + executionHostPlatform: nodePlatformSchema.nullable().optional(), + agent: z.enum(AI_VAULT_AGENTS), + sessionId: z.string(), + title: z.string(), + cwd: z.string().nullable(), + branch: z.string().nullable(), + model: z.string().nullable(), + filePath: z.string(), + codexHome: z.string().nullable(), + createdAt: z.string().nullable(), + updatedAt: z.string().nullable(), + modifiedAt: z.string(), + messageCount: z.number(), + totalTokens: z.number(), + previewMessages: z.array(sessionPreviewMessageSchema), + previewMessagesTruncated: z.boolean().optional(), + firstUserPrompt: z.string().nullable().optional(), + lastUserPrompt: z.string().nullable().optional(), + queuedMessageCount: z.number().default(0), + subagentTranscriptCount: z.number().default(0), + resumeCommand: z.string(), + subagent: z + .object({ + parentSessionId: z.string(), + agentType: z.string().nullable(), + status: z.enum(['running', 'completed', 'failed', 'stopped']).nullable() + }) + .nullable() + .default(null) +}) + +const aiVaultScanIssueSchema = z.object({ + executionHostId: executionHostIdSchema.optional(), + agent: z.enum(AI_VAULT_AGENTS), + kind: z.enum(['host', 'scope', 'notice']).optional(), + path: z.string(), + message: z.string() +}) + +const aiVaultListResultEnvelopeSchema = z.object({ + sessions: z.array(z.unknown()), + issues: z.array(z.unknown()), + scannedAt: z.string() +}) + +export function parseAiVaultListResult(value: unknown): AiVaultListResult { + const envelope = aiVaultListResultEnvelopeSchema.safeParse(value) + if (!envelope.success) { + throw new Error(envelope.error.issues[0]?.message ?? 'unexpected result shape') + } + const sessions = envelope.data.sessions.flatMap((session) => { + const parsed = aiVaultSessionSchema.safeParse(session) + return parsed.success ? [parsed.data] : [] + }) + if (envelope.data.sessions.length > 0 && sessions.length === 0) { + throw new Error('all supplied Agent Session History sessions were invalid') + } + const issues = envelope.data.issues.flatMap((issue) => { + const parsed = aiVaultScanIssueSchema.safeParse(issue) + return parsed.success ? [parsed.data] : [] + }) + const invalidCount = + envelope.data.sessions.length - sessions.length + (envelope.data.issues.length - issues.length) + if (invalidCount > 0) { + issues.push({ + agent: 'codex', + path: 'aiVault.listSessions', + message: `Skipped ${invalidCount} invalid Agent Session History result ${invalidCount === 1 ? 'entry' : 'entries'}.` + }) + } + return { sessions, issues, scannedAt: envelope.data.scannedAt } +} diff --git a/src/main/ai-vault/session-list-results.test.ts b/src/main/ai-vault/session-list-results.test.ts new file mode 100644 index 00000000000..ef0c578f662 --- /dev/null +++ b/src/main/ai-vault/session-list-results.test.ts @@ -0,0 +1,97 @@ +import { describe, expect, it } from 'vitest' +import type { + AiVaultListResult, + AiVaultScanIssue, + AiVaultSession +} from '../../shared/ai-vault-types' +import { mergeAiVaultListResults } from './session-list-results' + +function listResult(issues: AiVaultScanIssue[]): AiVaultListResult { + return { sessions: [], issues, scannedAt: '2026-08-02T00:00:00.000Z' } +} + +function session(index: number): AiVaultSession { + const id = `session-${index}` + const timestamp = new Date(Date.UTC(2026, 7, 2, 0, 0, index)).toISOString() + return { + id, + executionHostId: 'local', + agent: 'codex', + sessionId: id, + title: id, + cwd: '/repo', + branch: null, + model: null, + filePath: `/sessions/${id}.jsonl`, + codexHome: null, + createdAt: timestamp, + updatedAt: timestamp, + modifiedAt: timestamp, + messageCount: 1, + totalTokens: 0, + previewMessages: [], + queuedMessageCount: 0, + subagentTranscriptCount: 0, + resumeCommand: id, + subagent: null + } +} + +const SCOPE_TRUNCATION: AiVaultScanIssue = { + executionHostId: 'ssh:dev-box', + agent: 'codex', + kind: 'scope', + path: '/home/ada', + message: 'Only the first 64 project paths were scanned.' +} + +describe('mergeAiVaultListResults', () => { + it('does not cap an Unlimited all-host merge', () => { + const sessions = Array.from({ length: 1001 }, (_, index) => session(index)) + const merged = mergeAiVaultListResults([{ ...listResult([]), sessions }], undefined, true) + + expect(merged.sessions).toHaveLength(1001) + }) + + it('keeps a per-host scope truncation notice when merging all-host results', () => { + const merged = mergeAiVaultListResults( + [listResult([]), listResult([SCOPE_TRUNCATION])], + undefined + ) + + expect(merged.issues).toEqual([SCOPE_TRUNCATION]) + }) + + it('keeps one scope notice per host rather than collapsing them', () => { + const otherHost: AiVaultScanIssue = { ...SCOPE_TRUNCATION, executionHostId: 'ssh:build-box' } + + const merged = mergeAiVaultListResults( + [listResult([SCOPE_TRUNCATION]), listResult([otherHost])], + undefined + ) + + expect(merged.issues.map((issue) => issue.executionHostId)).toEqual([ + 'ssh:dev-box', + 'ssh:build-box' + ]) + }) + + it('keeps a scope notice alongside a failing host so one bad host is not the whole story', () => { + const hostDown: AiVaultScanIssue = { + executionHostId: 'ssh:build-box', + agent: 'codex', + kind: 'host', + path: 'build-box', + message: 'Remote connection dropped.' + } + + const merged = mergeAiVaultListResults( + [listResult([SCOPE_TRUNCATION]), listResult([hostDown])], + undefined + ) + + expect(merged.issues).toEqual([SCOPE_TRUNCATION, hostDown]) + // Kinded issues render as their own banner rows, never as skipped transcripts. + expect(merged.issues.filter((issue) => !issue.kind)).toEqual([]) + }) +}) diff --git a/src/main/ai-vault/session-list-results.ts b/src/main/ai-vault/session-list-results.ts index 06f8df9c39a..54e2fff7d5a 100644 --- a/src/main/ai-vault/session-list-results.ts +++ b/src/main/ai-vault/session-list-results.ts @@ -5,6 +5,7 @@ import type { } from '../../shared/ai-vault-types' import type { ExecutionHostId } from '../../shared/execution-host' import { sessionSortTime } from './session-scanner-accumulator' +import { aiVaultScanLimit } from '../../shared/ai-vault-session-depth' export function aiVaultScanIssueResult(args: { executionHostId?: ExecutionHostId @@ -17,6 +18,7 @@ export function aiVaultScanIssueResult(args: { { ...(args.executionHostId ? { executionHostId: args.executionHostId } : {}), agent: 'codex', + kind: 'host', path: args.path, message: args.message } @@ -25,6 +27,12 @@ export function aiVaultScanIssueResult(args: { } } +// A superseded scan has no findings to report; the flag tells the renderer to +// keep the list it already has rather than paint this empty body. +export function cancelledAiVaultListResult(): AiVaultListResult { + return { sessions: [], issues: [], scannedAt: new Date().toISOString(), cancelled: true } +} + // Why: the serving-side scan is host-local and cached once for every caller // (desktop parent, web, mobile), so callers that address this host by a runtime // id get the cached result restamped on the way out instead of a per-host scan. @@ -50,9 +58,10 @@ export function restampAiVaultListResult( export function mergeAiVaultListResults( results: readonly AiVaultListResult[], - rawLimit: number | undefined + rawLimit: number | undefined, + unlimited = false ): AiVaultListResult { - const limit = rawLimit && rawLimit > 0 ? Math.floor(rawLimit) : 1000 + const limit = aiVaultScanLimit({ limit: rawLimit, unlimited }) const byId = new Map() const issues: AiVaultScanIssue[] = [] for (const result of results) { diff --git a/src/main/ai-vault/session-scanner-accumulator.ts b/src/main/ai-vault/session-scanner-accumulator.ts index 97651c57109..caf08f4259d 100644 --- a/src/main/ai-vault/session-scanner-accumulator.ts +++ b/src/main/ai-vault/session-scanner-accumulator.ts @@ -1,11 +1,11 @@ import { basename, extname } from 'node:path' import { aiVaultAgentLabel, - buildAiVaultResumeCommand, type AiVaultAgent, type AiVaultSession, type AiVaultSessionPreviewMessage } from '../../shared/ai-vault-types' +import { buildAiVaultResumeCommand } from '../../shared/ai-vault-resume-command' import { LOCAL_EXECUTION_HOST_ID, type ExecutionHostId } from '../../shared/execution-host' import type { FileWithMtime, @@ -46,6 +46,7 @@ export function createAccumulator(args: { messageCount: 0, totalTokens: 0, previewMessages: [], + previewMessagesTruncated: false, firstUserPrompt: null, lastUserPrompt: null, queuedMessageCount: 0, @@ -119,6 +120,7 @@ export function finalizeSession( messageCount: accumulator.messageCount, totalTokens: accumulator.totalTokens, previewMessages: accumulator.previewMessages, + ...(accumulator.previewMessagesTruncated ? { previewMessagesTruncated: true } : {}), ...(accumulator.firstUserPrompt ? { firstUserPrompt: accumulator.firstUserPrompt } : {}), ...(accumulator.lastUserPrompt ? { lastUserPrompt: accumulator.lastUserPrompt } : {}), queuedMessageCount: accumulator.queuedMessageCount, @@ -161,6 +163,14 @@ export function addPreviewMessage( seedFirstUserPrompt?: boolean } ): void { + // Seeded before the preview-empty return so the copy body never depends on + // preview-only normalization rules. + seedFullFirstUserPrompt( + accumulator, + args.role, + () => (args.text ? normalizeFullFirstUserPromptText(args.text) : null), + args.seedFirstUserPrompt + ) const text = normalizePreviewText(args.text ?? '') if (!text) { return @@ -172,17 +182,7 @@ export function addPreviewMessage( }) if (accumulator.previewMessages.length > SESSION_PREVIEW_MESSAGE_LIMIT) { accumulator.previewMessages.shift() - } - // Why: list scans never store firstUserPrompt (payload/perf). Only the - // on-demand full-capture path seeds the untruncated copy body. - if ( - args.role === 'user' && - args.seedFirstUserPrompt !== false && - !accumulator.firstUserPrompt && - shouldCaptureFullFirstUserPrompt() && - args.text - ) { - accumulator.firstUserPrompt = normalizeFullFirstUserPromptText(args.text) + accumulator.previewMessagesTruncated = true } } @@ -193,14 +193,12 @@ export function addPreviewContent( timestamp?: unknown, options?: { seedFirstUserPrompt?: boolean } ): void { - if ( - role === 'user' && - options?.seedFirstUserPrompt !== false && - !accumulator.firstUserPrompt && - shouldCaptureFullFirstUserPrompt() - ) { - accumulator.firstUserPrompt = extractFullFirstUserPromptText(content) - } + seedFullFirstUserPrompt( + accumulator, + role, + () => extractFullFirstUserPromptText(content), + options?.seedFirstUserPrompt + ) addPreviewMessage(accumulator, { role, text: extractPreviewContentText(content), @@ -210,6 +208,28 @@ export function addPreviewContent( }) } +/** + * Seed the copyable first prompt from the first real user turn. `fullText` is a + * thunk so list scans (capture mode `none`) never pay the extraction cost. + */ +export function seedFullFirstUserPrompt( + accumulator: SessionAccumulator, + role: AiVaultSessionPreviewMessage['role'], + fullText: () => string | null, + seedFirstUserPrompt?: boolean +): void { + // Why: list scans never store firstUserPrompt (payload/perf). Only the + // on-demand full-capture path seeds the untruncated copy body. + if ( + role === 'user' && + seedFirstUserPrompt !== false && + !accumulator.firstUserPrompt && + shouldCaptureFullFirstUserPrompt() + ) { + accumulator.firstUserPrompt = fullText() + } +} + export function timestampIso(value: unknown): string | null { const parsed = timestampMs(value) return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null diff --git a/src/main/ai-vault/session-scanner-agent-parser.ts b/src/main/ai-vault/session-scanner-agent-parser.ts index bcfb8babdfc..1c2c9e84e8e 100644 --- a/src/main/ai-vault/session-scanner-agent-parser.ts +++ b/src/main/ai-vault/session-scanner-agent-parser.ts @@ -10,12 +10,10 @@ import { parseOpenCodeSqliteSessionViaWorker } from './session-scanner-opencode- import { parseClaudeSessionFile } from './session-scanner-primary-parsers' import { parseGeminiSessionFile } from './session-scanner-gemini-parsers' import { parseCodexSessionFile } from './session-scanner-codex-parser' -import { - parseCopilotSessionFile, - parseCursorSessionFile, - parseHermesSessionFile, - parseOpenCodeSessionFile -} from './session-scanner-secondary-parsers' +import { parseCopilotSessionFile } from './session-scanner-copilot-parser' +import { parseCursorSessionFile } from './session-scanner-cursor-parser' +import { parseHermesSessionFile } from './session-scanner-hermes-parser' +import { parseOpenCodeSessionFile } from './session-scanner-opencode-parser' import type { SessionFileCandidate } from './session-scanner-types' /** diff --git a/src/main/ai-vault/session-scanner-antigravity-parser.ts b/src/main/ai-vault/session-scanner-antigravity-parser.ts index 2e3a3a08b4a..818167fbd0c 100644 --- a/src/main/ai-vault/session-scanner-antigravity-parser.ts +++ b/src/main/ai-vault/session-scanner-antigravity-parser.ts @@ -1,3 +1,4 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' import { createReadStream } from 'node:fs' import { createInterface } from 'node:readline' import type { AiVaultSession } from '../../shared/ai-vault-types' @@ -36,11 +37,12 @@ export async function parseAntigravitySessionContent( file: FileWithMtime, content: string, platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} + options: ParserSessionOptions = {}, + signal?: AbortSignal ): Promise { return parseAntigravitySessionLines({ file, - lines: content.split(/\r?\n/), + lines: remoteSessionContentLines(content, signal), platform, options }) diff --git a/src/main/ai-vault/session-scanner-codex-parser.ts b/src/main/ai-vault/session-scanner-codex-parser.ts index 7e08ec9d92e..74e92165c61 100644 --- a/src/main/ai-vault/session-scanner-codex-parser.ts +++ b/src/main/ai-vault/session-scanner-codex-parser.ts @@ -31,6 +31,7 @@ import { parseJsonObject, subtractCodexUsage } from './session-scanner-values' +import { remoteSessionContentLines } from './remote-session-content-lines' export async function parseCodexSessionFile( file: FileWithMtime, @@ -61,10 +62,11 @@ export async function parseCodexSessionContent(args: { executionHostId?: ExecutionHostId executionHostPlatform?: NodeJS.Platform | null readIndexedTitle?: (sessionId: string) => Promise + signal?: AbortSignal }): Promise { return parseCodexSessionLines({ file: args.file, - lines: args.content.split(/\r?\n/), + lines: remoteSessionContentLines(args.content, args.signal), platform: args.platform ?? process.platform, codexHome: args.codexHome ?? null, executionHostId: args.executionHostId, diff --git a/src/main/ai-vault/session-scanner-copilot-parser.ts b/src/main/ai-vault/session-scanner-copilot-parser.ts new file mode 100644 index 00000000000..4d0140fc3df --- /dev/null +++ b/src/main/ai-vault/session-scanner-copilot-parser.ts @@ -0,0 +1,128 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' +import { createReadStream } from 'node:fs' +import { createInterface } from 'node:readline' +import type { AiVaultSession } from '../../shared/ai-vault-types' +import type { ExecutionHostId } from '../../shared/execution-host' +import type { + FileWithMtime, + ResumableSessionParseState, + SessionAccumulator +} from './session-scanner-types' +import { + accumulatorFoldResumeState, + addPreviewMessage, + createAccumulator, + sessionIdFromFileName, + updateTimeline +} from './session-scanner-accumulator' +import { + asRecord, + copilotModelMetricsTotal, + extractString, + extractTrustedFolder, + normalizeTitleText, + numberValue, + parseJsonObject +} from './session-scanner-values' + +type ParserSessionOptions = { + executionHostId?: ExecutionHostId + executionHostPlatform?: NodeJS.Platform | null +} + +export async function parseCopilotSessionFile( + file: FileWithMtime, + platform: NodeJS.Platform = process.platform +): Promise { + const lines = createInterface({ + input: createReadStream(file.path, { encoding: 'utf-8' }), + crlfDelay: Infinity + }) + return parseCopilotSessionLines({ file, lines, platform }) +} + +export async function parseCopilotSessionContent( + file: FileWithMtime, + content: string, + platform: NodeJS.Platform = process.platform, + options: ParserSessionOptions = {}, + signal?: AbortSignal +): Promise { + return parseCopilotSessionLines({ + file, + lines: remoteSessionContentLines(content, signal), + platform, + options + }) +} + +function consumeCopilotRecordLine(accumulator: SessionAccumulator, line: string): void { + const record = parseJsonObject(line) + if (!record) { + return + } + updateTimeline(accumulator, extractString(record.timestamp)) + const data = asRecord(record.data) + if (record.type === 'session.start' && data) { + const sessionId = extractString(data.sessionId) + if (sessionId) { + accumulator.sessionId = sessionId + } + updateTimeline(accumulator, extractString(data.startTime)) + return + } + if (record.type === 'session.model_change' && data) { + accumulator.model = extractString(data.newModel) ?? accumulator.model + return + } + if (record.type === 'session.info' && data) { + accumulator.cwd = extractTrustedFolder(data.message) ?? accumulator.cwd + return + } + if (record.type === 'user.message' && data) { + accumulator.messageCount++ + accumulator.title ??= normalizeTitleText( + extractString(data.transformedContent) ?? extractString(data.content) ?? '' + ) + addPreviewMessage(accumulator, { + role: 'user', + text: extractString(data.transformedContent) ?? extractString(data.content), + timestamp: record.timestamp + }) + return + } + if (record.type === 'assistant.message' && data) { + accumulator.messageCount++ + addPreviewMessage(accumulator, { + role: 'assistant', + text: extractString(data.content), + timestamp: record.timestamp + }) + return + } + if (record.type === 'session.shutdown' && data) { + accumulator.model = extractString(data.currentModel) ?? accumulator.model + accumulator.totalTokens += numberValue(data.currentTokens) + accumulator.totalTokens += copilotModelMetricsTotal(data.modelMetrics) + } +} + +export function createCopilotSessionResumeState(file: FileWithMtime): ResumableSessionParseState { + return accumulatorFoldResumeState( + createAccumulator({ agent: 'copilot', file, sessionId: sessionIdFromFileName(file.path) }), + consumeCopilotRecordLine + ) +} + +async function parseCopilotSessionLines(args: { + file: FileWithMtime + lines: AsyncIterable | Iterable + platform: NodeJS.Platform + options?: ParserSessionOptions +}): Promise { + const state = createCopilotSessionResumeState(args.file) + for await (const line of args.lines) { + state.consumeLine(line) + } + return state.finalize(args.platform, args.options) +} diff --git a/src/main/ai-vault/session-scanner-cursor-parser.ts b/src/main/ai-vault/session-scanner-cursor-parser.ts new file mode 100644 index 00000000000..b18402584e5 --- /dev/null +++ b/src/main/ai-vault/session-scanner-cursor-parser.ts @@ -0,0 +1,96 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' +import { createReadStream } from 'node:fs' +import { createInterface } from 'node:readline' +import type { AiVaultSession } from '../../shared/ai-vault-types' +import type { ExecutionHostId } from '../../shared/execution-host' +import type { + FileWithMtime, + ResumableSessionParseState, + SessionAccumulator +} from './session-scanner-types' +import { + accumulatorFoldResumeState, + addPreviewContent, + createAccumulator, + sessionIdFromFileName, + updateTimeline +} from './session-scanner-accumulator' +import { + asRecord, + extractContentText, + extractMessageText, + extractString, + parseJsonObject +} from './session-scanner-values' + +type ParserSessionOptions = { + executionHostId?: ExecutionHostId + executionHostPlatform?: NodeJS.Platform | null +} + +export async function parseCursorSessionFile( + file: FileWithMtime, + platform: NodeJS.Platform = process.platform +): Promise { + const lines = createInterface({ + input: createReadStream(file.path, { encoding: 'utf-8' }), + crlfDelay: Infinity + }) + return parseCursorSessionLines({ file, lines, platform }) +} + +export async function parseCursorSessionContent( + file: FileWithMtime, + content: string, + platform: NodeJS.Platform = process.platform, + options: ParserSessionOptions = {}, + signal?: AbortSignal +): Promise { + return parseCursorSessionLines({ + file, + lines: remoteSessionContentLines(content, signal), + platform, + options + }) +} + +function consumeCursorRecordLine(accumulator: SessionAccumulator, line: string): void { + const record = parseJsonObject(line) + if (!record) { + return + } + updateTimeline(accumulator, extractString(record.timestamp)) + const role = extractString(record.role) + if (role === 'user' || role === 'assistant') { + accumulator.messageCount++ + if (role === 'user') { + accumulator.title ??= extractMessageText(record.message) ?? extractContentText(record.content) + } + addPreviewContent( + accumulator, + role, + asRecord(record.message)?.content ?? record.content, + record.timestamp + ) + } +} + +export function createCursorSessionResumeState(file: FileWithMtime): ResumableSessionParseState { + return accumulatorFoldResumeState( + createAccumulator({ agent: 'cursor', file, sessionId: sessionIdFromFileName(file.path) }), + consumeCursorRecordLine + ) +} + +async function parseCursorSessionLines(args: { + file: FileWithMtime + lines: AsyncIterable | Iterable + platform: NodeJS.Platform + options?: ParserSessionOptions +}): Promise { + const state = createCursorSessionResumeState(args.file) + for await (const line of args.lines) { + state.consumeLine(line) + } + return state.finalize(args.platform, args.options) +} diff --git a/src/main/ai-vault/session-scanner-droid-parser.ts b/src/main/ai-vault/session-scanner-droid-parser.ts index 2abaa7b8193..557920e7f40 100644 --- a/src/main/ai-vault/session-scanner-droid-parser.ts +++ b/src/main/ai-vault/session-scanner-droid-parser.ts @@ -1,3 +1,4 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' import { createReadStream } from 'node:fs' import { createInterface } from 'node:readline' import type { AiVaultSession } from '../../shared/ai-vault-types' @@ -44,11 +45,12 @@ export async function parseDroidSessionContent( file: FileWithMtime, content: string, platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} + options: ParserSessionOptions = {}, + signal?: AbortSignal ): Promise { return parseDroidSessionLines({ file, - lines: content.split(/\r?\n/), + lines: remoteSessionContentLines(content, signal), platform, options }) diff --git a/src/main/ai-vault/session-scanner-first-user-prompt.test.ts b/src/main/ai-vault/session-scanner-first-user-prompt.test.ts index 47235cbce12..6400b5b6488 100644 --- a/src/main/ai-vault/session-scanner-first-user-prompt.test.ts +++ b/src/main/ai-vault/session-scanner-first-user-prompt.test.ts @@ -16,6 +16,21 @@ describe('AI Vault full first-user-prompt normalization', () => { it('keeps a prompt shorter than the safety limit intact', () => { expect(normalizeFullFirstUserPromptText('ship it 😀')).toBe('ship it 😀') }) + + // Why this matters: the bootstrap probe runs on the bounded slice. That is only + // safe because the envelope strip is unbounded, so a query past the cap is still + // unwrapped and never reaches the probe as a bare user_info dump. + it('unwraps a user_query that lands past the safety limit', () => { + const raw = `\n${'context '.repeat(SAFETY_LIMIT / 4)}\nship it` + + expect(normalizeFullFirstUserPromptText(raw)).toBe('ship it') + }) + + it('still rejects a user_info dump with no user_query anywhere', () => { + const raw = `\n${'context '.repeat(SAFETY_LIMIT / 4)}` + + expect(normalizeFullFirstUserPromptText(raw)).toBeNull() + }) }) function hasUnpairedSurrogate(value: string): boolean { diff --git a/src/main/ai-vault/session-scanner-first-user-prompt.ts b/src/main/ai-vault/session-scanner-first-user-prompt.ts index 4228abc9aaa..8751817c577 100644 --- a/src/main/ai-vault/session-scanner-first-user-prompt.ts +++ b/src/main/ai-vault/session-scanner-first-user-prompt.ts @@ -68,12 +68,16 @@ function finalizeFullFirstUserPrompt(value: string): string | null { if (isKnownHarnessInjectedUserTurnText(trimmed)) { return null } + // Bound before scanning so a multi-MB paste cannot force a full lowercase copy. + const bounded = sliceAtCodeUnitLimit(trimmed, FULL_FIRST_USER_PROMPT_SAFETY_LIMIT) // Reject pure Grok bootstrap dumps even when they arrived via a non-Grok path. - const lower = trimmed.toLowerCase() + // Safe on the bounded slice: stripGrokUserQueryEnvelope above already unwrapped + // any , wherever it sat, so a match here means there was none. + const lower = bounded.toLowerCase() if (lower.startsWith('') && !lower.includes('')) { return null } - return sliceAtCodeUnitLimit(trimmed, FULL_FIRST_USER_PROMPT_SAFETY_LIMIT) + return bounded } function isSuppressedFullFirstUserPrompt(value: string): boolean { diff --git a/src/main/ai-vault/session-scanner-gemini-parsers.ts b/src/main/ai-vault/session-scanner-gemini-parsers.ts index 6f0b9fdc7c1..c3cda8856bb 100644 --- a/src/main/ai-vault/session-scanner-gemini-parsers.ts +++ b/src/main/ai-vault/session-scanner-gemini-parsers.ts @@ -1,3 +1,4 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' import { createReadStream } from 'node:fs' import { readFile } from 'node:fs/promises' import { createInterface } from 'node:readline' @@ -40,12 +41,13 @@ export async function parseGeminiSessionContent( file: FileWithMtime, content: string, platform: NodeJS.Platform = process.platform, - options: ResumableParseFinalizeOptions = {} + options: ResumableParseFinalizeOptions = {}, + signal?: AbortSignal ): Promise { if (file.path.endsWith('.jsonl')) { return parseGeminiJsonlSessionLines({ file, - lines: content.split(/\r?\n/), + lines: remoteSessionContentLines(content, signal), platform, options }) diff --git a/src/main/ai-vault/session-scanner-graph-parsers.ts b/src/main/ai-vault/session-scanner-graph-parsers.ts index 04601eacde5..b4d0c171171 100644 --- a/src/main/ai-vault/session-scanner-graph-parsers.ts +++ b/src/main/ai-vault/session-scanner-graph-parsers.ts @@ -1,3 +1,4 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' import { createReadStream } from 'node:fs' import { readFile } from 'node:fs/promises' import { basename, dirname, join } from 'node:path' @@ -184,12 +185,13 @@ export async function parseMessageGraphSessionContent( file: FileWithMtime, content: string, platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} + options: ParserSessionOptions = {}, + signal?: AbortSignal ): Promise { return parseMessageGraphSessionLines({ agent, file, - lines: content.split(/\r?\n/), + lines: remoteSessionContentLines(content, signal), platform, options }) diff --git a/src/main/ai-vault/session-scanner-hermes-parser.ts b/src/main/ai-vault/session-scanner-hermes-parser.ts new file mode 100644 index 00000000000..be844cc6627 --- /dev/null +++ b/src/main/ai-vault/session-scanner-hermes-parser.ts @@ -0,0 +1,66 @@ +import { readFile } from 'node:fs/promises' +import type { AiVaultSession } from '../../shared/ai-vault-types' +import type { ExecutionHostId } from '../../shared/execution-host' +import type { FileWithMtime } from './session-scanner-types' +import { + addPreviewContent, + createAccumulator, + finalizeSession, + sessionIdFromFileName, + updateTimeline +} from './session-scanner-accumulator' +import { + arrayValue, + asRecord, + extractContentText, + extractString, + numberValue +} from './session-scanner-values' + +type ParserSessionOptions = { + executionHostId?: ExecutionHostId + executionHostPlatform?: NodeJS.Platform | null +} + +export async function parseHermesSessionFile( + file: FileWithMtime, + platform: NodeJS.Platform = process.platform +): Promise { + return parseHermesSessionContent(file, await readFile(file.path, 'utf-8'), platform) +} + +export async function parseHermesSessionContent( + file: FileWithMtime, + content: string, + platform: NodeJS.Platform = process.platform, + options: ParserSessionOptions = {} +): Promise { + const record = asRecord(JSON.parse(content) as unknown) + if (!record) { + return null + } + const accumulator = createAccumulator({ + agent: 'hermes', + file, + sessionId: extractString(record.session_id) ?? sessionIdFromFileName(file.path) + }) + accumulator.model = extractString(record.model) + accumulator.cwd = extractString(record.cwd) + updateTimeline(accumulator, extractString(record.session_start)) + updateTimeline(accumulator, extractString(record.last_updated)) + for (const message of arrayValue(record.messages)) { + const messageRecord = asRecord(message) + const role = extractString(messageRecord?.role) + if (role === 'user' || role === 'assistant') { + accumulator.messageCount++ + if (role === 'user') { + accumulator.title ??= extractContentText(messageRecord?.content) + } + addPreviewContent(accumulator, role, messageRecord?.content) + } + } + if (accumulator.messageCount === 0) { + accumulator.messageCount = numberValue(record.message_count) + } + return finalizeSession(accumulator, platform, options) +} diff --git a/src/main/ai-vault/session-scanner-injected-title.test.ts b/src/main/ai-vault/session-scanner-injected-title.test.ts index f0f566a79f5..a1bf6f799f8 100644 --- a/src/main/ai-vault/session-scanner-injected-title.test.ts +++ b/src/main/ai-vault/session-scanner-injected-title.test.ts @@ -3,6 +3,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' import { scanAiVaultSessions } from './session-scanner' +import { withFullFirstUserPromptCapture } from './session-scanner-first-user-prompt-capture' import { isolatedScanRoots, jsonLines } from './session-scanner-test-fixtures' let tempRoots: string[] = [] @@ -127,10 +128,14 @@ describe('scanAiVaultSessions harness-injected title seeding', () => { ]) ) - const result = await scanAiVaultSessions({ - ...roots, - platform: 'darwin' - }) + // Full capture, else firstUserPrompt is never populated and the assertion + // below would pass whether or not the meta preamble is excluded. + const result = await withFullFirstUserPromptCapture(() => + scanAiVaultSessions({ + ...roots, + platform: 'darwin' + }) + ) expect(result.issues).toEqual([]) expect(result.sessions[0]?.lastUserPrompt).toBe('Fix the zoom behavior in a separate PR') diff --git a/src/main/ai-vault/session-scanner-opencode-parser.test.ts b/src/main/ai-vault/session-scanner-opencode-parser.test.ts new file mode 100644 index 00000000000..9a29927042d --- /dev/null +++ b/src/main/ai-vault/session-scanner-opencode-parser.test.ts @@ -0,0 +1,93 @@ +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { parseOpenCodeSessionFile } from './session-scanner-opencode-parser' +import { withFullFirstUserPromptCapture } from './session-scanner-first-user-prompt-capture' + +let tempDirs: string[] = [] + +afterEach(async () => { + await Promise.all(tempDirs.map((dir) => rm(dir, { recursive: true, force: true }))) + tempDirs = [] +}) + +function userMessage(text: string, createdAt: number): string { + return JSON.stringify({ + role: 'user', + content: [{ type: 'text', text }], + time: { created: createdAt }, + tokens: { input: 5, output: 0 } + }) +} + +describe('parseOpenCodeSessionFile', () => { + it('skips a corrupt message file instead of discarding the whole session', async () => { + const storageRoot = await mkdtemp(join(tmpdir(), 'orca-opencode-parser-')) + tempDirs.push(storageRoot) + const sessionDir = join(storageRoot, 'session', 'project') + const messageDir = join(storageRoot, 'message', 'ses_corrupt') + await mkdir(sessionDir, { recursive: true }) + await mkdir(messageDir, { recursive: true }) + + const path = join(sessionDir, 'ses_corrupt.json') + const mtimeMs = Date.now() + await writeFile( + path, + JSON.stringify({ + id: 'ses_corrupt', + directory: '/tmp/opencode', + title: 'OpenCode title', + time: { created: 1_777_634_000_000, updated: 1_777_634_002_000 } + }) + ) + await writeFile(join(messageDir, 'msg_1.json'), userMessage('First prompt', 1_777_634_000_000)) + // Partially-written file from a live OpenCode process. + await writeFile(join(messageDir, 'msg_2.json'), '{"role":"user","content":[{"type":') + await writeFile(join(messageDir, 'msg_3.json'), userMessage('Third prompt', 1_777_634_002_000)) + + const session = await parseOpenCodeSessionFile({ + path, + mtimeMs, + modifiedAt: new Date(mtimeMs).toISOString() + }) + + expect(session).not.toBeNull() + expect(session?.messageCount).toBe(2) + expect(session?.totalTokens).toBe(10) + expect(session?.previewMessages.map((message) => message.text)).toEqual([ + 'First prompt', + 'Third prompt' + ]) + }) + + it('orders messages by created time when file order disagrees', async () => { + const storageRoot = await mkdtemp(join(tmpdir(), 'orca-opencode-parser-')) + tempDirs.push(storageRoot) + const sessionDir = join(storageRoot, 'session', 'project') + const messageDir = join(storageRoot, 'message', 'ses_order') + await mkdir(sessionDir, { recursive: true }) + await mkdir(messageDir, { recursive: true }) + + const path = join(sessionDir, 'ses_order.json') + const mtimeMs = Date.now() + await writeFile(path, JSON.stringify({ id: 'ses_order', directory: '/tmp/opencode' })) + // File names sort the opposite way from the transcript's creation order. + await writeFile(join(messageDir, 'msg_a.json'), userMessage('Later turn', 1_777_634_002_000)) + await writeFile(join(messageDir, 'msg_b.json'), userMessage('Earliest turn', 1_777_634_000_000)) + + const session = await withFullFirstUserPromptCapture(() => + parseOpenCodeSessionFile({ + path, + mtimeMs, + modifiedAt: new Date(mtimeMs).toISOString() + }) + ) + + expect(session?.firstUserPrompt).toBe('Earliest turn') + expect(session?.previewMessages.map((message) => message.text)).toEqual([ + 'Earliest turn', + 'Later turn' + ]) + }) +}) diff --git a/src/main/ai-vault/session-scanner-opencode-parser.ts b/src/main/ai-vault/session-scanner-opencode-parser.ts new file mode 100644 index 00000000000..4231f7d9de4 --- /dev/null +++ b/src/main/ai-vault/session-scanner-opencode-parser.ts @@ -0,0 +1,126 @@ +import { readFile, readdir } from 'node:fs/promises' +import { join } from 'node:path' +import type { AiVaultSession } from '../../shared/ai-vault-types' +import type { FileWithMtime, SessionAccumulator } from './session-scanner-types' +import { + addPreviewMessage, + createAccumulator, + finalizeSession, + seedFullFirstUserPrompt, + sessionIdFromFileName, + updateTimeline +} from './session-scanner-accumulator' +import { extractFullFirstUserPromptText } from './session-scanner-first-user-prompt' +import { + asRecord, + extractPreviewContentText, + extractString, + findOpenCodeStorageRoot, + normalizeTitleText, + timeObjectValue, + timestampMs, + tokenTotal +} from './session-scanner-values' + +export async function parseOpenCodeSessionFile( + file: FileWithMtime, + platform: NodeJS.Platform = process.platform +): Promise { + const record = asRecord(JSON.parse(await readFile(file.path, 'utf-8')) as unknown) + if (!record) { + return null + } + const sessionId = extractString(record.id) ?? sessionIdFromFileName(file.path) + const accumulator = createAccumulator({ agent: 'opencode', file, sessionId }) + accumulator.title = normalizeTitleText(extractString(record.title) ?? '') + accumulator.cwd = extractString(record.directory) + updateTimeline(accumulator, timeObjectValue(record.time, 'created')) + updateTimeline(accumulator, timeObjectValue(record.time, 'updated')) + await consumeOpenCodeMessages(accumulator, findOpenCodeStorageRoot(file.path), sessionId) + return finalizeSession(accumulator, platform) +} + +// Why: OpenCode stores one file per message and `readdir` order is arbitrary, +// so the transcript has to be rebuilt by creation time before anything reads +// "the first user prompt". Undated messages sort last, by file name, so a +// missing timestamp can never displace a real first turn. +async function readOpenCodeMessagesInOrder(messageDir: string): Promise[]> { + let entries + try { + entries = await readdir(messageDir, { withFileTypes: true }) + } catch { + return [] + } + const messages: { name: string; createdMs: number; message: Record }[] = [] + for (const entry of entries) { + if (!entry.isFile() || !entry.name.endsWith('.json')) { + continue + } + let message: Record | null = null + try { + message = asRecord( + JSON.parse(await readFile(join(messageDir, entry.name), 'utf-8')) as unknown + ) + } catch { + // A live OpenCode process can leave a half-written file; skip it rather + // than discard the whole session. + continue + } + if (!message) { + continue + } + const createdMs = timestampMs(timeObjectValue(message.time, 'created')) + messages.push({ + name: entry.name, + createdMs: Number.isFinite(createdMs) ? createdMs : Number.POSITIVE_INFINITY, + message + }) + } + return messages + .sort((a, b) => a.createdMs - b.createdMs || a.name.localeCompare(b.name)) + .map((entry) => entry.message) +} + +export async function consumeOpenCodeMessages( + accumulator: SessionAccumulator, + storageRoot: string | null, + sessionId: string +): Promise { + if (!storageRoot) { + return + } + for (const message of await readOpenCodeMessagesInOrder( + join(storageRoot, 'message', sessionId) + )) { + const role = extractString(message.role) + if (role === 'user' || role === 'assistant') { + accumulator.messageCount++ + updateTimeline(accumulator, timeObjectValue(message.time, 'created')) + const summary = asRecord(message.summary) + if (role === 'user') { + accumulator.title ??= extractString(summary?.title) ?? extractString(summary?.body) + } + // Why: the summary fallbacks are AI-generated. Seed the copyable first + // prompt from real typed content only, never from a summary of a + // harness-injected turn. Extraction stays inside the thunk so list scans + // (capture mode `none`) never pay for it. + seedFullFirstUserPrompt(accumulator, role, () => + extractFullFirstUserPromptText(message.content) + ) + addPreviewMessage(accumulator, { + role, + text: + extractPreviewContentText(message.content) ?? + extractString(summary?.body) ?? + extractString(summary?.title), + timestamp: timeObjectValue(message.time, 'created'), + seedFirstUserPrompt: false + }) + accumulator.model = + extractString(asRecord(message.model)?.modelID) || + extractString(message.modelID) || + accumulator.model + accumulator.totalTokens += tokenTotal(message.tokens) + } + } +} diff --git a/src/main/ai-vault/session-scanner-opencode-sqlite-bounds.test.ts b/src/main/ai-vault/session-scanner-opencode-sqlite-bounds.test.ts index 7f50a220247..87cc8eb2f47 100644 --- a/src/main/ai-vault/session-scanner-opencode-sqlite-bounds.test.ts +++ b/src/main/ai-vault/session-scanner-opencode-sqlite-bounds.test.ts @@ -135,6 +135,22 @@ describe('listOpenCodeSqliteSessions — LIMIT-first discovery', () => { ]) }) + it('omits the SQL limit for an Unlimited scan', async () => { + const { db, path } = createTempDb() + applySchema(db) + for (let i = 0; i < 5; i++) { + insertSession(db, `ses_${i}`, 1_777_634_000_000 + i * 1000) + } + db.close() + + const candidates = await listOpenCodeSqliteSessions({ + dbPaths: [path], + limit: Number.POSITIVE_INFINITY, + issues: [] + }) + expect(candidates).toHaveLength(5) + }) + it('uses time_created recency when time_updated is not positive', async () => { const { db, path } = createTempDb() applySchema(db) diff --git a/src/main/ai-vault/session-scanner-opencode-sqlite-list.ts b/src/main/ai-vault/session-scanner-opencode-sqlite-list.ts index 5d6c6202824..4b86d04161a 100644 --- a/src/main/ai-vault/session-scanner-opencode-sqlite-list.ts +++ b/src/main/ai-vault/session-scanner-opencode-sqlite-list.ts @@ -32,7 +32,7 @@ function canReadOpenCodeSessions(db: SyncDatabase): boolean { ) } -function buildSessionListQuery(db: SyncDatabase): string { +function buildSessionListQuery(db: SyncDatabase, limited: boolean): string { const parentIdPredicate = columnExists(db, 'session', 'parent_id') ? 'AND parent_id IS NULL' : '' const archivedPredicate = columnExists(db, 'session', 'time_archived') ? 'AND time_archived IS NULL' @@ -45,7 +45,7 @@ function buildSessionListQuery(db: SyncDatabase): string { FROM session WHERE 1=1 ${parentIdPredicate} ${archivedPredicate} ORDER BY CASE WHEN time_updated > 0 THEN time_updated ELSE time_created END DESC - LIMIT ?` + ${limited ? 'LIMIT ?' : ''}` } function rowToCandidate(row: SessionRow, dbPath: string): SessionFileCandidate { @@ -105,7 +105,9 @@ export async function listOpenCodeSqliteSessions(args: { if (!canReadOpenCodeSessions(db)) { continue } - const rows = db.prepare(buildSessionListQuery(db)).all(args.limit) as SessionRow[] + const limited = Number.isFinite(args.limit) + const statement = db.prepare(buildSessionListQuery(db, limited)) + const rows = (limited ? statement.all(args.limit) : statement.all()) as SessionRow[] for (const row of rows) { candidates.push(rowToCandidate(row, dbPath)) } diff --git a/src/main/ai-vault/session-scanner-opencode-sqlite.ts b/src/main/ai-vault/session-scanner-opencode-sqlite.ts index d247156b8cf..c0ffdbfb894 100644 --- a/src/main/ai-vault/session-scanner-opencode-sqlite.ts +++ b/src/main/ai-vault/session-scanner-opencode-sqlite.ts @@ -294,9 +294,17 @@ export async function parseOpenCodeSqliteSession(args: { const previewSql = buildPreviewQuery(db) if (previewSql) { - const previewRows = db + // Why: SQL already dropped anything older than the newest-N window, so the + // accumulator never shifts and cannot detect the truncation itself. Ask for + // one extra row so an exactly-full window is not mistaken for a trimmed one. + const probedRows = db .prepare(previewSql) - .all(sessionId, OPENCODE_SQLITE_PREVIEW_LIMIT) as PreviewRow[] + .all(sessionId, OPENCODE_SQLITE_PREVIEW_LIMIT + 1) as PreviewRow[] + if (probedRows.length > OPENCODE_SQLITE_PREVIEW_LIMIT) { + accumulator.previewMessagesTruncated = true + } + // Newest-first, so the probe row to drop is the oldest one at the tail. + const previewRows = probedRows.slice(0, OPENCODE_SQLITE_PREVIEW_LIMIT) // Why: query returns newest-first; push in chronological order so the // accumulator's ring buffer keeps the newest OPENCODE_SQLITE_PREVIEW_LIMIT // messages. diff --git a/src/main/ai-vault/session-scanner-parse-cache.ts b/src/main/ai-vault/session-scanner-parse-cache.ts index b3e4448a410..572002197e0 100644 --- a/src/main/ai-vault/session-scanner-parse-cache.ts +++ b/src/main/ai-vault/session-scanner-parse-cache.ts @@ -8,10 +8,8 @@ import { createDroidSessionResumeState } from './session-scanner-droid-parser' import { createMessageGraphSessionResumeState } from './session-scanner-graph-parsers' import { createClaudeSessionResumeState } from './session-scanner-primary-parsers' import { createGeminiJsonlSessionResumeState } from './session-scanner-gemini-parsers' -import { - createCopilotSessionResumeState, - createCursorSessionResumeState -} from './session-scanner-secondary-parsers' +import { createCopilotSessionResumeState } from './session-scanner-copilot-parser' +import { createCursorSessionResumeState } from './session-scanner-cursor-parser' import { countSubagentTranscripts } from './session-scanner-subagent-transcripts' import type { ResumableSessionParseState, SessionFileCandidate } from './session-scanner-types' diff --git a/src/main/ai-vault/session-scanner-preview-window-truncation.test.ts b/src/main/ai-vault/session-scanner-preview-window-truncation.test.ts new file mode 100644 index 00000000000..936e97134c7 --- /dev/null +++ b/src/main/ai-vault/session-scanner-preview-window-truncation.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, it } from 'vitest' +import { + addPreviewMessage, + createAccumulator, + finalizeSession +} from './session-scanner-accumulator' +import type { SessionAccumulator } from './session-scanner-types' + +// Mirrors SESSION_PREVIEW_MESSAGE_LIMIT in the module under test. +const PREVIEW_LIMIT = 5 + +function accumulatorWithUserTurns(count: number): SessionAccumulator { + const accumulator = createAccumulator({ + agent: 'claude', + file: { path: '/tmp/session-1.jsonl', mtimeMs: 0, modifiedAt: new Date(0).toISOString() }, + sessionId: 'session-1' + }) + for (let index = 0; index < count; index += 1) { + addPreviewMessage(accumulator, { role: 'user', text: `turn ${index}` }) + } + return accumulator +} + +describe('AI Vault preview-window truncation signal', () => { + it('leaves the flag off while the window still holds the whole transcript', () => { + const session = finalizeSession(accumulatorWithUserTurns(PREVIEW_LIMIT), 'darwin') + + expect(session?.previewMessages).toHaveLength(PREVIEW_LIMIT) + expect(session?.previewMessagesTruncated).toBeUndefined() + }) + + it('flags the session once an older turn falls out of the window', () => { + const session = finalizeSession(accumulatorWithUserTurns(PREVIEW_LIMIT + 1), 'darwin') + + // The opening ask is gone, so the earliest preview turn is not the first prompt. + expect(session?.previewMessages[0]?.text).toBe('turn 1') + expect(session?.previewMessagesTruncated).toBe(true) + }) + + it('carries the flag onto snapshots taken from a cloned accumulator', () => { + const accumulator = accumulatorWithUserTurns(PREVIEW_LIMIT + 1) + + expect(finalizeSession({ ...accumulator }, 'darwin')?.previewMessagesTruncated).toBe(true) + }) +}) diff --git a/src/main/ai-vault/session-scanner-primary-parsers.ts b/src/main/ai-vault/session-scanner-primary-parsers.ts index 537055d87d4..92db2241320 100644 --- a/src/main/ai-vault/session-scanner-primary-parsers.ts +++ b/src/main/ai-vault/session-scanner-primary-parsers.ts @@ -1,3 +1,4 @@ +import { remoteSessionContentLines } from './remote-session-content-lines' import { createReadStream } from 'node:fs' import { createInterface } from 'node:readline' import type { AiVaultSession } from '../../shared/ai-vault-types' @@ -219,11 +220,12 @@ export async function parseClaudeSessionContent( file: FileWithMtime, content: string, platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} + options: ParserSessionOptions = {}, + signal?: AbortSignal ): Promise { return parseClaudeSessionLines({ file, - lines: content.split(/\r?\n/), + lines: remoteSessionContentLines(content, signal), platform, options }) diff --git a/src/main/ai-vault/session-scanner-secondary-parsers.ts b/src/main/ai-vault/session-scanner-secondary-parsers.ts deleted file mode 100644 index cb472aaefe9..00000000000 --- a/src/main/ai-vault/session-scanner-secondary-parsers.ts +++ /dev/null @@ -1,316 +0,0 @@ -import { createReadStream } from 'node:fs' -import { readFile, readdir } from 'node:fs/promises' -import { join } from 'node:path' -import { createInterface } from 'node:readline' -import type { AiVaultSession } from '../../shared/ai-vault-types' -import type { ExecutionHostId } from '../../shared/execution-host' -import type { - FileWithMtime, - ResumableSessionParseState, - SessionAccumulator -} from './session-scanner-types' -import { - accumulatorFoldResumeState, - addPreviewContent, - addPreviewMessage, - createAccumulator, - finalizeSession, - sessionIdFromFileName, - updateTimeline -} from './session-scanner-accumulator' -import { extractFullFirstUserPromptText } from './session-scanner-first-user-prompt' -import { - arrayValue, - asRecord, - copilotModelMetricsTotal, - extractContentText, - extractMessageText, - extractString, - extractTrustedFolder, - findOpenCodeStorageRoot, - normalizeTitleText, - numberValue, - parseJsonObject, - timeObjectValue, - tokenTotal -} from './session-scanner-values' - -type ParserSessionOptions = { - executionHostId?: ExecutionHostId - executionHostPlatform?: NodeJS.Platform | null -} - -export async function parseCopilotSessionFile( - file: FileWithMtime, - platform: NodeJS.Platform = process.platform -): Promise { - const lines = createInterface({ - input: createReadStream(file.path, { encoding: 'utf-8' }), - crlfDelay: Infinity - }) - return parseCopilotSessionLines({ file, lines, platform }) -} - -export async function parseCopilotSessionContent( - file: FileWithMtime, - content: string, - platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} -): Promise { - return parseCopilotSessionLines({ - file, - lines: content.split(/\r?\n/), - platform, - options - }) -} - -function consumeCopilotRecordLine(accumulator: SessionAccumulator, line: string): void { - const record = parseJsonObject(line) - if (!record) { - return - } - updateTimeline(accumulator, extractString(record.timestamp)) - const data = asRecord(record.data) - if (record.type === 'session.start' && data) { - const sessionId = extractString(data.sessionId) - if (sessionId) { - accumulator.sessionId = sessionId - } - updateTimeline(accumulator, extractString(data.startTime)) - return - } - if (record.type === 'session.model_change' && data) { - accumulator.model = extractString(data.newModel) ?? accumulator.model - return - } - if (record.type === 'session.info' && data) { - accumulator.cwd = extractTrustedFolder(data.message) ?? accumulator.cwd - return - } - if (record.type === 'user.message' && data) { - accumulator.messageCount++ - accumulator.title ??= normalizeTitleText( - extractString(data.transformedContent) ?? extractString(data.content) ?? '' - ) - addPreviewMessage(accumulator, { - role: 'user', - text: extractString(data.transformedContent) ?? extractString(data.content), - timestamp: record.timestamp - }) - return - } - if (record.type === 'assistant.message' && data) { - accumulator.messageCount++ - addPreviewMessage(accumulator, { - role: 'assistant', - text: extractString(data.content), - timestamp: record.timestamp - }) - return - } - if (record.type === 'session.shutdown' && data) { - accumulator.model = extractString(data.currentModel) ?? accumulator.model - accumulator.totalTokens += numberValue(data.currentTokens) - accumulator.totalTokens += copilotModelMetricsTotal(data.modelMetrics) - } -} - -export function createCopilotSessionResumeState(file: FileWithMtime): ResumableSessionParseState { - return accumulatorFoldResumeState( - createAccumulator({ agent: 'copilot', file, sessionId: sessionIdFromFileName(file.path) }), - consumeCopilotRecordLine - ) -} - -async function parseCopilotSessionLines(args: { - file: FileWithMtime - lines: AsyncIterable | Iterable - platform: NodeJS.Platform - options?: ParserSessionOptions -}): Promise { - const state = createCopilotSessionResumeState(args.file) - for await (const line of args.lines) { - state.consumeLine(line) - } - return state.finalize(args.platform, args.options) -} - -export async function parseCursorSessionFile( - file: FileWithMtime, - platform: NodeJS.Platform = process.platform -): Promise { - const lines = createInterface({ - input: createReadStream(file.path, { encoding: 'utf-8' }), - crlfDelay: Infinity - }) - return parseCursorSessionLines({ file, lines, platform }) -} - -export async function parseCursorSessionContent( - file: FileWithMtime, - content: string, - platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} -): Promise { - return parseCursorSessionLines({ - file, - lines: content.split(/\r?\n/), - platform, - options - }) -} - -function consumeCursorRecordLine(accumulator: SessionAccumulator, line: string): void { - const record = parseJsonObject(line) - if (!record) { - return - } - updateTimeline(accumulator, extractString(record.timestamp)) - const role = extractString(record.role) - if (role === 'user' || role === 'assistant') { - accumulator.messageCount++ - if (role === 'user') { - accumulator.title ??= extractMessageText(record.message) ?? extractContentText(record.content) - } - addPreviewContent( - accumulator, - role, - asRecord(record.message)?.content ?? record.content, - record.timestamp - ) - } -} - -export function createCursorSessionResumeState(file: FileWithMtime): ResumableSessionParseState { - return accumulatorFoldResumeState( - createAccumulator({ agent: 'cursor', file, sessionId: sessionIdFromFileName(file.path) }), - consumeCursorRecordLine - ) -} - -async function parseCursorSessionLines(args: { - file: FileWithMtime - lines: AsyncIterable | Iterable - platform: NodeJS.Platform - options?: ParserSessionOptions -}): Promise { - const state = createCursorSessionResumeState(args.file) - for await (const line of args.lines) { - state.consumeLine(line) - } - return state.finalize(args.platform, args.options) -} - -export async function parseOpenCodeSessionFile( - file: FileWithMtime, - platform: NodeJS.Platform = process.platform -): Promise { - const record = asRecord(JSON.parse(await readFile(file.path, 'utf-8')) as unknown) - if (!record) { - return null - } - const sessionId = extractString(record.id) ?? sessionIdFromFileName(file.path) - const accumulator = createAccumulator({ agent: 'opencode', file, sessionId }) - accumulator.title = normalizeTitleText(extractString(record.title) ?? '') - accumulator.cwd = extractString(record.directory) - updateTimeline(accumulator, timeObjectValue(record.time, 'created')) - updateTimeline(accumulator, timeObjectValue(record.time, 'updated')) - await consumeOpenCodeMessages(accumulator, findOpenCodeStorageRoot(file.path), sessionId) - return finalizeSession(accumulator, platform) -} - -export async function consumeOpenCodeMessages( - accumulator: SessionAccumulator, - storageRoot: string | null, - sessionId: string -): Promise { - if (!storageRoot) { - return - } - const messageDir = join(storageRoot, 'message', sessionId) - let entries - try { - entries = await readdir(messageDir, { withFileTypes: true }) - } catch { - return - } - for (const entry of entries) { - if (!entry.isFile() || !entry.name.endsWith('.json')) { - continue - } - const message = asRecord( - JSON.parse(await readFile(join(messageDir, entry.name), 'utf-8')) as unknown - ) - if (!message) { - continue - } - const role = extractString(message.role) - if (role === 'user' || role === 'assistant') { - accumulator.messageCount++ - updateTimeline(accumulator, timeObjectValue(message.time, 'created')) - if (role === 'user') { - accumulator.title ??= extractString(asRecord(message.summary)?.title) - accumulator.title ??= extractString(asRecord(message.summary)?.body) - } - // Why: pass raw body text so full first-prompt capture is not stuck on the - // 220-char preview fold (addPreviewMessage preview-caps for display). - addPreviewMessage(accumulator, { - role, - text: - extractFullFirstUserPromptText(message.content) ?? - extractString(asRecord(message.summary)?.body) ?? - extractString(asRecord(message.summary)?.title), - timestamp: timeObjectValue(message.time, 'created') - }) - accumulator.model = - extractString(asRecord(message.model)?.modelID) || - extractString(message.modelID) || - accumulator.model - accumulator.totalTokens += tokenTotal(message.tokens) - } - } -} - -export async function parseHermesSessionFile( - file: FileWithMtime, - platform: NodeJS.Platform = process.platform -): Promise { - return parseHermesSessionContent(file, await readFile(file.path, 'utf-8'), platform) -} - -export async function parseHermesSessionContent( - file: FileWithMtime, - content: string, - platform: NodeJS.Platform = process.platform, - options: ParserSessionOptions = {} -): Promise { - const record = asRecord(JSON.parse(content) as unknown) - if (!record) { - return null - } - const accumulator = createAccumulator({ - agent: 'hermes', - file, - sessionId: extractString(record.session_id) ?? sessionIdFromFileName(file.path) - }) - accumulator.model = extractString(record.model) - accumulator.cwd = extractString(record.cwd) - updateTimeline(accumulator, extractString(record.session_start)) - updateTimeline(accumulator, extractString(record.last_updated)) - for (const message of arrayValue(record.messages)) { - const messageRecord = asRecord(message) - const role = extractString(messageRecord?.role) - if (role === 'user' || role === 'assistant') { - accumulator.messageCount++ - if (role === 'user') { - accumulator.title ??= extractContentText(messageRecord?.content) - } - addPreviewContent(accumulator, role, messageRecord?.content) - } - } - if (accumulator.messageCount === 0) { - accumulator.messageCount = numberValue(record.message_count) - } - return finalizeSession(accumulator, platform, options) -} diff --git a/src/main/ai-vault/session-scanner-types.ts b/src/main/ai-vault/session-scanner-types.ts index cc8f4939aa2..13b40698cfd 100644 --- a/src/main/ai-vault/session-scanner-types.ts +++ b/src/main/ai-vault/session-scanner-types.ts @@ -34,12 +34,16 @@ export type AiVaultScanOptions = { droidProjectsDir?: string kimiSessionsDir?: string limit?: number + unlimited?: boolean limitPerAgent?: number // Active workspace/project paths whose sessions must be included regardless of // the recency cap (see discoverInScopeClaudeFiles). scopePaths?: readonly string[] platform?: NodeJS.Platform executionHostId?: ExecutionHostId + // Superseded/cancelled scans stop between parse batches instead of parsing + // every remaining transcript for a caller that already left. + signal?: AbortSignal } export type FileWithMtime = { @@ -110,6 +114,9 @@ export type SessionAccumulator = { messageCount: number totalTokens: number previewMessages: AiVaultSessionPreviewMessage[] + // True once an older message fell out of the newest-N preview window, so the + // earliest preview turn is no longer the session's opening ask. + previewMessagesTruncated: boolean firstUserPrompt: string | null lastUserPrompt: string | null // Recoverable signal for a zero-turn transcript (see AiVaultSession). diff --git a/src/main/ai-vault/session-scanner.test.ts b/src/main/ai-vault/session-scanner.test.ts index 7c472d6f3eb..e6d49d1b965 100644 --- a/src/main/ai-vault/session-scanner.test.ts +++ b/src/main/ai-vault/session-scanner.test.ts @@ -154,7 +154,9 @@ describe('scanAiVaultSessions', () => { const result = await scanAiVaultSessions({ ...roots, - platform: 'darwin' + platform: 'darwin', + limit: 1, + unlimited: true }) expect(result.issues).toEqual([]) diff --git a/src/main/ai-vault/session-scanner.ts b/src/main/ai-vault/session-scanner.ts index f1979c67626..3a98b7018ac 100644 --- a/src/main/ai-vault/session-scanner.ts +++ b/src/main/ai-vault/session-scanner.ts @@ -39,13 +39,11 @@ import type { SessionParseResult } from './session-scanner-types' import { clampPositiveInteger, errorMessage } from './session-scanner-values' +import { throwIfAiVaultScanCancelled } from './ai-vault-scan-cancellation' +import { DEFAULT_AI_VAULT_SCAN_LIMIT } from '../../shared/ai-vault-session-depth' -const DEFAULT_LIMIT = 1000 -const DEFAULT_SCAN_LIMIT_PER_AGENT = 1000 const SESSION_PARSE_CONCURRENCY = 8 -// Upper bound on extra in-scope transcripts discovered and parsed past the -// recency cap; guards against a pathological scoped history directory. -const SCOPE_PARSE_LIMIT = 2000 +const SESSION_PARSE_CANDIDATE_MULTIPLIER = 2 /** * Scan all supported AI agent session stores and return a unified, sorted, @@ -63,8 +61,12 @@ export async function scanAiVaultSessions( // "one core pegged" reports need to show whether transcript scanning is the // subsystem burning CPU, and how much of each scan the cache absorbed. return withSpan('aiVault.scan', async (span) => { - const limit = clampPositiveInteger(options.limit, DEFAULT_LIMIT) - const limitPerAgent = clampPositiveInteger(options.limitPerAgent, DEFAULT_SCAN_LIMIT_PER_AGENT) + const limit = options.unlimited + ? Number.POSITIVE_INFINITY + : clampPositiveInteger(options.limit, DEFAULT_AI_VAULT_SCAN_LIMIT) + const limitPerAgent = options.unlimited + ? Number.POSITIVE_INFINITY + : clampPositiveInteger(options.limitPerAgent, limit * SESSION_PARSE_CANDIDATE_MULTIPLIER) const platform = options.platform ?? process.platform const executionHostId = options.executionHostId ?? LOCAL_EXECUTION_HOST_ID const issues: AiVaultScanIssue[] = [] @@ -72,8 +74,10 @@ export async function scanAiVaultSessions( const antigravityWorkspaceResolver = createAntigravityWorkspaceResolver(readOptionalTextFile) // Why: persisted entries must be seeded before any candidate is parsed, or // the cold scan gains nothing from the cache file (#9210). + throwIfAiVaultScanCancelled(options.signal) await ensureSessionParseCacheLoaded() const discoveries = await discoverAiVaultSessionSources({ options, limitPerAgent, issues }) + throwIfAiVaultScanCancelled(options.signal) const candidates = dedupeCodexRolloutFileAliases( discoveries @@ -106,12 +110,13 @@ export async function scanAiVaultSessions( ) const parsedSessions = await parseSessionCandidates({ - candidates, + candidates: candidates.slice(0, limit * SESSION_PARSE_CANDIDATE_MULTIPLIER), limit, platform, executionHostId, issues, parseStats, + signal: options.signal, antigravityWorkspaceResolver }) @@ -122,12 +127,17 @@ export async function scanAiVaultSessions( const scopeSessions = await scanInScopeSessions({ discoveries, scopePaths: options.scopePaths ?? [], + limit, alreadyParsedFilePaths: new Set(cappedSessions.map((session) => session.filePath)), platform, executionHostId, issues, - parseStats + parseStats, + signal: options.signal }) + // Scope discovery can return without parsing anything, so an abort landing + // here would otherwise persist and return a cancelled scan as complete. + throwIfAiVaultScanCancelled(options.signal) span.setAttribute('candidates', candidates.length) span.setAttribute('reused', parseStats.reused) @@ -169,11 +179,13 @@ function mergeSessions( async function scanInScopeSessions(args: { discoveries: SessionFileDiscovery[] scopePaths: readonly string[] + limit: number alreadyParsedFilePaths: ReadonlySet platform: NodeJS.Platform executionHostId: ExecutionHostId issues: AiVaultScanIssue[] parseStats: SessionParseStats + signal?: AbortSignal }): Promise { if (args.scopePaths.length === 0) { return [] @@ -184,7 +196,7 @@ async function scanInScopeSessions(args: { const files = await discoverInScopeClaudeFiles({ rootDirs: claudeRootDirs, scopePaths: args.scopePaths, - limit: SCOPE_PARSE_LIMIT, + limit: args.limit, excludedFilePaths: args.alreadyParsedFilePaths, issues: args.issues }) @@ -201,7 +213,8 @@ async function scanInScopeSessions(args: { platform: args.platform, executionHostId: args.executionHostId, issues: args.issues, - parseStats: args.parseStats + parseStats: args.parseStats, + signal: args.signal }) } @@ -212,12 +225,14 @@ async function parseSessionCandidates(args: { executionHostId: ExecutionHostId issues: AiVaultScanIssue[] parseStats: SessionParseStats + signal?: AbortSignal antigravityWorkspaceResolver?: AntigravityWorkspaceResolver }): Promise { const sessions: AiVaultSession[] = [] let index = 0 while (index < args.candidates.length) { + throwIfAiVaultScanCancelled(args.signal) if (canStopParsingSessions(sessions, args.limit, args.candidates[index]?.file.mtimeMs)) { break } @@ -255,6 +270,9 @@ async function parseSessionCandidates(args: { index += batchSize } + // An abort can land while the final batch settles; observe it here so a + // partial parse is never cached or returned as a complete scan. + throwIfAiVaultScanCancelled(args.signal) return sessions } diff --git a/src/main/ai-vault/ssh-session-list.test.ts b/src/main/ai-vault/ssh-session-list.test.ts new file mode 100644 index 00000000000..4d1abd483c3 --- /dev/null +++ b/src/main/ai-vault/ssh-session-list.test.ts @@ -0,0 +1,249 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import type { AiVaultListResult, AiVaultSession } from '../../shared/ai-vault-types' +import { SSH_MUX_REQUEST_TIMEOUT_CODE } from '../ssh/ssh-channel-multiplexer' + +const requestActiveSshAiVaultSessionList = vi.fn() +const getActiveSshAiVaultHostInfo = vi.fn() +const getSshFilesystemProvider = vi.fn() +const scanRemoteAiVaultSessions = vi.fn() + +vi.mock('../ipc/ssh', () => ({ + requestActiveSshAiVaultSessionList: (...args: unknown[]) => + requestActiveSshAiVaultSessionList(...args), + getActiveSshAiVaultHostInfo: (...args: unknown[]) => getActiveSshAiVaultHostInfo(...args) +})) + +vi.mock('../providers/ssh-filesystem-dispatch', () => ({ + getSshFilesystemProvider: (...args: unknown[]) => getSshFilesystemProvider(...args), + SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE: 'SSH filesystem is unavailable.' +})) + +vi.mock('./remote-session-scanner', () => ({ + scanRemoteAiVaultSessions: (...args: unknown[]) => scanRemoteAiVaultSessions(...args) +})) + +const { scanSshAiVaultSessions } = await import('./ssh-session-list') + +describe('scanSshAiVaultSessions', () => { + beforeEach(() => { + vi.clearAllMocks() + vi.useRealTimers() + getActiveSshAiVaultHostInfo.mockReturnValue({ remoteHome: '/home/dev', hostPlatform: 'linux' }) + getSshFilesystemProvider.mockReturnValue({}) + }) + + it('returns at the deadline when the legacy crawl ignores abort', async () => { + // Relay without the method resolves null, so the leg falls through to the + // desktop crawl — which used to run unbounded even under an all-host budget. + vi.useFakeTimers() + requestActiveSshAiVaultSessionList.mockResolvedValue(null) + let fallbackSignal: AbortSignal | undefined + scanRemoteAiVaultSessions.mockImplementation(({ signal }: { signal?: AbortSignal }) => { + fallbackSignal = signal + return new Promise(() => {}) + }) + + const resultPromise = scanSshAiVaultSessions('dev-box', undefined, { timeoutMs: 20 }) + await vi.advanceTimersByTimeAsync(20) + const result = await Promise.race([resultPromise, Promise.resolve('still-pending' as const)]) + + expect(result).not.toBe('still-pending') + expect(fallbackSignal?.aborted).toBe(true) + if (result === 'still-pending') { + return + } + expect(result.sessions).toEqual([]) + expect(result.issues).toEqual([ + expect.objectContaining({ + executionHostId: 'ssh:dev-box', + kind: 'host', + message: 'Agent Session History scan timed out after 20ms on this SSH host.' + }) + ]) + }) + + it('leaves the crawl unbounded when no budget was requested', async () => { + requestActiveSshAiVaultSessionList.mockResolvedValue(null) + scanRemoteAiVaultSessions.mockResolvedValue(emptyResult()) + + await scanSshAiVaultSessions('dev-box') + + expect(scanRemoteAiVaultSessions).toHaveBeenCalledWith( + expect.objectContaining({ signal: undefined }) + ) + }) + + it('reports an unexpected crawl failure as a host issue instead of rejecting', async () => { + // Why: `all` scope awaits every host leg together, so a throw here would + // discard the local sessions alongside this host's. + requestActiveSshAiVaultSessionList.mockResolvedValue(null) + scanRemoteAiVaultSessions.mockRejectedValue(new TypeError('provider blew up')) + + const result = await scanSshAiVaultSessions('dev-box') + + expect(result.sessions).toEqual([]) + expect(result.issues).toEqual([ + expect.objectContaining({ executionHostId: 'ssh:dev-box', message: 'provider blew up' }) + ]) + }) + + it('bounds the relay round trip separately from the whole leg', async () => { + // The relay needs seconds to walk a real remote home; only the leg total + // has to stay short enough that one host cannot hold the merge open. + requestActiveSshAiVaultSessionList.mockResolvedValue(null) + scanRemoteAiVaultSessions.mockResolvedValue(emptyResult()) + + await scanSshAiVaultSessions('dev-box', undefined, { + timeoutMs: 20_000, + relayTimeoutMs: 15_000 + }) + + expect(requestActiveSshAiVaultSessionList).toHaveBeenCalledWith( + 'dev-box', + expect.any(Object), + expect.objectContaining({ timeoutMs: 15_000 }) + ) + }) + + it('keeps a relay scan that outran the old three-second bound', async () => { + // Regression: the shared 3s budget emptied healthy hosts in the all-hosts + // view. A relay answering inside the scan budget must keep its sessions. + requestActiveSshAiVaultSessionList.mockImplementation( + (_targetId: string, _params: unknown, options: { timeoutMs?: number }) => + (options.timeoutMs ?? 0) > 3_000 + ? Promise.resolve({ + sessions: [remoteSession()], + issues: [], + scannedAt: '2026-08-02T00:00:00.000Z' + }) + : Promise.reject(relayTimeoutError()) + ) + + const result = await scanSshAiVaultSessions('dev-box', undefined, { + timeoutMs: 20_000, + relayTimeoutMs: 15_000 + }) + + expect(result.sessions).toEqual([expect.objectContaining({ sessionId: 'remote-session' })]) + expect(scanRemoteAiVaultSessions).not.toHaveBeenCalled() + }) + + it('reports a host issue when the relay timed out on a real scan budget', async () => { + // A relay that had a fair scan window will not answer faster over the far + // slower filesystem crawl, so retrying it only stalls the merge. + requestActiveSshAiVaultSessionList.mockRejectedValue(relayTimeoutError()) + + const result = await scanSshAiVaultSessions('dev-box', undefined, { + timeoutMs: 20_000, + relayTimeoutMs: 15_000 + }) + + expect(scanRemoteAiVaultSessions).not.toHaveBeenCalled() + expect(result.issues).toEqual([ + expect.objectContaining({ executionHostId: 'ssh:dev-box', kind: 'host' }) + ]) + }) + + it('still falls back when the relay budget was too short for a fair attempt', async () => { + requestActiveSshAiVaultSessionList.mockRejectedValue(relayTimeoutError()) + scanRemoteAiVaultSessions.mockResolvedValue({ + sessions: [remoteSession()], + issues: [], + scannedAt: '2026-08-02T00:00:00.000Z' + }) + + const result = await scanSshAiVaultSessions('dev-box', undefined, { + timeoutMs: 3_000, + relayTimeoutMs: 2_000 + }) + + expect(scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(result.sessions).toEqual([expect.objectContaining({ sessionId: 'remote-session' })]) + }) + + it('does not treat an unrelated error mentioning a timeout as a relay timeout', async () => { + requestActiveSshAiVaultSessionList.mockRejectedValue( + new Error('the remote agent timed out after loading its index') + ) + scanRemoteAiVaultSessions.mockResolvedValue({ + sessions: [remoteSession()], + issues: [], + scannedAt: '2026-08-02T00:00:00.000Z' + }) + + const result = await scanSshAiVaultSessions('dev-box', undefined, { + timeoutMs: 20_000, + relayTimeoutMs: 15_000 + }) + + expect(scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(result.sessions).toEqual([expect.objectContaining({ sessionId: 'remote-session' })]) + }) + + it('reports the relay error when the fallback crawl recovered nothing', async () => { + // Otherwise a broken relay over an empty crawl reads as a healthy but empty + // host, and the panel shows no reason for the missing sessions. + requestActiveSshAiVaultSessionList.mockRejectedValue(new Error('relay method exploded')) + scanRemoteAiVaultSessions.mockResolvedValue(emptyResult()) + + const result = await scanSshAiVaultSessions('dev-box') + + expect(result.issues).toEqual([ + expect.objectContaining({ executionHostId: 'ssh:dev-box', message: 'relay method exploded' }) + ]) + }) + + it('still propagates a caller cancellation', async () => { + const controller = new AbortController() + requestActiveSshAiVaultSessionList.mockResolvedValue(null) + scanRemoteAiVaultSessions.mockImplementation(() => new Promise(() => {})) + + const result = scanSshAiVaultSessions('dev-box', undefined, { + signal: controller.signal, + timeoutMs: 5_000 + }) + await vi.waitFor(() => expect(scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1)) + controller.abort() + + await expect(result).rejects.toMatchObject({ name: 'AbortError' }) + }) +}) + +function emptyResult(): AiVaultListResult { + return { sessions: [], issues: [], scannedAt: '2026-08-02T00:00:00.000Z' } +} + +/** Mirrors the multiplexer's typed timeout: the leg branches on the code, not + * on the message text, so a look-alike message must not take that branch. */ +function relayTimeoutError(): Error { + return Object.assign(new Error('Request "aiVault.listSessions" timed out after 15000ms'), { + code: SSH_MUX_REQUEST_TIMEOUT_CODE + }) +} + +// Relay rows are re-validated before they are trusted, so this has to satisfy +// the full session schema rather than a partial stub. +function remoteSession(): AiVaultSession { + return { + id: 'ssh:dev-box:codex:remote-session:/home/dev/remote-session.jsonl', + executionHostId: 'ssh:dev-box', + agent: 'codex', + sessionId: 'remote-session', + title: 'remote-session', + cwd: '/home/dev/repo', + branch: null, + model: null, + filePath: '/home/dev/remote-session.jsonl', + codexHome: null, + createdAt: null, + updatedAt: '2026-08-02T00:00:00.000Z', + modifiedAt: '2026-08-02T00:00:00.000Z', + messageCount: 1, + totalTokens: 0, + previewMessages: [], + queuedMessageCount: 0, + subagentTranscriptCount: 0, + resumeCommand: 'codex resume remote-session', + subagent: null + } +} diff --git a/src/main/ai-vault/ssh-session-list.ts b/src/main/ai-vault/ssh-session-list.ts new file mode 100644 index 00000000000..7a02883f812 --- /dev/null +++ b/src/main/ai-vault/ssh-session-list.ts @@ -0,0 +1,241 @@ +import { + AI_VAULT_SCOPE_PATHS_MAX_COUNT, + type AiVaultListArgs, + type AiVaultListResult, + type AiVaultScanIssue +} from '../../shared/ai-vault-types' +import { toSshExecutionHostId } from '../../shared/execution-host' +import { + getSshFilesystemProvider, + SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE +} from '../providers/ssh-filesystem-dispatch' +import { getActiveSshAiVaultHostInfo, requestActiveSshAiVaultSessionList } from '../ipc/ssh' +import { isSshMuxRequestTimeoutError } from '../ssh/ssh-channel-multiplexer' +import { createAiVaultScanCancelledError } from './ai-vault-scan-cancellation' +import { scanRemoteAiVaultSessions } from './remote-session-scanner' +import { parseAiVaultListResult } from './session-list-result-validation' +import { aiVaultScanIssueResult, restampAiVaultListResult } from './session-list-results' + +/** Bounds one SSH host leg. `relayTimeoutMs` caps the relay round trip alone; + * `timeoutMs` caps the whole leg, including the legacy filesystem crawl. */ +export type SshAiVaultScanBudget = { + signal?: AbortSignal + timeoutMs?: number + relayTimeoutMs?: number +} + +// Why: a relay that was given a real scan budget and still timed out will not +// answer faster over the slower filesystem crawl, so that leg reports a host +// issue. A relay cut short below this never got a fair attempt — those fall +// back rather than emptying a healthy host's sessions (#12178 follow-up). +const MEANINGFUL_RELAY_SCAN_ATTEMPT_MS = 10_000 + +export async function scanSshAiVaultSessions( + targetId: string, + args?: AiVaultListArgs, + options: SshAiVaultScanBudget = {} +): Promise { + const executionHostId = toSshExecutionHostId(targetId) + // Why: in `all` scope every host leg is awaited together, so an unexpected + // throw here (not a caller cancellation) would discard the local results too. + try { + return await scanOneSshHost(targetId, executionHostId, args, options) + } catch (error) { + if (isAbortError(error)) { + throw error + } + return sshScanIssueResult(executionHostId, targetId, errorMessage(error)) + } +} + +async function scanOneSshHost( + targetId: string, + executionHostId: `ssh:${string}`, + args: AiVaultListArgs | undefined, + options: SshAiVaultScanBudget +): Promise { + const startedAt = Date.now() + // Both legs scan the same capped set, so the fallback can't quietly scan more + // paths — or skip the truncation notice — than the relay leg would. + const scopePaths = args?.scopePaths?.slice(0, AI_VAULT_SCOPE_PATHS_MAX_COUNT) + const scopePathsTruncated = (args?.scopePaths?.length ?? 0) > AI_VAULT_SCOPE_PATHS_MAX_COUNT + let relayError: unknown + const relayTimeoutMs = options.relayTimeoutMs ?? options.timeoutMs + try { + const params = { + limit: args?.limit, + ...(args?.unlimited === true ? { unlimited: true } : {}), + ...(args?.force === true ? { force: true } : {}), + scopePaths, + ...(scopePathsTruncated ? { scopePathsTruncated: true } : {}) + } + const relayResult = + options.signal || relayTimeoutMs !== undefined + ? await requestActiveSshAiVaultSessionList(targetId, params, { + signal: options.signal, + timeoutMs: relayTimeoutMs + }) + : await requestActiveSshAiVaultSessionList(targetId, params) + if (relayResult !== null) { + return restampAiVaultListResult(parseAiVaultListResult(relayResult), executionHostId) + } + } catch (error) { + if (isAbortError(error)) { + throw error + } + if ( + isSshMuxRequestTimeoutError(error) && + (relayTimeoutMs === undefined || relayTimeoutMs >= MEANINGFUL_RELAY_SCAN_ATTEMPT_MS) + ) { + return sshScanIssueResult(executionHostId, targetId, errorMessage(error)) + } + relayError = error + } + const hostInfo = getActiveSshAiVaultHostInfo(targetId) + const provider = getSshFilesystemProvider(targetId) + if (!hostInfo || !provider) { + return sshScanIssueResult( + executionHostId, + targetId, + relayError ? errorMessage(relayError) : SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE + ) + } + // Why: `timeoutMs` bounded only the relay round trip, so a host on a relay + // without the list method fell through to the unbounded desktop crawl and one + // stalled SSH file stream could hold every other host's results hostage. + const fallbackResult = await scanRemoteSessionsWithinBudget({ + scan: (signal) => + scanRemoteAiVaultSessions({ + provider, + executionHostId, + remoteHome: hostInfo.remoteHome, + hostPlatform: hostInfo.hostPlatform, + limit: args?.limit, + unlimited: args?.unlimited, + scopePaths, + signal + }), + signal: options.signal, + remainingMs: remainingScanBudgetMs(options.timeoutMs, startedAt) + }) + if (!fallbackResult) { + return sshScanIssueResult( + executionHostId, + targetId, + `Agent Session History scan timed out after ${options.timeoutMs}ms on this SSH host.` + ) + } + const scopeIssues = scopePathsTruncated + ? [scopeTruncationIssue(executionHostId, hostInfo.remoteHome)] + : [] + // An empty remote home and "the relay method failed and the crawl found + // nothing" look identical, so a fallback that recovered nothing still reports + // the relay error instead of presenting a broken relay as an empty host. + if (!relayError || fallbackResult.sessions.length > 0) { + return { ...fallbackResult, issues: [...fallbackResult.issues, ...scopeIssues] } + } + return { + ...fallbackResult, + issues: [ + ...sshScanIssueResult(executionHostId, targetId, errorMessage(relayError)).issues, + ...fallbackResult.issues, + ...scopeIssues + ] + } +} + +/** Budget left for the legacy crawl after the relay attempt spent part of it. */ +function remainingScanBudgetMs(timeoutMs: number | undefined, startedAt: number): number | null { + if (timeoutMs === undefined) { + return null + } + return Math.max(0, timeoutMs - (Date.now() - startedAt)) +} + +/** Runs the legacy crawl under `remainingMs`; resolves null once the budget is + * spent. Caller cancellation still propagates as an AbortError. */ +async function scanRemoteSessionsWithinBudget(args: { + scan: (signal?: AbortSignal) => Promise + signal?: AbortSignal + remainingMs: number | null +}): Promise { + const remainingMs = args.remainingMs + if (remainingMs === null) { + return args.scan(args.signal) + } + if (args.signal?.aborted) { + throw createAiVaultScanCancelledError() + } + if (remainingMs === 0) { + return null + } + const controller = new AbortController() + return new Promise((resolve, reject) => { + let settled = false + const finish = (settle: () => void): void => { + if (settled) { + return + } + settled = true + clearTimeout(timer) + args.signal?.removeEventListener('abort', onCallerAbort) + settle() + } + const onCallerAbort = (): void => { + controller.abort() + finish(() => reject(createAiVaultScanCancelledError())) + } + const timer = setTimeout(() => { + controller.abort() + finish(() => resolve(null)) + }, remainingMs) + args.signal?.addEventListener('abort', onCallerAbort, { once: true }) + if (args.signal?.aborted) { + onCallerAbort() + return + } + try { + const scan = args.scan(controller.signal) + // The SSH provider may ignore abort; observe any eventual rejection after + // this caller has already returned its timeout or cancellation result. + void scan.then( + (result) => finish(() => resolve(result)), + (error: unknown) => finish(() => reject(error)) + ) + } catch (error) { + finish(() => reject(error)) + } + }) +} + +// Mirrors the notice the relay leg appends so both legs report the same cap. +function scopeTruncationIssue( + executionHostId: `ssh:${string}`, + remoteHome: string +): AiVaultScanIssue { + return { + executionHostId, + agent: 'codex', + kind: 'scope', + path: remoteHome, + message: `Only the first ${AI_VAULT_SCOPE_PATHS_MAX_COUNT} project paths were scanned.` + } +} + +function sshScanIssueResult( + executionHostId: `ssh:${string}`, + targetId: string, + message: string +): AiVaultListResult { + return aiVaultScanIssueResult({ executionHostId, path: targetId, message }) +} + +function isAbortError(error: unknown): boolean { + return error instanceof Error && error.name === 'AbortError' +} + +function errorMessage(error: unknown): string { + return error instanceof Error + ? error.message + : 'Agent Session History scan failed on the SSH target.' +} diff --git a/src/main/attribution/terminal-attribution-path-env-casing.test.ts b/src/main/attribution/terminal-attribution-path-env-casing.test.ts new file mode 100644 index 00000000000..95ff6fdc2e3 --- /dev/null +++ b/src/main/attribution/terminal-attribution-path-env-casing.test.ts @@ -0,0 +1,169 @@ +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { applyTerminalAttributionEnv } from './terminal-attribution' + +describe('applyTerminalAttributionEnv PATH key casing', () => { + let tmpRoot: string | null = null + + afterEach(() => { + if (tmpRoot) { + rmSync(tmpRoot, { force: true, recursive: true }) + tmpRoot = null + } + }) + + function makeTmpRoot(): string { + tmpRoot = mkdtempSync(join(tmpdir(), 'orca-attribution-path-casing-')) + return tmpRoot + } + + // Why: a Windows child that inherits both spellings crashes the packaged orca.exe launcher + // with "Item has already been added. Key in dictionary: 'PATH'" (stablyai/orca#12046). + function pathEnvKeys(env: Record): string[] { + return Object.keys(env).filter((key) => /^path$/i.test(key)) + } + + it('writes back the inherited Windows `Path` spelling instead of adding `PATH`', () => { + const root = makeTmpRoot() + const userDataPath = join(root, 'user-data') + const baseEnv: Record = { + Path: 'C:\\Windows\\system32;C:\\Program Files\\Git\\cmd', + SystemRoot: 'C:\\Windows' + } + + applyTerminalAttributionEnv(baseEnv, { + enabled: true, + platform: 'win32', + shellFamily: 'native-windows', + userDataPath + }) + + const win32Dir = join(userDataPath, 'orca-terminal-attribution', 'win32') + const pathEntries = baseEnv.Path.split(';') + + expect(pathEnvKeys(baseEnv)).toEqual(['Path']) + expect(pathEntries[0]).toBe(win32Dir) + expect(pathEntries).toContain('C:\\Program Files\\Git\\cmd') + }) + + // Why: Win32 resolves a duplicated variable by taking the first match in the block, so the + // shim must land on the first-listed spelling and the shadowed one must keep its value — + // dropping it would promote it the moment anything downstream removes the live key. + it.each([ + { first: 'PATH', second: 'Path' }, + { first: 'Path', second: 'PATH' } + ])( + 'prepends the shim onto the first-listed `$first` and leaves `$second` untouched', + ({ first, second }) => { + const root = makeTmpRoot() + const userDataPath = join(root, 'user-data') + const baseEnv: Record = { + [first]: 'C:\\tools\\bin;C:\\Windows\\system32', + [second]: 'C:\\Windows\\system32' + } + + applyTerminalAttributionEnv(baseEnv, { + enabled: true, + platform: 'win32', + shellFamily: 'native-windows', + userDataPath + }) + + const win32Dir = join(userDataPath, 'orca-terminal-attribution', 'win32') + expect(baseEnv[first].split(';')).toEqual([ + win32Dir, + 'C:\\tools\\bin', + 'C:\\Windows\\system32' + ]) + expect(baseEnv[second]).toBe('C:\\Windows\\system32') + } + ) + + it('keeps a shadowed duplicate when the live spelling strips down to nothing', () => { + const root = makeTmpRoot() + const userDataPath = join(root, 'user-data') + const shimDir = join(userDataPath, 'orca-terminal-attribution', 'win32') + const baseEnv: Record = { Path: shimDir, PATH: 'C:\\Windows\\system32' } + + applyTerminalAttributionEnv(baseEnv, { + enabled: false, + platform: 'win32', + shellFamily: 'native-windows', + userDataPath + }) + + expect(pathEnvKeys(baseEnv)).toEqual(['PATH']) + expect(baseEnv.PATH).toBe('C:\\Windows\\system32') + }) + + it('strips shim entries from the inherited `Path` when attribution is disabled', () => { + const root = makeTmpRoot() + const userDataPath = join(root, 'user-data') + const shimDir = join(userDataPath, 'orca-terminal-attribution', 'win32') + const baseEnv: Record = { Path: `${shimDir};C:\\Windows\\system32` } + + applyTerminalAttributionEnv(baseEnv, { + enabled: false, + platform: 'win32', + shellFamily: 'native-windows', + userDataPath + }) + + expect(pathEnvKeys(baseEnv)).toEqual(['Path']) + expect(baseEnv.Path).toBe('C:\\Windows\\system32') + }) + + // Why: the daemon receives a sparse env patch with no path key and re-merges its own block + // underneath it, so guessing the spelling here hands the child both. + it.each([ + { hostKey: 'PATH', otherKey: 'Path' }, + { hostKey: 'Path', otherKey: 'PATH' } + ])('adopts a host block spelt `$hostKey` on a path-less env', ({ hostKey, otherKey }) => { + const root = makeTmpRoot() + const userDataPath = join(root, 'user-data') + const inherited = { PATH: process.env.PATH, Path: process.env.Path } + delete process.env.PATH + delete process.env.Path + process.env[hostKey] = 'C:\\Windows\\system32' + + try { + const baseEnv: Record = { SystemRoot: 'C:\\Windows' } + + applyTerminalAttributionEnv(baseEnv, { + enabled: true, + platform: 'win32', + shellFamily: 'native-windows', + userDataPath + }) + + expect(pathEnvKeys(baseEnv)).toEqual([hostKey]) + expect(baseEnv[otherKey]).toBeUndefined() + } finally { + delete process.env[hostKey] + for (const [key, value] of Object.entries(inherited)) { + if (value !== undefined) { + process.env[key] = value + } + } + } + }) + + it('leaves a case-sensitive POSIX `Path` variable alone', () => { + const root = makeTmpRoot() + const baseEnv: Record = { + PATH: '/usr/bin:/bin', + Path: '/decoy' + } + + applyTerminalAttributionEnv(baseEnv, { + enabled: true, + platform: 'linux', + userDataPath: join(root, 'user-data') + }) + + expect(baseEnv.Path).toBe('/decoy') + expect(baseEnv.PATH.split(':')).toContain('/usr/bin') + }) +}) diff --git a/src/main/attribution/terminal-attribution.ts b/src/main/attribution/terminal-attribution.ts index d1c4dd099fe..136a01b82f2 100644 --- a/src/main/attribution/terminal-attribution.ts +++ b/src/main/attribution/terminal-attribution.ts @@ -5,6 +5,7 @@ instead of scattering generated shell fragments across files. */ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' import { join, win32 as pathWin32 } from 'node:path' import { ORCA_GIT_COMMIT_TRAILER } from '../../shared/orca-attribution' +import { resolvePathEnvKey } from '../pty/windows-environment-path' const ATTRIBUTION_ROOT_DIR = 'orca-terminal-attribution' const ATTRIBUTION_SHIM_VERSION = '6' @@ -73,7 +74,8 @@ export function applyTerminalAttributionEnv( } const pathDelimiter = platform === 'win32' ? ';' : ':' - const basePath = baseEnv.PATH ?? process.env.PATH ?? '' + const pathKey = resolvePathEnvKey(baseEnv, platform) + const basePath = baseEnv[pathKey] ?? process.env[pathKey] ?? '' // Why: resolve real Windows commands before prepending shims so cmd wrappers // cannot recursively point ORCA_REAL_* at themselves. const resolvedGit = platform === 'win32' ? resolveWindowsExecutable('git', basePath) : null @@ -102,7 +104,7 @@ export function applyTerminalAttributionEnv( // shim directory here keeps the attribution behavior scoped to Orca's live // terminal environment instead of mutating global git/gh config or the // user's external shell PATH. - baseEnv.PATH = [...prependDirs, cleanedBasePath].filter(Boolean).join(pathDelimiter) + baseEnv[pathKey] = [...prependDirs, cleanedBasePath].filter(Boolean).join(pathDelimiter) baseEnv.ORCA_ENABLE_GIT_ATTRIBUTION = '1' baseEnv.ORCA_GIT_COMMIT_TRAILER = ORCA_GIT_COMMIT_TRAILER baseEnv.ORCA_GH_PR_FOOTER = ORCA_GH_FOOTER @@ -131,11 +133,12 @@ function clearTerminalAttributionEnv( delete baseEnv[key] } const pathDelimiter = platform === 'win32' ? ';' : ':' - const cleanedPath = stripAttributionPathEntries(baseEnv.PATH ?? '', pathDelimiter) + const pathKey = resolvePathEnvKey(baseEnv, platform) + const cleanedPath = stripAttributionPathEntries(baseEnv[pathKey] ?? '', pathDelimiter) if (cleanedPath) { - baseEnv.PATH = cleanedPath + baseEnv[pathKey] = cleanedPath } else { - delete baseEnv.PATH + delete baseEnv[pathKey] } } diff --git a/src/main/browser/browser-cookie-import.test.ts b/src/main/browser/browser-cookie-import.test.ts index 55fae27c93e..657215a6fbc 100644 --- a/src/main/browser/browser-cookie-import.test.ts +++ b/src/main/browser/browser-cookie-import.test.ts @@ -223,6 +223,35 @@ describe('importCookiesFromFile', () => { expect(firstCall.sameSite).toBe('lax') }) + it('sets __Host- cookies host-only so Chromium does not reject them', async () => { + const filePath = writeCookieFile([ + { + domain: 'github.com', + name: '__Host-user_session_same_site', + value: 'sess', + path: '/account', + secure: true, + httpOnly: true, + sameSite: 'lax' + }, + { domain: '.github.com', name: '_gh_sess', value: 'abc', path: '/settings', secure: true } + ]) + + const result = await importCookiesFromFile(filePath, 'persist:test') + expect(result.ok).toBe(true) + + const hostCall = cookiesSetMock.mock.calls + .map((c) => c[0]) + .find((c) => c.name === '__Host-user_session_same_site') + // __Host- prefix requires no Domain attribute and path=/, or Chromium drops it. + expect(hostCall).not.toHaveProperty('domain') + expect(hostCall.path).toBe('/') + + const normalCall = cookiesSetMock.mock.calls.map((c) => c[0]).find((c) => c.name === '_gh_sess') + expect(normalCall.domain).toBe('.github.com') + expect(normalCall.path).toBe('/settings') + }) + it('rejects non-JSON files', async () => { const filePath = join(tmpDir, 'bad.json') writeFileSync(filePath, 'not json at all') diff --git a/src/main/browser/browser-cookie-import.ts b/src/main/browser/browser-cookie-import.ts index 22b891cd2a0..23bdd248777 100644 --- a/src/main/browser/browser-cookie-import.ts +++ b/src/main/browser/browser-cookie-import.ts @@ -567,12 +567,14 @@ async function importValidatedCookies( for (const cookie of cookies) { try { + // Why: Chromium rejects __Host- cookies unless they omit domain and use path=/. + const isHostPrefixed = cookie.name.startsWith('__Host-') await targetSession.cookies.set({ url: cookie.url, name: cookie.name, value: stripNonPrintable(cookie.value), - domain: cookie.domain, - path: cookie.path, + ...(isHostPrefixed ? {} : { domain: cookie.domain }), + path: isHostPrefixed ? '/' : cookie.path, secure: cookie.secure, httpOnly: cookie.httpOnly, sameSite: cookie.sameSite, diff --git a/src/main/cli/cli-installer.ts b/src/main/cli/cli-installer.ts index 9c120c230bc..e8ca10f7c44 100644 --- a/src/main/cli/cli-installer.ts +++ b/src/main/cli/cli-installer.ts @@ -17,6 +17,7 @@ import { homedir } from 'node:os' import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path' import { promisify } from 'node:util' import type { CliInstallMethod, CliInstallStatus } from '../../shared/cli-install-types' +import { expandWindowsEnvironmentVariables } from '../../shared/windows-environment-expansion' import { buildAppImageCliWrapper } from './appimage-cli-wrapper' import { invalidateWindowsUserPathRegistryCache, @@ -1087,13 +1088,6 @@ function normalizeWindowsPath( .toLowerCase() } -function expandWindowsEnvironmentVariables(value: string, env: NodeJS.ProcessEnv): string { - return value.replace(/%([^%]+)%/g, (match, rawName: string) => { - const envKey = Object.keys(env).find((key) => key.toLowerCase() === rawName.toLowerCase()) - return envKey && env[envKey] ? env[envKey] : match - }) -} - function escapeWindowsBatchValue(value: string): string { return value.replaceAll('"', '""') } diff --git a/src/main/cli/windows-launcher-asset.test.ts b/src/main/cli/windows-launcher-asset.test.ts index f491cb0771d..2eec4fee577 100644 --- a/src/main/cli/windows-launcher-asset.test.ts +++ b/src/main/cli/windows-launcher-asset.test.ts @@ -16,12 +16,15 @@ describe('packaged Windows CLI launcher asset', () => { const sourcePath = join(process.cwd(), 'native', 'windows-cli-launcher', 'OrcaCliLauncher.cs') const source = readFileSync(sourcePath, 'utf8') + // Why: the marker and command name must ride the launcher's own environment, never + // ProcessStartInfo's case-insensitive copy of a PATH/Path block (stablyai/orca#12046). expect(source).toContain( - 'startInfo.EnvironmentVariables["ORCA_WINDOWS_PACKAGED_CLI_LAUNCHER"] = "1";' + 'Environment.SetEnvironmentVariable("ORCA_WINDOWS_PACKAGED_CLI_LAUNCHER", "1");' ) - expect(source).toContain('Environment.GetEnvironmentVariable("ORCA_CLI_COMMAND") == "orca-ide"') - expect(source).toContain('? "orca-ide"') - expect(source).toContain(': "orca";') + expect(source).toContain( + 'string requestedCliCommand = Environment.GetEnvironmentVariable("ORCA_CLI_COMMAND");' + ) + expect(source).toContain('requestedCliCommand == "orca-ide" ? "orca-ide" : "orca"') expect(source).toContain('child.WaitForExit();') expect(source).toContain('return child.ExitCode;') }) diff --git a/src/main/codex-accounts/codex-credential-absence-grace.test.ts b/src/main/codex-accounts/codex-credential-absence-grace.test.ts new file mode 100644 index 00000000000..6672bb7676a --- /dev/null +++ b/src/main/codex-accounts/codex-credential-absence-grace.test.ts @@ -0,0 +1,65 @@ +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { + CODEX_CREDENTIAL_ABSENCE_GRACE_MS, + CodexCredentialAbsenceGrace +} from './codex-credential-absence-grace' + +const VALID_AUTH = JSON.stringify({ + auth_mode: 'chatgpt', + tokens: { access_token: 'a', id_token: 'b', refresh_token: 'c' } +}) + +describe('CodexCredentialAbsenceGrace', () => { + let dir = '' + let authPath = '' + + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), 'codex-absence-grace-')) + authPath = join(dir, 'auth.json') + }) + + afterEach(() => { + rmSync(dir, { recursive: true, force: true }) + }) + + it('treats a torn mid-write read as transient until it outlives the grace window', () => { + const grace = new CodexCredentialAbsenceGrace() + writeFileSync(authPath, '{"tokens":{"acc', 'utf-8') + + expect(grace.assess(authPath, 1_000)).toEqual({ state: 'unreadable', durable: false }) + expect(grace.assess(authPath, 1_000 + CODEX_CREDENTIAL_ABSENCE_GRACE_MS - 1)).toEqual({ + state: 'unreadable', + durable: false + }) + expect(grace.assess(authPath, 1_000 + CODEX_CREDENTIAL_ABSENCE_GRACE_MS)).toEqual({ + state: 'unreadable', + durable: true + }) + }) + + it('clears the absence clock when a transient failure heals', () => { + const grace = new CodexCredentialAbsenceGrace() + writeFileSync(authPath, '{"tokens":{"acc', 'utf-8') + expect(grace.assess(authPath, 1_000).durable).toBe(false) + + writeFileSync(authPath, VALID_AUTH, 'utf-8') + expect(grace.assess(authPath, 2_000)).toEqual({ state: 'present', durable: true }) + + // A later absence starts a fresh grace window instead of inheriting the old clock. + rmSync(authPath) + expect(grace.assess(authPath, 100_000)).toEqual({ state: 'missing', durable: false }) + expect(grace.assess(authPath, 100_000 + CODEX_CREDENTIAL_ABSENCE_GRACE_MS)).toEqual({ + state: 'missing', + durable: true + }) + }) + + it('reports settled credential-free JSON as durable immediately', () => { + const grace = new CodexCredentialAbsenceGrace() + writeFileSync(authPath, '{}', 'utf-8') + expect(grace.assess(authPath, 1_000)).toEqual({ state: 'no-credential', durable: true }) + }) +}) diff --git a/src/main/codex-accounts/codex-credential-absence-grace.ts b/src/main/codex-accounts/codex-credential-absence-grace.ts new file mode 100644 index 00000000000..e6572297ac3 --- /dev/null +++ b/src/main/codex-accounts/codex-credential-absence-grace.ts @@ -0,0 +1,46 @@ +import { existsSync } from 'node:fs' +import { dirname } from 'node:path' +import { normalizeRuntimePathForComparison } from '../../shared/cross-platform-path' +import { + readStoredCodexCredentialState, + type StoredCodexCredentialState +} from './managed-codex-auth-readiness' + +export const CODEX_CREDENTIAL_ABSENCE_GRACE_MS = 5_000 + +export type CodexCredentialAbsenceVerdict = { + state: StoredCodexCredentialState + /** For 'missing'/'unreadable': true once the absence outlived the grace window. */ + durable: boolean +} + +// Why: codex rotates auth.json in place, so one missing/unreadable read can be +// a write in progress. Deselecting the managed account on that snapshot logs +// the user out over a race; absence must persist across a grace window first. +// Valid JSON (with or without a credential) is a settled file and needs none. +export class CodexCredentialAbsenceGrace { + private readonly firstAbsenceAtByPath = new Map() + + constructor(private readonly graceMs = CODEX_CREDENTIAL_ABSENCE_GRACE_MS) {} + + assess(authPath: string, now = Date.now()): CodexCredentialAbsenceVerdict { + const state = readStoredCodexCredentialState(authPath) + const key = normalizeRuntimePathForComparison(authPath) + if (state === 'present' || state === 'incomplete' || state === 'no-credential') { + this.firstAbsenceAtByPath.delete(key) + return { state, durable: true } + } + // Why: rotation replaces auth.json inside an existing home; the home + // directory itself being gone is structural, not a write in flight. + if (state === 'missing' && !existsSync(dirname(authPath))) { + this.firstAbsenceAtByPath.delete(key) + return { state, durable: true } + } + const firstAbsenceAt = this.firstAbsenceAtByPath.get(key) + if (firstAbsenceAt === undefined) { + this.firstAbsenceAtByPath.set(key, now) + return { state, durable: false } + } + return { state, durable: now - firstAbsenceAt >= this.graceMs } + } +} diff --git a/src/main/codex-accounts/managed-codex-auth-readiness.test.ts b/src/main/codex-accounts/managed-codex-auth-readiness.test.ts index f32bfbd153d..4de1da70396 100644 --- a/src/main/codex-accounts/managed-codex-auth-readiness.test.ts +++ b/src/main/codex-accounts/managed-codex-auth-readiness.test.ts @@ -4,7 +4,10 @@ import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' import type { CodexManagedAccount, GlobalSettings } from '../../shared/types' -import { waitForManagedCodexAuthReady } from './managed-codex-auth-readiness' +import { + readStoredCodexCredentialState, + waitForManagedCodexAuthReady +} from './managed-codex-auth-readiness' const roots: string[] = [] const testIdToken = 'e30.eyJlbWFpbCI6InVzZXJAZXhhbXBsZS5jb20ifQ.sig' @@ -87,6 +90,7 @@ describe('waitForManagedCodexAuthReady', () => { writeAuth(fixture.home, { tokens: { access_token: 'access', id_token: testIdToken } }) + expect(readStoredCodexCredentialState(join(fixture.home, 'auth.json'))).toBe('incomplete') let resolved = false const readiness = waitForManagedCodexAuthReady(fixture.args) void readiness?.then(() => { @@ -101,6 +105,16 @@ describe('waitForManagedCodexAuthReady', () => { await expect(readiness).resolves.toBe(true) }) + it('does not treat empty ChatGPT token fields as credential material', () => { + const fixture = createFixture() + writeAuth(fixture.home, { + auth_mode: 'chatgpt', + tokens: { access_token: '', id_token: '', refresh_token: '' } + }) + + expect(readStoredCodexCredentialState(join(fixture.home, 'auth.json'))).toBe('no-credential') + }) + it('waits for an empty managed ChatGPT refresh token to be restored', async () => { vi.useFakeTimers() const fixture = createFixture() diff --git a/src/main/codex-accounts/managed-codex-auth-readiness.ts b/src/main/codex-accounts/managed-codex-auth-readiness.ts index 4c9f28eec70..5b7938ea30c 100644 --- a/src/main/codex-accounts/managed-codex-auth-readiness.ts +++ b/src/main/codex-accounts/managed-codex-auth-readiness.ts @@ -85,19 +85,48 @@ function isManagedHostCodexHome( ) } -export function hasStoredCodexCredential(authPath: string): boolean { +export type StoredCodexCredentialState = + | 'present' + | 'incomplete' + | 'missing' + | 'unreadable' + | 'no-credential' + +// Why: callers deciding whether to deselect an account must tell a settled +// logout ('no-credential') apart from a rotation in progress ('unreadable') or +// an absent file ('missing') — collapsing them to false logs users out on races. +export function readStoredCodexCredentialState(authPath: string): StoredCodexCredentialState { + let raw: string try { - const parsed: unknown = JSON.parse(readFileSync(authPath, 'utf8')) - if (!isRecord(parsed) || Object.keys(parsed).length === 0) { - return false - } - const auth = parsed as StoredCodexAuth - return auth.auth_mode == null + raw = readFileSync(authPath, 'utf8') + } catch (error) { + const code = (error as NodeJS.ErrnoException).code + // Why: Windows auth.json rotation can surface transient EPERM/EBUSY reads. + return code === 'ENOENT' || code === 'ENOTDIR' ? 'missing' : 'unreadable' + } + let parsed: unknown + try { + parsed = JSON.parse(raw) + } catch { + // Torn JSON means a write is in flight, not that the credential is gone. + return 'unreadable' + } + if (!isRecord(parsed) || Object.keys(parsed).length === 0) { + return 'no-credential' + } + const auth = parsed as StoredCodexAuth + const hasCredential = + auth.auth_mode == null ? hasCredentialWithoutDeclaredMode(auth) : hasCredentialForDeclaredMode(auth) - } catch { - return false + if (hasCredential) { + return 'present' } + return hasIncompleteCredentialMaterial(auth) ? 'incomplete' : 'no-credential' +} + +export function hasStoredCodexCredential(authPath: string): boolean { + return readStoredCodexCredentialState(authPath) === 'present' } function hasCredentialForDeclaredMode(auth: StoredCodexAuth): boolean { @@ -135,6 +164,10 @@ function hasCredentialWithoutDeclaredMode(auth: StoredCodexAuth): boolean { return Object.keys(auth).some((key) => key !== 'auth_mode' && key !== 'last_refresh') } +function hasIncompleteCredentialMaterial(auth: StoredCodexAuth): boolean { + return hasChatGptTokenMaterial(auth.tokens) || hasAgentIdentityMaterial(auth.agent_identity) +} + function isNonEmptyString(value: unknown): value is string { return typeof value === 'string' && value.trim().length > 0 } @@ -166,6 +199,17 @@ function hasBedrockApiKey(value: unknown): boolean { return isRecord(value) && isNonEmptyString(value.api_key) } +function hasChatGptTokenMaterial(tokens: unknown): boolean { + return ( + isRecord(tokens) && + [tokens.access_token, tokens.id_token, tokens.refresh_token].some(isNonEmptyString) + ) +} + +function hasAgentIdentityMaterial(value: unknown): boolean { + return isNonEmptyString(value) || (isRecord(value) && Object.values(value).some(isNonEmptyString)) +} + function isRecord(value: unknown): value is Record { return value !== null && typeof value === 'object' && !Array.isArray(value) } diff --git a/src/main/codex-accounts/runtime-home-service.test.ts b/src/main/codex-accounts/runtime-home-service.test.ts index d1a8b1bed0d..d4ab194705d 100644 --- a/src/main/codex-accounts/runtime-home-service.test.ts +++ b/src/main/codex-accounts/runtime-home-service.test.ts @@ -383,6 +383,90 @@ describe('CodexRuntimeHomeService', () => { ).toBe(false) }) + it('deselects a shared-home account on settled credential-free JSON', async () => { + const systemAuth = createCodexAuthJson('system@example.com', 'acct-system', 'system') + const managedAuth = createCodexAuthJson('user@example.com', 'acct-user', 'managed') + writeFileSync(getSystemCodexAuthPath(), systemAuth, 'utf-8') + const managedHomePath = createManagedAuth(testState.userDataDir, 'account-1', managedAuth) + const store = createStore( + createSettings({ + codexManagedAccounts: [ + { + id: 'account-1', + email: 'user@example.com', + managedHomePath, + providerAccountId: 'acct-user', + workspaceLabel: null, + workspaceAccountId: 'acct-user', + createdAt: 1, + updatedAt: 1, + lastAuthenticatedAt: 1 + } + ], + activeCodexManagedAccountId: 'account-1', + activeCodexManagedAccountIdsByRuntime: { host: 'account-1', wsl: {} } + }) + ) + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const { CodexRuntimeHomeService } = await import('./runtime-home-service') + const service = new CodexRuntimeHomeService(store as never) + store.updateSettings.mockClear() + + writeFileSync(join(managedHomePath, 'auth.json'), '{}\n', 'utf-8') + service.syncForCurrentSelection() + + expect(store.getSettings().activeCodexManagedAccountId).toBeNull() + expect(store.getSettings().activeCodexManagedAccountIdsByRuntime?.host).toBeNull() + expect(readFileSync(join(managedHomePath, 'auth.json'), 'utf-8')).toBe('{}\n') + expect(readFileSync(getRuntimeCodexAuthPath(), 'utf-8')).toBe(systemAuth) + expect(warnSpy).toHaveBeenCalledWith( + '[codex-runtime-home] Active managed account credential is unavailable, restoring system default' + ) + }) + + it('deselects a shared-home account when unreadable auth outlives the grace window', async () => { + const systemAuth = createCodexAuthJson('system@example.com', 'acct-system', 'system') + const managedAuth = createCodexAuthJson('user@example.com', 'acct-user', 'managed') + writeFileSync(getSystemCodexAuthPath(), systemAuth, 'utf-8') + const managedHomePath = createManagedAuth(testState.userDataDir, 'account-1', managedAuth) + const store = createStore( + createSettings({ + codexManagedAccounts: [ + { + id: 'account-1', + email: 'user@example.com', + managedHomePath, + providerAccountId: 'acct-user', + workspaceLabel: null, + workspaceAccountId: 'acct-user', + createdAt: 1, + updatedAt: 1, + lastAuthenticatedAt: 1 + } + ], + activeCodexManagedAccountId: 'account-1', + activeCodexManagedAccountIdsByRuntime: { host: 'account-1', wsl: {} } + }) + ) + vi.spyOn(console, 'warn').mockImplementation(() => {}) + const { CodexRuntimeHomeService } = await import('./runtime-home-service') + const service = new CodexRuntimeHomeService(store as never) + store.updateSettings.mockClear() + writeFileSync(join(managedHomePath, 'auth.json'), '{"tokens":{"acc', 'utf-8') + const observedAt = Date.now() + const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(observedAt) + + service.syncForCurrentSelection() + expect(store.getSettings().activeCodexManagedAccountId).toBe('account-1') + expect(store.updateSettings).not.toHaveBeenCalled() + + nowSpy.mockReturnValue(observedAt + 6_000) + service.syncForCurrentSelection() + nowSpy.mockRestore() + expect(store.getSettings().activeCodexManagedAccountId).toBeNull() + expect(store.getSettings().activeCodexManagedAccountIdsByRuntime?.host).toBeNull() + }) + it('repoints legacy active host CODEX_HOME to the shared runtime home on startup', async () => { const legacyLaunchHomePath = join( testState.userDataDir, @@ -2389,11 +2473,27 @@ describe('CodexRuntimeHomeService', () => { expect(store.updateSettings).not.toHaveBeenCalled() rmSync(join(managedHomePath1, 'auth.json'), { force: true }) + // Why: the first missing read may be a rotation in flight — the selection + // survives the grace window and the launch still targets the account home. + const absenceObservedAt = Date.now() expect( service.prepareForCodexLaunch(undefined, undefined, { unavailableManagedHomePath: managedHomePath1 }) - ).toBeNull() + ).toBe(managedHomePath1) + expect(store.updateSettings).not.toHaveBeenCalled() + + // Once the absence outlives the grace window it is durable and deselects. + const nowSpy = vi.spyOn(Date, 'now').mockImplementation(() => absenceObservedAt + 6_000) + try { + expect( + service.prepareForCodexLaunch(undefined, undefined, { + unavailableManagedHomePath: managedHomePath1 + }) + ).toBeNull() + } finally { + nowSpy.mockRestore() + } expect(store.getSettings().activeCodexManagedAccountId).toBeNull() expect(store.getSettings().activeCodexManagedAccountIdsByRuntime).toEqual({ host: null, @@ -2408,6 +2508,66 @@ describe('CodexRuntimeHomeService', () => { ) }) + it('does not deselect the account when a transient unreadable auth.json heals', async () => { + const systemAuth = createCodexAuthJson('system@example.com', 'acct-system', 'system') + writeFileSync(getSystemCodexAuthPath(), systemAuth, 'utf-8') + const accountAuth = createCodexAuthJson('user@example.com', 'acct-user', 'managed') + const managedHomePath = createManagedAuth(testState.userDataDir, 'account-1', accountAuth) + const store = createStore( + createSettings({ + codexSystemDefaultRealHomeEnabled: true, + codexManagedAccounts: [ + { + id: 'account-1', + email: 'user@example.com', + managedHomePath, + providerAccountId: 'acct-user', + workspaceLabel: null, + workspaceAccountId: 'acct-user', + createdAt: 1, + updatedAt: 1, + lastAuthenticatedAt: 1 + } + ], + activeCodexManagedAccountId: 'account-1', + activeCodexManagedAccountIdsByRuntime: { host: 'account-1', wsl: {} } + }) + ) + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const { CodexRuntimeHomeService } = await import('./runtime-home-service') + const service = new CodexRuntimeHomeService(store as never) + + // A mid-write read observes torn JSON: no deselect, and the launch still + // targets the account home so codex re-reads the settled file itself. + writeFileSync(join(managedHomePath, 'auth.json'), '{"tokens":{"acc', 'utf-8') + expect( + service.prepareForCodexLaunch(undefined, undefined, { + unavailableManagedHomePath: managedHomePath + }) + ).toBe(managedHomePath) + expect(store.getSettings().activeCodexManagedAccountId).toBe('account-1') + expect(store.updateSettings).not.toHaveBeenCalled() + + // The write completes; even past the grace window the selection is intact. + writeFileSync(join(managedHomePath, 'auth.json'), accountAuth, 'utf-8') + const healedAt = Date.now() + const nowSpy = vi.spyOn(Date, 'now').mockImplementation(() => healedAt + 60_000) + try { + expect( + service.prepareForCodexLaunch(undefined, undefined, { + unavailableManagedHomePath: managedHomePath + }) + ).toBe(managedHomePath) + } finally { + nowSpy.mockRestore() + } + expect(store.getSettings().activeCodexManagedAccountId).toBe('account-1') + expect(store.updateSettings).not.toHaveBeenCalled() + expect(warnSpy).not.toHaveBeenCalledWith( + '[codex-runtime-home] Active managed account credential remained unavailable, clearing selection' + ) + }) + it('ignores mismatched runtime auth when the active managed auth is missing', async () => { const runtimeAuthPath = getRuntimeCodexAuthPath() const systemAuth = createCodexAuthJson('system@example.com', 'acct-system', 'system') @@ -4706,11 +4866,11 @@ describe('CodexRuntimeHomeService', () => { it('rejects unverifiable Codex read-back on first sync after restart', async () => { const runtimeAuthPath = getRuntimeCodexAuthPath() - writeFileSync(runtimeAuthPath, '{"tokens":"refreshed-while-down"}\n', 'utf-8') + writeFileSync(runtimeAuthPath, '{"credential":"refreshed-while-down"}\n', 'utf-8') const managedHomePath = createManagedAuth( testState.userDataDir, 'account-1', - '{"tokens":"original"}\n' + '{"credential":"original"}\n' ) const managedAuthPath = join(managedHomePath, 'auth.json') const store = createStore( @@ -4735,8 +4895,8 @@ describe('CodexRuntimeHomeService', () => { const { CodexRuntimeHomeService } = await import('./runtime-home-service') new CodexRuntimeHomeService(store as never) - expect(readFileSync(managedAuthPath, 'utf-8')).toBe('{"tokens":"original"}\n') - expect(readFileSync(runtimeAuthPath, 'utf-8')).toBe('{"tokens":"original"}\n') + expect(readFileSync(managedAuthPath, 'utf-8')).toBe('{"credential":"original"}\n') + expect(readFileSync(runtimeAuthPath, 'utf-8')).toBe('{"credential":"original"}\n') }) it('reads back verified same-account refreshes on first sync after restart', async () => { @@ -4811,12 +4971,12 @@ describe('CodexRuntimeHomeService', () => { const managedHomePath1 = createManagedAuth( testState.userDataDir, 'account-1', - '{"tokens":"account1"}\n' + '{"credential":"account1"}\n' ) const managedHomePath2 = createManagedAuth( testState.userDataDir, 'account-2', - '{"tokens":"account2"}\n' + '{"credential":"account2"}\n' ) const managedAuthPath2 = join(managedHomePath2, 'auth.json') const settings = createSettings({ @@ -4854,8 +5014,8 @@ describe('CodexRuntimeHomeService', () => { settings.activeCodexManagedAccountId = 'account-2' service.syncForCurrentSelection() - expect(readFileSync(managedAuthPath2, 'utf-8')).toBe('{"tokens":"account2"}\n') - expect(readFileSync(runtimeAuthPath, 'utf-8')).toBe('{"tokens":"account2"}\n') + expect(readFileSync(managedAuthPath2, 'utf-8')).toBe('{"credential":"account2"}\n') + expect(readFileSync(runtimeAuthPath, 'utf-8')).toBe('{"credential":"account2"}\n') }) it('does not carry the reauth read-back skip across Codex account switches', async () => { diff --git a/src/main/codex-accounts/runtime-home-service.ts b/src/main/codex-accounts/runtime-home-service.ts index e9256145b77..fac946c51b2 100644 --- a/src/main/codex-accounts/runtime-home-service.ts +++ b/src/main/codex-accounts/runtime-home-service.ts @@ -77,7 +77,7 @@ import { codexAuthMatchesSystemDefaultIdentity } from './codex-auth-identity' import { migrateLegacySharedAuthToPerAccountHome } from './legacy-shared-auth-migration' -import { hasStoredCodexCredential } from './managed-codex-auth-readiness' +import { CodexCredentialAbsenceGrace } from './codex-credential-absence-grace' import { syncLegacySharedCodexConfigForRetainedPanes } from './legacy-shared-config-compatibility' import { hasRecordedLegacySharedCodexPane, @@ -179,6 +179,8 @@ export class CodexRuntimeHomeService { // provenance so a later deselect/rollback never adopts stale shared bytes. private lastHostAccountUsedSelfContainedHome = false private sharedAuthRefreshBlockedByManagedTransition = false + // Why: transient auth.json read/parse failures must not deselect an account. + private readonly credentialAbsenceGrace = new CodexCredentialAbsenceGrace() constructor(private readonly store: Store) { this.safeRecoverInterruptedRuntimeAuthOperation() @@ -307,11 +309,15 @@ export class CodexRuntimeHomeService { if ( unavailableManagedHomePath && normalizeRuntimePathForComparison(unavailableManagedHomePath) === - normalizeRuntimePathForComparison(perAccountHome) && - !hasStoredCodexCredential(join(perAccountHome, 'auth.json')) + normalizeRuntimePathForComparison(perAccountHome) ) { - this.clearSelfContainedManagedSelection(account, 'credential remained unavailable') - return null + const absence = this.credentialAbsenceGrace.assess(join(perAccountHome, 'auth.json')) + if (absence.state !== 'present' && absence.durable) { + this.clearSelfContainedManagedSelection(account, 'credential remained unavailable') + return null + } + // Why: a transient missing/unreadable auth.json is usually codex rotating + // it; keep the selection and launch — the CLI re-reads the settled file. } // Why: link the user's real ~/.codex resources and mirror config into THIS // home (never symlinking into or mutating ~/.codex), so the per-account home @@ -732,11 +738,22 @@ export class CodexRuntimeHomeService { } const activeAuthPath = join(activeAccount.managedHomePath, 'auth.json') - if (!existsSync(activeAuthPath)) { + const authAbsence = this.credentialAbsenceGrace.assess(activeAuthPath) + if (authAbsence.state !== 'present' && authAbsence.state !== 'incomplete') { + if (!authAbsence.durable) { + // Why: mid-rotation reads look missing/unreadable for a moment; skip + // this sync without deselecting and let a settled read decide later. + console.warn( + '[codex-runtime-home] Active managed account auth.json unavailable, keeping selection through grace window' + ) + return + } console.warn( - '[codex-runtime-home] Active managed account is missing auth.json, restoring system default' + '[codex-runtime-home] Active managed account credential is unavailable, restoring system default' ) - if (this.lastSyncedAccountId === activeAccount.id) { + // Why: valid credential-free JSON is an explicit logout; never revive it + // from stale shared-home bytes while clearing the selection. + if (authAbsence.state !== 'no-credential' && this.lastSyncedAccountId === activeAccount.id) { outgoingReadBackResult = this.recoverRefreshForMissingActiveAccount(activeAccount) } this.store.updateSettings({ diff --git a/src/main/codex-cli/codex-home-process-lock.test.ts b/src/main/codex-cli/codex-home-process-lock.test.ts new file mode 100644 index 00000000000..7287d011b42 --- /dev/null +++ b/src/main/codex-cli/codex-home-process-lock.test.ts @@ -0,0 +1,134 @@ +import { join } from 'node:path' +import { homedir } from 'node:os' +import { describe, expect, it } from 'vitest' +import { + resolveCodexHomeProcessLockKey, + resolveCodexHomeProcessLockKeyForSpawnEnv, + withCodexHomeProcessLock +} from './codex-home-process-lock' + +function deferred() { + let resolve!: (value: T) => void + let reject!: (error: unknown) => void + const promise = new Promise((res, rej) => { + resolve = res + reject = rej + }) + return { promise, resolve, reject } +} + +describe('withCodexHomeProcessLock', () => { + it('serializes runs that share a lock key', async () => { + const events: string[] = [] + const firstGate = deferred() + + const first = withCodexHomeProcessLock('home-a', async () => { + events.push('first:start') + await firstGate.promise + events.push('first:end') + return 1 + }) + const second = withCodexHomeProcessLock('home-a', async () => { + events.push('second:start') + return 2 + }) + + await Promise.resolve() + expect(events).toEqual(['first:start']) + + firstGate.resolve() + await expect(first).resolves.toBe(1) + await expect(second).resolves.toBe(2) + expect(events).toEqual(['first:start', 'first:end', 'second:start']) + }) + + it('runs different lock keys concurrently', async () => { + const events: string[] = [] + const firstGate = deferred() + + const first = withCodexHomeProcessLock('home-a', async () => { + events.push('a:start') + await firstGate.promise + }) + const second = withCodexHomeProcessLock('home-b', async () => { + events.push('b:start') + }) + + await second + expect(events).toEqual(['a:start', 'b:start']) + firstGate.resolve() + await first + }) + + it('releases the lock after a rejected run', async () => { + await expect( + withCodexHomeProcessLock('home-a', async () => { + throw new Error('boom') + }) + ).rejects.toThrow('boom') + + await expect(withCodexHomeProcessLock('home-a', async () => 'after')).resolves.toBe('after') + }) + + it('keys explicit and default host homes consistently', () => { + const previousCodexHome = process.env.CODEX_HOME + delete process.env.CODEX_HOME + try { + const defaultKey = resolveCodexHomeProcessLockKey(null) + expect(resolveCodexHomeProcessLockKey(join(homedir(), '.codex'))).toBe(defaultKey) + expect(resolveCodexHomeProcessLockKeyForSpawnEnv(undefined)).toBe(defaultKey) + expect(resolveCodexHomeProcessLockKey('/somewhere/else')).not.toBe(defaultKey) + } finally { + if (previousCodexHome !== undefined) { + process.env.CODEX_HOME = previousCodexHome + } + } + }) + + it('keys a stripped child env to the real default home, not ambient CODEX_HOME', () => { + const previousCodexHome = process.env.CODEX_HOME + process.env.CODEX_HOME = '/nested-orca/managed-home' + try { + expect(resolveCodexHomeProcessLockKeyForSpawnEnv({ PATH: process.env.PATH })).toBe( + resolveCodexHomeProcessLockKey(join(homedir(), '.codex')) + ) + expect(resolveCodexHomeProcessLockKeyForSpawnEnv(undefined)).toBe( + resolveCodexHomeProcessLockKey('/nested-orca/managed-home') + ) + } finally { + if (previousCodexHome === undefined) { + delete process.env.CODEX_HOME + } else { + process.env.CODEX_HOME = previousCodexHome + } + } + }) + + it('keys a WSL UNC probe home and a WSL spawn env to the same lock', () => { + const probeKey = resolveCodexHomeProcessLockKey('\\\\wsl$\\Ubuntu\\home\\user\\.codex') + const spawnKey = resolveCodexHomeProcessLockKeyForSpawnEnv( + { CODEX_HOME: '/home/user/.codex' }, + 'Ubuntu' + ) + expect(spawnKey).toBe(probeKey) + }) + + it('uses the WSL default sentinel when launcher filtering strips an ambient home', () => { + const previousCodexHome = process.env.CODEX_HOME + process.env.CODEX_HOME = '/host-only/codex-home' + try { + const inheritedKey = resolveCodexHomeProcessLockKeyForSpawnEnv( + { CODEX_HOME: '/host-only/codex-home' }, + 'Ubuntu' + ) + const strippedKey = resolveCodexHomeProcessLockKeyForSpawnEnv({}, 'Ubuntu') + expect(inheritedKey).toBe(strippedKey) + } finally { + if (previousCodexHome === undefined) { + delete process.env.CODEX_HOME + } else { + process.env.CODEX_HOME = previousCodexHome + } + } + }) +}) diff --git a/src/main/codex-cli/codex-home-process-lock.ts b/src/main/codex-cli/codex-home-process-lock.ts new file mode 100644 index 00000000000..ef91a5705d9 --- /dev/null +++ b/src/main/codex-cli/codex-home-process-lock.ts @@ -0,0 +1,55 @@ +import { homedir } from 'node:os' +import { join } from 'node:path' +import { normalizeRuntimePathForComparison } from '../../shared/cross-platform-path' + +// Why: Codex OAuth uses rotating refresh tokens stored in each home's auth.json. +// Two Orca-spawned codex processes refreshing the same home concurrently can +// consume one rotation twice and permanently invalidate the stored credential, +// so Orca's own spawns (quota probes, commit-message runs) serialize per home. +// User terminal panes are intentionally not serialized here. + +const lockTails = new Map>() + +export function resolveCodexHomeProcessLockKey(codexHomePath?: string | null): string { + const home = codexHomePath ?? process.env.CODEX_HOME ?? join(homedir(), '.codex') + return normalizeRuntimePathForComparison(home) +} + +export function resolveCodexHomeProcessLockKeyForSpawnEnv( + env: NodeJS.ProcessEnv | undefined, + wslDistro?: string | null +): string { + if (wslDistro) { + // buildWslLauncherEnv forwards only explicit values that differ from the + // host process; all other cases use the distro user's default home. + const codexHome = env?.CODEX_HOME !== process.env.CODEX_HOME ? (env?.CODEX_HOME ?? null) : null + // Why: WSL spawns carry a Linux CODEX_HOME; key it through the same UNC + // normalization the probe's \\wsl$ home path uses so both lanes collide. + // Without an explicit home the distro default is unknowable from the host; + // a sentinel still serializes same-distro default spawns with each other. + return normalizeRuntimePathForComparison( + `//wsl$/${wslDistro}${codexHome ?? '/.orca-default-codex-home'}` + ) + } + // An explicit env is the child's complete environment. If CODEX_HOME was + // deliberately stripped, the child uses ~/.codex regardless of our ambient env. + const codexHome = env === undefined ? process.env.CODEX_HOME : env.CODEX_HOME + return normalizeRuntimePathForComparison(codexHome ?? join(homedir(), '.codex')) +} + +export function withCodexHomeProcessLock(lockKey: string, fn: () => Promise): Promise { + const prior = lockTails.get(lockKey) ?? Promise.resolve() + const run = prior.then(fn) + // Why: keep the queue alive past a failed run so later entrants still start. + const tail = run.then( + () => undefined, + () => undefined + ) + lockTails.set(lockKey, tail) + void tail.then(() => { + if (lockTails.get(lockKey) === tail) { + lockTails.delete(lockKey) + } + }) + return run +} diff --git a/src/main/daemon/daemon-audit-eligibility-event.test.ts b/src/main/daemon/daemon-audit-eligibility-event.test.ts index 52171e14853..13d3e0f39ed 100644 --- a/src/main/daemon/daemon-audit-eligibility-event.test.ts +++ b/src/main/daemon/daemon-audit-eligibility-event.test.ts @@ -4,7 +4,9 @@ import { join } from 'node:path' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { validate } from '../telemetry/validator' import { recordAuthenticatedInventory, type DaemonAuditContext } from './daemon-audit-classifier' +import type { ExactDaemonIncarnation } from './daemon-incarnation-evidence' import { DaemonPtyAdapter } from './daemon-pty-adapter' +import { PROTOCOL_VERSION } from './daemon-protocol-version' import { DaemonServer } from './daemon-server' import { getDaemonSocketPath } from './daemon-spawner' @@ -25,6 +27,16 @@ const context: DaemonAuditContext = { profileScope: '/profile' } +const exactIncarnation: ExactDaemonIncarnation = { + identity: { + pid: 92_847_561, + startedAtMs: 1_786_000_123_456, + launchNonce: 'private-launch-nonce' + }, + linuxStartTicks: '8642097531', + bootId: 'private-boot-id' +} + beforeEach(() => { trackMock.mockReset() }) @@ -42,12 +54,70 @@ describe('daemon audit eligibility telemetry', () => { reason: 'authenticated_inventory', evidence_sources: ['authenticated_inventory'], protocol_generation: 23, + generation_role: 'legacy', exact_incarnation: 'unavailable', process_reason: null }) + expect(props).not.toHaveProperty('exact_incarnation_correlation') expect(validate('daemon_audit_eligibility', props).ok).toBe(true) }) + it('correlates an exact incarnation across app trackers without raw identity fields', () => { + const currentContext = { ...context, protocolGeneration: PROTOCOL_VERSION } + const firstAppTracker = createDaemonAuditEligibilityTracker() + const secondAppTracker = createDaemonAuditEligibilityTracker() + + firstAppTracker(recordAuthenticatedInventory(currentContext, exactIncarnation)) + secondAppTracker(recordAuthenticatedInventory(currentContext, exactIncarnation)) + secondAppTracker( + recordAuthenticatedInventory(currentContext, { + ...exactIncarnation, + identity: { ...exactIncarnation.identity, launchNonce: 'another-private-launch-nonce' } + }) + ) + + const firstProperties = trackMock.mock.calls[0][1] + const secondProperties = trackMock.mock.calls[1][1] + const replacementProperties = trackMock.mock.calls[2][1] + expect(firstProperties).toMatchObject({ + generation_role: 'current', + exact_incarnation: 'endpoint-identity-linux-ticks', + exact_incarnation_correlation: 'v1:2751326d0f457808fe11a03ce2f6e732' + }) + expect(secondProperties.exact_incarnation_correlation).toBe( + firstProperties.exact_incarnation_correlation + ) + expect(replacementProperties.exact_incarnation_correlation).not.toBe( + firstProperties.exact_incarnation_correlation + ) + expect(validate('daemon_audit_eligibility', firstProperties).ok).toBe(true) + + const serializedProperties = JSON.stringify(firstProperties) + for (const rawIdentity of [ + exactIncarnation.identity.launchNonce, + String(exactIncarnation.identity.pid), + String(exactIncarnation.identity.startedAtMs), + exactIncarnation.linuxStartTicks, + exactIncarnation.bootId + ]) { + expect(serializedProperties).not.toContain(rawIdentity) + } + }) + + it('does not mislabel a future protocol generation as legacy', () => { + const trackEligibility = createDaemonAuditEligibilityTracker() + + expect(() => + trackEligibility( + recordAuthenticatedInventory( + { ...context, protocolGeneration: PROTOCOL_VERSION + 1 }, + exactIncarnation + ) + ) + ).not.toThrow() + expect(trackMock).not.toHaveBeenCalled() + }) + it('cannot affect callers when telemetry throws', () => { trackMock.mockImplementation(() => { throw new Error('transport failed') @@ -83,13 +153,13 @@ describe('daemon audit eligibility telemetry', () => { for (let index = 0; index < 60; index += 1) { nowMs += 1_000 - trackEligibility(recordAuthenticatedInventory(context, null)) + trackEligibility(recordAuthenticatedInventory(context, exactIncarnation)) } expect(trackMock).toHaveBeenCalledOnce() nowMs += 5 * 60_000 - trackEligibility(recordAuthenticatedInventory(context, null)) + trackEligibility(recordAuthenticatedInventory(context, exactIncarnation)) expect(trackMock).toHaveBeenCalledTimes(2) }) diff --git a/src/main/daemon/daemon-audit-eligibility-event.ts b/src/main/daemon/daemon-audit-eligibility-event.ts index 3afaaa8aad5..e99ac903eb8 100644 --- a/src/main/daemon/daemon-audit-eligibility-event.ts +++ b/src/main/daemon/daemon-audit-eligibility-event.ts @@ -1,15 +1,22 @@ +import { createHash } from 'node:crypto' import { track } from '../telemetry/client' import type { EventProps } from '../../shared/telemetry-events' import type { DaemonAuditObservation } from './daemon-audit-classifier' +import { PROTOCOL_VERSION } from './daemon-protocol-version' // Why: a steady daemon repeats a byte-identical observation on every listProcesses call, so // repeats are re-sent only as an occasional heartbeat — the shared per-session telemetry // ceiling is 1,000 events for the whole app and audit data must not crowd it out. const REPEATED_OBSERVATION_INTERVAL_MS = 5 * 60_000 +const INCARNATION_CORRELATION_DOMAIN = 'orca:daemon-audit-eligibility:incarnation:v1' +type AuditEligibilityCommonProperties = Omit< + Extract, { exact_incarnation: 'unavailable' }>, + 'exact_incarnation' +> export function trackDaemonAuditEligibility(observation: DaemonAuditObservation): void { try { - track('daemon_audit_eligibility', auditEligibilityProperties(observation)) + track('daemon_audit_eligibility', auditEligibilityProperties(observation, hashLaunchNonce)) } catch { // Audit telemetry cannot affect daemon availability. } @@ -22,11 +29,13 @@ export function createDaemonAuditEligibilityTracker( ): (observation: DaemonAuditObservation) => void { let lastProperties: string | null = null let lastTrackedAtMs = 0 + const correlateLaunchNonce = createLaunchNonceCorrelationCache() return (observation) => { // Why: the rate-limit bookkeeping runs inside the daemon's inventory path, so it is guarded // together with the emit — audit telemetry cannot affect daemon availability. try { - const properties = JSON.stringify(auditEligibilityProperties(observation)) + const eventProperties = auditEligibilityProperties(observation, correlateLaunchNonce) + const properties = JSON.stringify(eventProperties) const observedAtMs = monotonicNowMs() const elapsedMs = observedAtMs - lastTrackedAtMs if ( @@ -38,7 +47,7 @@ export function createDaemonAuditEligibilityTracker( } lastProperties = properties lastTrackedAtMs = observedAtMs - trackDaemonAuditEligibility(observation) + track('daemon_audit_eligibility', eventProperties) } catch { // Audit telemetry cannot affect daemon availability. } @@ -46,33 +55,73 @@ export function createDaemonAuditEligibilityTracker( } function auditEligibilityProperties( - observation: DaemonAuditObservation + observation: DaemonAuditObservation, + correlateLaunchNonce: (launchNonce: string) => string ): EventProps<'daemon_audit_eligibility'> { - return { + const generationRole = generationRoleForProtocol(observation.context.protocolGeneration) + const commonProperties: AuditEligibilityCommonProperties = { state: observation.state, reason: observation.reason, trigger: observation.trigger, evidence_sources: [...observation.evidenceSources], protocol_generation: observation.context.protocolGeneration, + generation_role: generationRole, provider: observation.context.provider, endpoint_kind: observation.context.endpointKind, profile_scope: observation.context.profileScope ? 'configured' : 'unspecified', - exact_incarnation: exactIncarnationKind(observation), reachability: observation.reachability, inventory_authority: observation.inventoryAuthority, process_liveness: observation.processLiveness, process_reason: observation.processReason, endpoint_state: observation.endpointState } + if (!observation.exactIncarnation) { + return { ...commonProperties, exact_incarnation: 'unavailable' } + } + return { + ...commonProperties, + exact_incarnation: exactIncarnationKind(observation.exactIncarnation), + exact_incarnation_correlation: correlateLaunchNonce( + observation.exactIncarnation.identity.launchNonce + ) + } +} + +function generationRoleForProtocol(protocolGeneration: number): 'current' | 'legacy' { + if (protocolGeneration === PROTOCOL_VERSION) { + return 'current' + } + if (protocolGeneration > 0 && protocolGeneration < PROTOCOL_VERSION) { + return 'legacy' + } + throw new Error('unsupported_daemon_audit_protocol_generation') } function exactIncarnationKind( - observation: DaemonAuditObservation -): 'endpoint-identity' | 'endpoint-identity-linux-ticks' | 'unavailable' { - if (!observation.exactIncarnation) { - return 'unavailable' - } - return observation.exactIncarnation.linuxStartTicks && observation.exactIncarnation.bootId + exactIncarnation: NonNullable +): 'endpoint-identity' | 'endpoint-identity-linux-ticks' { + return exactIncarnation.linuxStartTicks && exactIncarnation.bootId ? 'endpoint-identity-linux-ticks' : 'endpoint-identity' } + +function createLaunchNonceCorrelationCache(): (launchNonce: string) => string { + let cachedNonce: string | null = null + let cachedCorrelation = '' + return (launchNonce) => { + if (launchNonce !== cachedNonce) { + cachedNonce = launchNonce + cachedCorrelation = hashLaunchNonce(launchNonce) + } + return cachedCorrelation + } +} + +function hashLaunchNonce(launchNonce: string): string { + const digest = createHash('sha256') + .update(INCARNATION_CORRELATION_DOMAIN) + .update('\0') + .update(launchNonce) + .digest('hex') + return `v1:${digest.slice(0, 32)}` +} diff --git a/src/main/daemon/daemon-foreground-confirmation-protocol.test.ts b/src/main/daemon/daemon-foreground-confirmation-protocol.test.ts index a9e5285c8f6..07f291a60ff 100644 --- a/src/main/daemon/daemon-foreground-confirmation-protocol.test.ts +++ b/src/main/daemon/daemon-foreground-confirmation-protocol.test.ts @@ -3,7 +3,7 @@ import { PREVIOUS_DAEMON_PROTOCOL_VERSIONS, PROTOCOL_VERSION } from './types' describe('foreground-confirmation daemon protocol', () => { it('rejects daemons from before the fresh-confirmation RPC', () => { - expect(PROTOCOL_VERSION).toBe(30) + expect(PROTOCOL_VERSION).toBe(32) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(19) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(22) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(23) @@ -13,5 +13,7 @@ describe('foreground-confirmation daemon protocol', () => { expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(27) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(28) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(29) + expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(30) + expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toContain(31) }) }) diff --git a/src/main/daemon/daemon-init.test.ts b/src/main/daemon/daemon-init.test.ts index 444627f59e6..6f7de545dc4 100644 --- a/src/main/daemon/daemon-init.test.ts +++ b/src/main/daemon/daemon-init.test.ts @@ -689,6 +689,29 @@ describe('daemon-init: runRestartDaemon (7-step sequence)', () => { expect(adapterInstances[0].listProcesses).toHaveBeenCalled() }) + it('rechecks the preserved daemon endpoint before recovering fresh-spawn routing', async () => { + const mod = await importFresh() + ensureRunningOverrides.push(async () => ({ + socketPath: '/fake/degraded-socket', + tokenPath: '/fake/degraded-token', + mode: 'degraded-new-pty-fallback' + })) + await mod.initDaemonPtyProvider() + checkDaemonHealthMock.mockClear() + + const { DegradedDaemonPtyProvider } = await import('./degraded-daemon-pty-provider') + const provider = mod.getDaemonProvider() + expect(provider).toBeInstanceOf(DegradedDaemonPtyProvider) + const degradedProvider = provider as InstanceType + + await expect(degradedProvider.recoverFreshSpawnRouting()).resolves.toBe(true) + expect(checkDaemonHealthMock).toHaveBeenCalledWith( + '/fake/degraded-socket', + '/fake/degraded-token' + ) + expect(degradedProvider.routesFreshSpawnsToLocalProvider).toBeUndefined() + }) + it('fans pty:exit for every active session *before* unbinding listeners, and killedCount is captured pre-fanout', async () => { const mod = await importFresh() await mod.initDaemonPtyProvider() diff --git a/src/main/daemon/daemon-init.ts b/src/main/daemon/daemon-init.ts index 6c793a316b8..de040bb8efc 100644 --- a/src/main/daemon/daemon-init.ts +++ b/src/main/daemon/daemon-init.ts @@ -763,7 +763,9 @@ export async function initDaemonPtyProvider( ? new DegradedDaemonPtyProvider({ current: newAdapter, legacy: legacyAdapters, - fallback: getLocalPtyProvider() + fallback: getLocalPtyProvider(), + probeCurrentDaemonSpawn: async () => + (await checkDaemonHealth(info.socketPath, info.tokenPath)) === 'healthy' }) : legacyAdapters.length > 0 ? new DaemonPtyRouter({ diff --git a/src/main/daemon/daemon-protocol-version.test.ts b/src/main/daemon/daemon-protocol-version.test.ts index db00c375065..53ad0c06341 100644 --- a/src/main/daemon/daemon-protocol-version.test.ts +++ b/src/main/daemon/daemon-protocol-version.test.ts @@ -6,6 +6,8 @@ import { GET_FOREGROUND_PROCESS_PROTOCOL_VERSION, HISTORY_SEED_TRANSFER_PROTOCOL_VERSION, MODE_2031_UNSUBSCRIBE_FACT_PROTOCOL_VERSION, + SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION, + STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION, PREVIOUS_DAEMON_PROTOCOL_VERSIONS, PROTOCOL_VERSION, supportsMode2031UnsubscribeFact @@ -13,7 +15,9 @@ import { describe('daemon protocol version', () => { it('ships bounded history transfer after the 2031-unsubscribe fact', () => { - expect(PROTOCOL_VERSION).toBe(30) + expect(PROTOCOL_VERSION).toBe(32) + expect(SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION).toBe(32) + expect(STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION).toBe(31) expect(HISTORY_SEED_TRANSFER_PROTOCOL_VERSION).toBe(30) expect(MODE_2031_UNSUBSCRIBE_FACT_PROTOCOL_VERSION).toBe(29) expect(COMPLETION_PROCESS_INSPECTION_PROTOCOL_VERSION).toBe(27) @@ -21,7 +25,7 @@ describe('daemon protocol version', () => { expect(AGENT_SESSION_CLAIM_DAEMON_PROTOCOL_VERSION).toBe(26) expect(AGENT_SESSION_CREATE_OPERATION_DAEMON_PROTOCOL_VERSION).toBe(26) expect(PREVIOUS_DAEMON_PROTOCOL_VERSIONS).toEqual( - Array.from({ length: 29 }, (_, index) => index + 1) + Array.from({ length: 31 }, (_, index) => index + 1) ) }) diff --git a/src/main/daemon/daemon-protocol-version.ts b/src/main/daemon/daemon-protocol-version.ts index 5a7f8bb99bb..61cabf2fc15 100644 --- a/src/main/daemon/daemon-protocol-version.ts +++ b/src/main/daemon/daemon-protocol-version.ts @@ -1,6 +1,8 @@ // Why: daemons survive app updates, so wire behavior must be version-gated. -// v30 transfers large cold-restore seeds across bounded NDJSON messages. -export const PROTOCOL_VERSION = 30 +// v32 carries the corrected terminal snapshot serializer; older owners remain attachable. +export const PROTOCOL_VERSION = 32 +export const SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION = 32 +export const STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION = 31 export const HISTORY_SEED_TRANSFER_PROTOCOL_VERSION = 30 export const COMPLETION_PROCESS_INSPECTION_PROTOCOL_VERSION = 27 export const GET_FOREGROUND_PROCESS_PROTOCOL_VERSION = 11 @@ -22,7 +24,7 @@ export const CLEAN_DISCONNECT_PROTOCOL_VERSION = 24 export const MODE_2031_UNSUBSCRIBE_FACT_PROTOCOL_VERSION = 29 export const PREVIOUS_DAEMON_PROTOCOL_VERSIONS = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29 + 28, 29, 30, 31 ] as const export function supportsPtyStartupIngress(protocolVersion: number): boolean { diff --git a/src/main/daemon/daemon-pty-adapter.test.ts b/src/main/daemon/daemon-pty-adapter.test.ts index 5a3d766b85d..5dc807459be 100644 --- a/src/main/daemon/daemon-pty-adapter.test.ts +++ b/src/main/daemon/daemon-pty-adapter.test.ts @@ -848,13 +848,13 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { } }) - it('delegates scan authority to a v29 daemon, which can retract', () => { + it('delegates scan authority to a v32 daemon with faithful snapshots', () => { const notifySpy = vi.spyOn(DaemonClient.prototype, 'notify') - const current = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 29 }) + const current = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 32 }) try { - current.setPtyBackgrounded('v29-session', true) + current.setPtyBackgrounded('v32-session', true) expect(notifySpy).toHaveBeenCalledWith('setSessionBackground', { - sessionId: 'v29-session', + sessionId: 'v32-session', background: true }) } finally { @@ -939,8 +939,8 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { }) describe('background stream thinning compatibility', () => { - it('reports authoritative snapshot support only for protocol v20 and newer', () => { - const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 19 }) + it('reports authoritative snapshot support only for the corrected serializer protocol', () => { + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 31 }) try { expect(legacy.canProvideAuthoritativeBufferSnapshot('legacy-session')).toBe(false) expect(adapter.canProvideAuthoritativeBufferSnapshot('current-session')).toBe(true) @@ -962,9 +962,9 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { } }) - it('keeps preserved v19 sessions unthinned because their snapshots have no sequence', () => { + it('keeps preserved v31 sessions unthinned because their snapshots can corrupt replay', () => { const notifySpy = vi.spyOn(DaemonClient.prototype, 'notify') - const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 19 }) + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 31 }) try { legacy.setPtyBackgrounded('legacy-session', true) expect(notifySpy).toHaveBeenCalledWith('setSessionBackground', { @@ -977,7 +977,7 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { } }) - it('clears a preserved v19 background hint before attaching its stream', async () => { + it('clears a preserved v31 background hint before attaching its stream', async () => { const ensureConnectedSpy = vi .spyOn(DaemonClient.prototype, 'ensureConnected') .mockResolvedValue() @@ -988,7 +988,7 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { snapshot: null } as never) const notifySpy = vi.spyOn(DaemonClient.prototype, 'notify') - const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 19 }) + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 31 }) try { await legacy.spawn({ sessionId: 'legacy-session', cols: 80, rows: 24 }) @@ -1009,7 +1009,9 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { it.each([ { protocolVersion: 28, clearsHint: true }, - { protocolVersion: 29, clearsHint: false } + { protocolVersion: 29, clearsHint: true }, + { protocolVersion: 31, clearsHint: true }, + { protocolVersion: 32, clearsHint: false } ])( 'uses protocol v$protocolVersion background authority before spawn', async ({ protocolVersion, clearsHint }) => { @@ -1085,7 +1087,7 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { } }) - it('leaves a v29 background hint alone on attach, because it can retract on its own', async () => { + it('leaves a v32 background hint alone on attach', async () => { const ensureConnectedSpy = vi .spyOn(DaemonClient.prototype, 'ensureConnected') .mockResolvedValue() @@ -1096,13 +1098,13 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { snapshot: null } as never) const notifySpy = vi.spyOn(DaemonClient.prototype, 'notify') - const current = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 29 }) + const current = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 32 }) try { - await current.attach('preserved-v29-session') + await current.attach('preserved-v32-session') expect(notifySpy).not.toHaveBeenCalledWith( 'setSessionBackground', - expect.objectContaining({ sessionId: 'preserved-v29-session' }) + expect.objectContaining({ sessionId: 'preserved-v32-session' }) ) } finally { current.dispose() @@ -1112,7 +1114,7 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { } }) - it('still returns the v19 attach snapshot for a desktop renderer replay', async () => { + it('still returns the v31 attach snapshot so desktop replay retains shell history', async () => { const ensureConnectedSpy = vi .spyOn(DaemonClient.prototype, 'ensureConnected') .mockResolvedValue() @@ -1129,7 +1131,7 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { rows: 24 } } as never) - const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 19 }) + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 31 }) try { const result = await legacy.spawn({ sessionId: 'legacy-session', cols: 80, rows: 24 }) @@ -1411,6 +1413,130 @@ describe('DaemonPtyAdapter (IPtyProvider)', () => { expect(result.snapshot).toBeUndefined() expect(result.providerSequence).toEqual({ value: 0, generation: 'reset' }) }) + + it('forwards attach-only and never creates an absent stable session', async () => { + const subprocessBeforeAttach = lastSubprocess + await expect( + adapter.spawn({ + cols: 80, + rows: 24, + sessionId: 'missing-stable-pane-session', + attachOnly: true + }) + ).rejects.toThrow('Session not found: missing-stable-pane-session') + expect(lastSubprocess).toBe(subprocessBeforeAttach) + }) + + it('does not inspect cold history for attach-only ownership checks', async () => { + const historyDir = join(dir, 'attach-only-history') + const historyAdapter = new DaemonPtyAdapter({ + socketPath, + tokenPath, + historyPath: historyDir + }) + const reader = (historyAdapter as unknown as { historyReader: HistoryReader }).historyReader + const probe = vi.spyOn(reader, 'probeRestorableHistory') + const getAppliedSize = vi.spyOn(historyAdapter, 'getAppliedSize') + + try { + await expect( + historyAdapter.spawn({ + cols: 80, + rows: 24, + sessionId: 'missing-attach-only-history-session', + attachOnly: true + }) + ).rejects.toThrow('Session not found: missing-attach-only-history-session') + expect(probe).not.toHaveBeenCalled() + expect(getAppliedSize).not.toHaveBeenCalled() + } finally { + historyAdapter.dispose() + } + }) + + it('reattaches a stable pane through a preserved v30 daemon', async () => { + const ensureConnected = vi + .spyOn(DaemonClient.prototype, 'ensureConnected') + .mockResolvedValue() + const request = vi.spyOn(DaemonClient.prototype, 'request').mockResolvedValue({ + isNew: false, + snapshot: null, + pid: 4321, + shellState: 'unsupported', + incarnationId: 'legacy-stable-pane-incarnation' + }) + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 30 }) + try { + await expect( + legacy.spawn({ + cols: 80, + rows: 24, + sessionId: 'legacy-stable-pane-session', + attachOnly: true, + command: 'must-not-run' + }) + ).resolves.toMatchObject({ + id: 'legacy-stable-pane-session', + incarnationId: 'legacy-stable-pane-incarnation', + isReattach: true + }) + expect(request).toHaveBeenCalledWith( + 'createOrAttach', + expect.objectContaining({ + command: undefined, + launchAgent: undefined, + startupCommandDelivery: undefined + }) + ) + expect(request.mock.calls[0]?.[1]).not.toHaveProperty('attachOnly') + } finally { + legacy.dispose() + request.mockRestore() + ensureConnected.mockRestore() + } + }) + + it('retires a replacement created by a raced-out v30 stable pane', async () => { + const ensureConnected = vi + .spyOn(DaemonClient.prototype, 'ensureConnected') + .mockResolvedValue() + const request = vi + .spyOn(DaemonClient.prototype, 'request') + .mockResolvedValueOnce({ + isNew: true, + snapshot: null, + pid: 4321, + shellState: 'unsupported', + incarnationId: 'legacy-replacement-incarnation' + }) + .mockResolvedValueOnce({}) + const legacy = new DaemonPtyAdapter({ socketPath, tokenPath, protocolVersion: 30 }) + try { + await expect( + legacy.spawn({ + cols: 80, + rows: 24, + sessionId: 'raced-out-legacy-session', + attachOnly: true, + command: 'must-not-run' + }) + ).rejects.toThrow('Session not found: raced-out-legacy-session') + expect(request).toHaveBeenNthCalledWith( + 1, + 'createOrAttach', + expect.objectContaining({ command: undefined }) + ) + expect(request).toHaveBeenNthCalledWith(2, 'kill', { + sessionId: 'raced-out-legacy-session', + immediate: true + }) + expect(legacy.getActiveSessionIds()).toEqual([]) + } finally { + legacy.dispose() + request.mockRestore() + ensureConnected.mockRestore() + } + }) }) describe('attach', () => { diff --git a/src/main/daemon/daemon-pty-adapter.ts b/src/main/daemon/daemon-pty-adapter.ts index ef60ca5d9f1..2bba3c467dc 100644 --- a/src/main/daemon/daemon-pty-adapter.ts +++ b/src/main/daemon/daemon-pty-adapter.ts @@ -32,10 +32,15 @@ import { type DaemonEvent, type GetSnapshotResult, type ListSessionsResult, + SessionNotFoundError, type SessionInfo, type TakePendingOutputResult } from './types' -import { HISTORY_SEED_TRANSFER_PROTOCOL_VERSION } from './daemon-protocol-version' +import { + HISTORY_SEED_TRANSFER_PROTOCOL_VERSION, + SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION, + STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION +} from './daemon-protocol-version' import { isAgentSessionClaimedSpawnResult, isAgentSessionOwnerBinding, @@ -272,7 +277,8 @@ export class DaemonPtyAdapter implements IPtyProvider { this.supportsCheckpoints = this.protocolVersion >= 4 this.supportsIncrementalCheckpoints = this.protocolVersion >= 13 this.supportsProducerFlowControl = this.protocolVersion >= 19 - this.supportsAuthoritativeBufferSnapshots = this.protocolVersion >= 20 + this.supportsAuthoritativeBufferSnapshots = + this.protocolVersion >= SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION this.supportsStartupIngress = supportsPtyStartupIngress(this.protocolVersion) this.client.onDisconnected(() => { if (!this.respawnAdoptionClosed) { @@ -376,6 +382,10 @@ export class DaemonPtyAdapter implements IPtyProvider { throw new Error('agent_session_claim_unavailable') } const requestedSessionId = opts.sessionId! + // Why: v30 daemons survive upgrades; reject their accidental create result before publication. + const attachOnly = opts.attachOnly === true + const emulateLegacyAttachOnly = + attachOnly && this.protocolVersion < STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION let sessionId = requestedSessionId let wslDistro = resolveWslSessionContext({ cwd: opts.cwd, @@ -449,7 +459,9 @@ export class DaemonPtyAdapter implements IPtyProvider { // Why probe aliveness first: detectColdRestore replays up to ~5MB on the main process, but a live session's snapshot supersedes disk, so the replay would be wasted. let restoreInfo: ColdRestoreInfo | null = null let restoreSkippedForLiveSession = false - const historyProbe = this.historyReader?.probeRestorableHistory(sessionId) + const historyProbe = opts.attachOnly + ? undefined + : this.historyReader?.probeRestorableHistory(sessionId) if (historyProbe && historyProbe.status !== 'none') { if ((await this.getAppliedSize(sessionId)) !== null) { restoreSkippedForLiveSession = true @@ -490,24 +502,29 @@ export class DaemonPtyAdapter implements IPtyProvider { sessionId, cols: effectiveCols, rows: effectiveRows, - cwd: effectiveCwd, - env: opts.env, - envToDelete: opts.envToDelete, - command: opts.command, - startupCommandDelivery: opts.startupCommandDelivery, - launchAgent: opts.launchAgent, + cwd: attachOnly ? undefined : effectiveCwd, + env: attachOnly ? undefined : opts.env, + envToDelete: attachOnly ? undefined : opts.envToDelete, + command: attachOnly ? undefined : opts.command, + startupCommandDelivery: attachOnly ? undefined : opts.startupCommandDelivery, + launchAgent: attachOnly ? undefined : opts.launchAgent, + ...(attachOnly && !emulateLegacyAttachOnly ? { attachOnly: true } : {}), // Why: without forwarding the override, the daemon falls back to cmd.exe/PowerShell, ignoring the shell the renderer chose; this matches LocalPtyProvider. - shellOverride: opts.shellOverride, - terminalWindowsWslDistro: opts.terminalWindowsWslDistro, - terminalWindowsPowerShellImplementation: opts.terminalWindowsPowerShellImplementation, - shellReadySupported, - ...(shellReadyTimeoutMs !== undefined ? { shellReadyTimeoutMs } : {}), + shellOverride: attachOnly ? undefined : opts.shellOverride, + terminalWindowsWslDistro: attachOnly ? undefined : opts.terminalWindowsWslDistro, + terminalWindowsPowerShellImplementation: attachOnly + ? undefined + : opts.terminalWindowsPowerShellImplementation, + shellReadySupported: attachOnly ? false : shellReadySupported, + ...(!attachOnly && shellReadyTimeoutMs !== undefined ? { shellReadyTimeoutMs } : {}), ...(historySeed ? { historySeed } : {}), ...(historySeedTransferId ? { historySeedTransferId } : {}), - ...(this.supportsStartupIngress && opts.startupIngress + ...(this.supportsStartupIngress && !attachOnly && opts.startupIngress ? { startupIngress: opts.startupIngress } : {}), - ...(opts.agentSessionEnsure ? { agentSessionEnsure: opts.agentSessionEnsure } : {}) + ...(!attachOnly && opts.agentSessionEnsure + ? { agentSessionEnsure: opts.agentSessionEnsure } + : {}) }) } @@ -595,6 +612,11 @@ export class DaemonPtyAdapter implements IPtyProvider { historySeedSegments = null } let result = await createOrAttach(historySeedSegments) + if (emulateLegacyAttachOnly && result.isNew) { + operation.ignoreNextExit = true + await this.client.request('kill', { sessionId: requestedSessionId, immediate: true }) + throw new SessionNotFoundError(requestedSessionId) + } await adoptSpawnResultSession(result) // Both ids: adoptSpawnResultSession may have rewritten sessionId to the claim owner. this.clearSessionAwaitingDaemonRecovery(requestedSessionId) @@ -939,7 +961,7 @@ export class DaemonPtyAdapter implements IPtyProvider { if (!this.supportsProducerFlowControl) { return } - // Why: preserved v19 daemons can thin but can't return the absolute snapshot sequence to recover a gap; clear their stale hint too. + // Why: preserved daemons without a sequence-safe, faithful serializer cannot heal a thinned stream. // Why also gate on 2031 (#9993): backgrounding is what hands transient-fact scan // authority to the daemon. A pre-v29 daemon can announce a 2031 subscribe but never // retract it, so a TUI exiting while hidden would strand the subscription and the diff --git a/src/main/daemon/daemon-pty-router-history-handoff.test.ts b/src/main/daemon/daemon-pty-router-history-handoff.test.ts index a53a4b29b63..07c2a5033d5 100644 --- a/src/main/daemon/daemon-pty-router-history-handoff.test.ts +++ b/src/main/daemon/daemon-pty-router-history-handoff.test.ts @@ -121,9 +121,7 @@ describe('DaemonPtyRouter history handoff', () => { 'finishHistorySeedTransfer' ]) ) - await expect(router.getBufferSnapshot(sessionId)).resolves.toMatchObject({ - data: expect.stringContaining(marker) - }) + await expect(router.getBufferSnapshot(sessionId)).resolves.toBeNull() expect(currentAdapter.getHistoryManager()?.hasWriter(sessionId)).toBe(true) }) }) diff --git a/src/main/daemon/daemon-pty-router.test.ts b/src/main/daemon/daemon-pty-router.test.ts index 17ad0dd835c..2bee5164ce9 100644 --- a/src/main/daemon/daemon-pty-router.test.ts +++ b/src/main/daemon/daemon-pty-router.test.ts @@ -7,7 +7,12 @@ import { AGENT_SESSION_CREATE_OPERATION_DAEMON_PROTOCOL_VERSION, GIT_CREDENTIAL_GUARD_HOST_PROTOCOL_VERSION } from './types' -import { HISTORY_SEED_TRANSFER_PROTOCOL_VERSION } from './daemon-protocol-version' +import { + HISTORY_SEED_TRANSFER_PROTOCOL_VERSION, + PROTOCOL_VERSION, + SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION, + STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION +} from './daemon-protocol-version' type AdapterMock = DaemonPtyAdapter & { emitData: (id: string, data: string, sequenceChars?: number) => void @@ -49,7 +54,8 @@ function createAdapter( protocolVersion >= AGENT_SESSION_CREATE_OPERATION_DAEMON_PROTOCOL_VERSION, providesAgentSessionOwnerListings: () => protocolVersion >= AGENT_SESSION_CLAIM_DAEMON_PROTOCOL_VERSION, - canProvideAuthoritativeBufferSnapshot: () => protocolVersion >= 20, + canProvideAuthoritativeBufferSnapshot: () => + protocolVersion >= SNAPSHOT_SERIALIZER_FIDELITY_DAEMON_PROTOCOL_VERSION, spawn: vi.fn(async (opts: PtySpawnOptions): Promise => { const id = opts.sessionId ?? `${label}-new` sessions.push(id) @@ -336,8 +342,13 @@ describe('DaemonPtyRouter', () => { }) it('reports snapshot capability for the adapter that owns each session', async () => { - const current = createAdapter('current', ['current-session'], undefined, 22) - const legacy = createAdapter('legacy', ['legacy-session'], undefined, 19) + const current = createAdapter('current', ['current-session'], undefined, PROTOCOL_VERSION) + const legacy = createAdapter( + 'legacy', + ['legacy-session'], + undefined, + STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION + ) const router = new DaemonPtyRouter({ current, legacy: [legacy] }) await router.discoverLegacySessions() @@ -371,21 +382,36 @@ describe('DaemonPtyRouter', () => { expect(current.confirmForegroundProcess).toHaveBeenCalledWith('current-session') }) - it('routes existing legacy sessions to their old daemon and new sessions to current daemon', async () => { - const current = createAdapter('current') - const legacy = createAdapter('legacy', ['legacy-session']) - const router = new DaemonPtyRouter({ current, legacy: [legacy] }) + it('preserves v30/v31 session owners and routes new sessions to v32', async () => { + const current = createAdapter('current', [], undefined, PROTOCOL_VERSION) + const legacyV30 = createAdapter( + 'v30', + ['v30-session'], + undefined, + HISTORY_SEED_TRANSFER_PROTOCOL_VERSION + ) + const legacyV31 = createAdapter( + 'v31', + ['v31-session'], + undefined, + STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION + ) + const router = new DaemonPtyRouter({ current, legacy: [legacyV30, legacyV31] }) await router.discoverLegacySessions() - await router.spawn({ sessionId: 'legacy-session', cols: 80, rows: 24 }) + await router.spawn({ sessionId: 'v30-session', cols: 80, rows: 24 }) + await router.spawn({ sessionId: 'v31-session', cols: 80, rows: 24 }) const fresh = await router.spawn({ cols: 80, rows: 24 }) - router.write('legacy-session', 'old\n') + router.write('v30-session', 'old-v30\n') + router.write('v31-session', 'old-v31\n') router.write(fresh.id, 'new\n') - expect(legacy.spawn).toHaveBeenCalledWith({ sessionId: 'legacy-session', cols: 80, rows: 24 }) + expect(legacyV30.spawn).toHaveBeenCalledWith({ sessionId: 'v30-session', cols: 80, rows: 24 }) + expect(legacyV31.spawn).toHaveBeenCalledWith({ sessionId: 'v31-session', cols: 80, rows: 24 }) expect(current.spawn).toHaveBeenCalledWith({ cols: 80, rows: 24 }) - expect(legacy.write).toHaveBeenCalledWith('legacy-session', 'old\n') + expect(legacyV30.write).toHaveBeenCalledWith('v30-session', 'old-v30\n') + expect(legacyV31.write).toHaveBeenCalledWith('v31-session', 'old-v31\n') expect(current.write).toHaveBeenCalledWith(fresh.id, 'new\n') }) diff --git a/src/main/daemon/daemon-pty-upgrade-adoption.test.ts b/src/main/daemon/daemon-pty-upgrade-adoption.test.ts new file mode 100644 index 00000000000..b06f026c2c4 --- /dev/null +++ b/src/main/daemon/daemon-pty-upgrade-adoption.test.ts @@ -0,0 +1,143 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { DaemonPtyAdapter } from './daemon-pty-adapter' +import { DaemonPtyRouter } from './daemon-pty-router' +import { DaemonServer } from './daemon-server' +import { STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION } from './daemon-protocol-version' +import { getDaemonSocketPath } from './daemon-spawner' +import type { DaemonFileLog } from './daemon-file-log' +import type { SubprocessHandle } from './session' + +type FixtureSubprocess = SubprocessHandle & { emitData: (data: string) => void } + +function createFixtureSubprocess(pid: number): FixtureSubprocess { + let onData: ((data: string) => void) | undefined + let onExit: ((code: number) => void) | undefined + return { + pid, + getForegroundProcess: vi.fn(() => null), + write: vi.fn(), + resize: vi.fn(), + pause: vi.fn(), + resume: vi.fn(), + kill: vi.fn(() => onExit?.(0)), + forceKill: vi.fn(() => onExit?.(137)), + signal: vi.fn(), + onData: vi.fn((callback) => { + onData = callback + }), + onExit: vi.fn((callback) => { + onExit = callback + }), + dispose: vi.fn(), + emitData: (data) => onData?.(data) + } +} + +describe('daemon PTY upgrade adoption', () => { + const servers: DaemonServer[] = [] + const adapters: DaemonPtyAdapter[] = [] + const directories: string[] = [] + let router: DaemonPtyRouter | null = null + + afterEach(async () => { + router?.dispose() + router = null + for (const adapter of adapters.splice(0)) { + adapter.dispose() + } + await Promise.all(servers.splice(0).map((server) => server.shutdown())) + for (const directory of directories.splice(0)) { + rmSync(directory, { recursive: true, force: true }) + } + }) + + it('reattaches a live v30 pane through a v31 router without spawning a replacement', async () => { + const directory = mkdtempSync(join(tmpdir(), 'daemon-pty-upgrade-adoption-')) + directories.push(directory) + const legacyProtocol = STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION - 1 + const currentProtocol = STABLE_PANE_ATTACH_ONLY_DAEMON_PROTOCOL_VERSION + const legacySocketPath = getDaemonSocketPath(directory, legacyProtocol) + const currentSocketPath = getDaemonSocketPath(directory, currentProtocol) + const legacyTokenPath = join(directory, 'legacy.token') + const currentTokenPath = join(directory, 'current.token') + const log: DaemonFileLog = { log: () => {}, close: () => {} } + const legacySubprocesses: FixtureSubprocess[] = [] + const currentSubprocesses: FixtureSubprocess[] = [] + const legacyServer = new DaemonServer({ + socketPath: legacySocketPath, + tokenPath: legacyTokenPath, + protocolVersion: legacyProtocol, + log, + spawnSubprocess: () => { + const subprocess = createFixtureSubprocess(30_030) + legacySubprocesses.push(subprocess) + return subprocess + } + }) + const currentServer = new DaemonServer({ + socketPath: currentSocketPath, + tokenPath: currentTokenPath, + protocolVersion: currentProtocol, + log, + spawnSubprocess: () => { + const subprocess = createFixtureSubprocess(31_031) + currentSubprocesses.push(subprocess) + return subprocess + } + }) + servers.push(legacyServer, currentServer) + await Promise.all([legacyServer.start(), currentServer.start()]) + + const oldAppAdapter = new DaemonPtyAdapter({ + socketPath: legacySocketPath, + tokenPath: legacyTokenPath, + protocolVersion: legacyProtocol + }) + adapters.push(oldAppAdapter) + const original = await oldAppAdapter.spawn({ + sessionId: 'v30-stable-pane', + cols: 80, + rows: 24 + }) + legacySubprocesses[0]?.emitData('output-before-v31-upgrade') + oldAppAdapter.dispose() + + const legacyAdapter = new DaemonPtyAdapter({ + socketPath: legacySocketPath, + tokenPath: legacyTokenPath, + protocolVersion: legacyProtocol + }) + const currentAdapter = new DaemonPtyAdapter({ + socketPath: currentSocketPath, + tokenPath: currentTokenPath, + protocolVersion: currentProtocol + }) + adapters.push(legacyAdapter, currentAdapter) + router = new DaemonPtyRouter({ current: currentAdapter, legacy: [legacyAdapter] }) + await router.discoverLegacySessions() + + const adopted = await router.spawn({ + sessionId: original.id, + cols: 120, + rows: 40, + attachOnly: true, + command: 'must-not-run' + }) + + expect(adopted).toMatchObject({ + id: original.id, + incarnationId: original.incarnationId, + isReattach: true, + snapshot: expect.stringContaining('output-before-v31-upgrade') + }) + expect(legacySubprocesses).toHaveLength(1) + expect(currentSubprocesses).toHaveLength(0) + router.write(original.id, 'input-after-v31-upgrade') + await vi.waitFor(() => + expect(legacySubprocesses[0]?.write).toHaveBeenCalledWith('input-after-v31-upgrade') + ) + }) +}) diff --git a/src/main/daemon/daemon-server-attach-only.test.ts b/src/main/daemon/daemon-server-attach-only.test.ts new file mode 100644 index 00000000000..6ec37b59bc8 --- /dev/null +++ b/src/main/daemon/daemon-server-attach-only.test.ts @@ -0,0 +1,105 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { DaemonClient } from './client' +import { DaemonServer } from './daemon-server' +import { getDaemonSocketPath } from './daemon-spawner' +import type { SubprocessHandle } from './session' + +function createMockSubprocess(): SubprocessHandle { + let onExit: ((code: number) => void) | undefined + return { + pid: 55555, + getForegroundProcess: vi.fn(() => null), + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(() => onExit?.(0)), + forceKill: vi.fn(() => onExit?.(137)), + signal: vi.fn(), + onData: vi.fn(), + onExit: vi.fn((callback) => { + onExit = callback + }), + dispose: vi.fn() + } +} + +describe('DaemonServer attach-only preparation', () => { + const servers: DaemonServer[] = [] + const clients: DaemonClient[] = [] + const directories: string[] = [] + + afterEach(async () => { + for (const client of clients.splice(0)) { + client.disconnect() + } + await Promise.all(servers.splice(0).map((server) => server.shutdown())) + for (const directory of directories.splice(0)) { + rmSync(directory, { recursive: true, force: true }) + } + }) + + it('skips fresh-spawn preparation when attaching only', async () => { + const directory = mkdtempSync(join(tmpdir(), 'daemon-attach-only-test-')) + directories.push(directory) + const socketPath = getDaemonSocketPath(directory) + const tokenPath = join(directory, 'test.token') + const preparePtySpawn = vi.fn(async () => {}) + const server = new DaemonServer({ + socketPath, + tokenPath, + preparePtySpawn, + spawnSubprocess: () => createMockSubprocess() + }) + servers.push(server) + await server.start() + const client = new DaemonClient({ socketPath, tokenPath }) + clients.push(client) + await client.ensureConnected() + await client.request('createOrAttach', { + sessionId: 'stable-pane-session', + cols: 80, + rows: 24 + }) + + await expect( + client.request('createOrAttach', { + sessionId: 'stable-pane-session', + cols: 120, + rows: 40, + attachOnly: true + }) + ).resolves.toMatchObject({ isNew: false }) + expect(preparePtySpawn).toHaveBeenCalledOnce() + }) + + it('prepares a fresh spawn when attachOnly is not the boolean true', async () => { + const directory = mkdtempSync(join(tmpdir(), 'daemon-attach-only-shape-test-')) + directories.push(directory) + const socketPath = getDaemonSocketPath(directory) + const tokenPath = join(directory, 'test.token') + const preparePtySpawn = vi.fn(async () => {}) + const server = new DaemonServer({ + socketPath, + tokenPath, + preparePtySpawn, + spawnSubprocess: () => createMockSubprocess() + }) + servers.push(server) + await server.start() + const client = new DaemonClient({ socketPath, tokenPath }) + clients.push(client) + await client.ensureConnected() + + await expect( + client.request('createOrAttach', { + sessionId: 'malformed-attach-only-session', + cols: 80, + rows: 24, + attachOnly: 'false' as never + }) + ).resolves.toMatchObject({ isNew: true }) + expect(preparePtySpawn).toHaveBeenCalledOnce() + }) +}) diff --git a/src/main/daemon/daemon-server-kill-attribution.test.ts b/src/main/daemon/daemon-server-kill-attribution.test.ts new file mode 100644 index 00000000000..8b324043358 --- /dev/null +++ b/src/main/daemon/daemon-server-kill-attribution.test.ts @@ -0,0 +1,119 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { DaemonServer } from './daemon-server' +import { SessionNotFoundError, type DaemonRequest } from './types' + +type DaemonServerPrivate = { + host: { kill: (sessionId: string, opts?: { immediate?: boolean }) => void | Promise } + pendingPtySpawnPreparations: Map> + routeRequest(clientId: string, request: DaemonRequest): Promise +} + +describe('daemon kill attribution', () => { + let server: DaemonServer + let dir: string + + afterEach(async () => { + await server?.shutdown() + rmSync(dir, { recursive: true, force: true }) + }) + + it('records the requesting control client in the session-killed log', async () => { + dir = mkdtempSync(join(tmpdir(), 'daemon-kill-attribution-')) + const killLog = { log: vi.fn(), close: vi.fn() } + server = new DaemonServer({ + socketPath: join(dir, 'daemon.sock'), + tokenPath: join(dir, 'daemon.token'), + log: killLog, + spawnSubprocess: () => { + throw new Error('not used') + } + }) + const daemon = server as unknown as DaemonServerPrivate + let finishKill!: () => void + const killFinished = new Promise((resolve) => { + finishKill = resolve + }) + vi.spyOn(daemon.host, 'kill').mockReturnValue(killFinished) + + const request = daemon.routeRequest('control-42', { + id: 'kill-1', + type: 'kill', + payload: { sessionId: 'agent-session', immediate: true } + }) + + await vi.waitFor(() => expect(daemon.host.kill).toHaveBeenCalledOnce()) + expect(killLog.log).not.toHaveBeenCalledWith('session-killed', expect.anything()) + finishKill() + await request + + expect(killLog.log).toHaveBeenCalledWith('session-killed', { + sessionId: 'agent-session', + immediate: true, + clientId: 'control-42' + }) + }) + + it('attributes a failed kill without claiming the session was killed', async () => { + dir = mkdtempSync(join(tmpdir(), 'daemon-kill-attribution-')) + const killLog = { log: vi.fn(), close: vi.fn() } + server = new DaemonServer({ + socketPath: join(dir, 'daemon.sock'), + tokenPath: join(dir, 'daemon.token'), + log: killLog, + spawnSubprocess: () => { + throw new Error('not used') + } + }) + const daemon = server as unknown as DaemonServerPrivate + vi.spyOn(daemon.host, 'kill').mockRejectedValue(new Error('kill refused')) + + await expect( + daemon.routeRequest('control-42', { + id: 'kill-1', + type: 'kill', + payload: { sessionId: 'agent-session', immediate: true } + }) + ).rejects.toThrow('kill refused') + + expect(killLog.log).toHaveBeenCalledWith('session-kill-failed', { + sessionId: 'agent-session', + immediate: true, + clientId: 'control-42' + }) + expect(killLog.log).not.toHaveBeenCalledWith('session-killed', expect.anything()) + }) + + it('attributes a tolerated kill after canceling a pending spawn', async () => { + dir = mkdtempSync(join(tmpdir(), 'daemon-kill-attribution-')) + const killLog = { log: vi.fn(), close: vi.fn() } + server = new DaemonServer({ + socketPath: join(dir, 'daemon.sock'), + tokenPath: join(dir, 'daemon.token'), + log: killLog, + spawnSubprocess: () => { + throw new Error('not used') + } + }) + const daemon = server as unknown as DaemonServerPrivate + const pendingPreparation = { canceled: false, clientId: 'control-42' } + daemon.pendingPtySpawnPreparations.set('agent-session', new Set([pendingPreparation])) + vi.spyOn(daemon.host, 'kill').mockRejectedValue(new SessionNotFoundError('agent-session')) + + await daemon.routeRequest('control-42', { + id: 'kill-1', + type: 'kill', + payload: { sessionId: 'agent-session', immediate: true } + }) + + expect(pendingPreparation.canceled).toBe(true) + expect(killLog.log).toHaveBeenCalledWith('session-killed', { + sessionId: 'agent-session', + immediate: true, + clientId: 'control-42' + }) + expect(killLog.log).not.toHaveBeenCalledWith('session-kill-failed', expect.anything()) + }) +}) diff --git a/src/main/daemon/daemon-server.ts b/src/main/daemon/daemon-server.ts index 0d8123ce11b..4c9ffd5098e 100644 --- a/src/main/daemon/daemon-server.ts +++ b/src/main/daemon/daemon-server.ts @@ -723,6 +723,7 @@ export class DaemonServer { } this.createOrAttachInFlight++ const p = request.payload + const attachOnly = p.attachOnly === true let routedSessionId = p.sessionId let result: Awaited> try { @@ -733,7 +734,9 @@ export class DaemonServer { ) { throw new Error('agent_session_identity_required') } - await this.preparePtySpawnUnlessCanceled(p.sessionId, clientId) + if (!attachOnly) { + await this.preparePtySpawnUnlessCanceled(p.sessionId, clientId) + } if (p.historySeed !== undefined && p.historySeedTransferId !== undefined) { throw new Error('Multiple terminal history seed sources') } @@ -752,6 +755,7 @@ export class DaemonServer { envToDelete: p.envToDelete, command: p.command, startupCommandDelivery: p.startupCommandDelivery, + ...(attachOnly ? { attachOnly: true } : {}), // Why: RPC payloads are untrusted JSON; persist only the allowlisted routing enum, never arbitrary identity. ...(isTuiAgent(p.launchAgent) ? { launchAgent: p.launchAgent } : {}), shellOverride: p.shellOverride, @@ -931,18 +935,22 @@ export class DaemonServer { request.payload.sessionId ) this.lastInputAtBySessionId.delete(request.payload.sessionId) - this.log.log('session-killed', { + const attribution = { sessionId: request.payload.sessionId, - immediate: request.payload.immediate === true - }) + immediate: request.payload.immediate === true, + // Daemon control identity, not the paired-device bearer credential. + clientId + } try { await this.host.kill(request.payload.sessionId, { immediate: request.payload.immediate }) } catch (error) { // Why: a kill that wins before session registration already canceled the pending spawn, so its intent is done. if (!(canceledPendingSpawn && error instanceof SessionNotFoundError)) { + this.log.log('session-kill-failed', attribution) throw error } } + this.log.log('session-killed', attribution) return {} } diff --git a/src/main/daemon/degraded-daemon-fresh-spawn-routing.ts b/src/main/daemon/degraded-daemon-fresh-spawn-routing.ts new file mode 100644 index 00000000000..b1d4661dc93 --- /dev/null +++ b/src/main/daemon/degraded-daemon-fresh-spawn-routing.ts @@ -0,0 +1,77 @@ +import type { IPtyProvider, PtySpawnOptions, PtySpawnResult } from '../providers/types' + +export const DEGRADED_DAEMON_RECOVERY_RETRY_MS = 30_000 + +export class DegradedDaemonFreshSpawnRouter { + private target: IPtyProvider + private recovery: Promise | null = null + private retryAfterMs = 0 + + constructor( + private readonly current: IPtyProvider, + private readonly fallback: IPtyProvider, + private readonly sessionProviders: Map, + private readonly probeCurrent: (() => Promise) | null + ) { + this.target = fallback + } + + get routesToFallback(): true | undefined { + return this.target === this.fallback ? true : undefined + } + + supportsGitGuardHost(sessionId?: string): boolean { + const provider = (sessionId ? this.sessionProviders.get(sessionId) : undefined) ?? this.target + return provider.supportsGitCredentialGuardHost?.(sessionId) === true + } + + canProvideSnapshot(sessionId: string): boolean { + return ( + this.sessionProviders.get(sessionId)?.canProvideAuthoritativeBufferSnapshot?.(sessionId) === + true + ) + } + + async recover(): Promise { + if (this.target === this.current) { + return true + } + if (!this.probeCurrent) { + return false + } + if (Date.now() < this.retryAfterMs) { + return false + } + if (this.recovery) { + return this.recovery + } + const recovery = this.probeCurrent() + .catch(() => false) + .then((healthy) => { + if (healthy) { + this.target = this.current + console.info('[daemon] PTY spawn health recovered; fresh terminals are daemon-backed') + } else { + this.retryAfterMs = Date.now() + DEGRADED_DAEMON_RECOVERY_RETRY_MS + } + return healthy + }) + .finally(() => { + if (this.recovery === recovery) { + this.recovery = null + } + }) + this.recovery = recovery + return recovery + } + + async spawn(opts: PtySpawnOptions): Promise { + const mapped = opts.sessionId ? this.sessionProviders.get(opts.sessionId) : undefined + const target = mapped ?? this.target + const result = await target.spawn(opts) + if (!result.exitedBeforeSpawnReply) { + this.sessionProviders.set(result.id, target) + } + return result + } +} diff --git a/src/main/daemon/degraded-daemon-pty-provider.test.ts b/src/main/daemon/degraded-daemon-pty-provider.test.ts index fbbfdfe4408..1f1bac4529f 100644 --- a/src/main/daemon/degraded-daemon-pty-provider.test.ts +++ b/src/main/daemon/degraded-daemon-pty-provider.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { DegradedDaemonPtyProvider } from './degraded-daemon-pty-provider' +import { DEGRADED_DAEMON_RECOVERY_RETRY_MS } from './degraded-daemon-fresh-spawn-routing' import type { DaemonPtyAdapter } from './daemon-pty-adapter' import type { IPtyProvider, PtySpawnOptions, PtySpawnResult } from '../providers/types' import type { PtyProcessInspection } from '../providers/pty-process-inspection' @@ -124,6 +125,8 @@ function createDaemonAdapter( return { ...createProvider(label, sessions, true), protocolVersion: 13, + supportsGitCredentialGuardHost: vi.fn(() => true), + canProvideAuthoritativeBufferSnapshot: vi.fn(() => true), listSessions: vi.fn(async () => []), ackColdRestore: vi.fn(), clearTombstone: vi.fn(), @@ -228,6 +231,89 @@ describe('DegradedDaemonPtyProvider', () => { expect(fallback.write).toHaveBeenCalledWith(fresh.id, 'new\n') }) + it('routes later fresh PTYs to the daemon after spawn health recovers', async () => { + const current = createDaemonAdapter('daemon') + const fallback = createProvider('fallback') + const probeCurrentDaemonSpawn = vi + .fn<() => Promise>() + .mockResolvedValueOnce(false) + .mockResolvedValueOnce(true) + const provider = new DegradedDaemonPtyProvider({ + current, + legacy: [], + fallback, + probeCurrentDaemonSpawn + }) + const now = vi.spyOn(Date, 'now').mockReturnValue(1_000) + + try { + await expect(provider.recoverFreshSpawnRouting()).resolves.toBe(false) + await provider.spawn({ cols: 80, rows: 24 }) + await expect(provider.recoverFreshSpawnRouting()).resolves.toBe(false) + expect(probeCurrentDaemonSpawn).toHaveBeenCalledOnce() + now.mockReturnValue(1_000 + DEGRADED_DAEMON_RECOVERY_RETRY_MS) + await expect(provider.recoverFreshSpawnRouting()).resolves.toBe(true) + const recovered = await provider.spawn({ cols: 80, rows: 24, worktreeId: 'wt-1' }) + + expect(provider.routesFreshSpawnsToLocalProvider).toBeUndefined() + expect(provider.isDegraded).toBe(true) + expect(provider.supportsGitCredentialGuardHost()).toBe(true) + expect(fallback.spawn).toHaveBeenCalledOnce() + expect(current.spawn).toHaveBeenCalledWith({ cols: 80, rows: 24, worktreeId: 'wt-1' }) + expect(recovered.id).toBe('daemon-new') + expect(provider.canProvideAuthoritativeBufferSnapshot(recovered.id)).toBe(true) + } finally { + now.mockRestore() + } + }) + + it('coalesces concurrent fresh-spawn recovery probes', async () => { + let resolveProbe: ((healthy: boolean) => void) | undefined + const probeCurrentDaemonSpawn = vi.fn( + () => + new Promise((resolve) => { + resolveProbe = resolve + }) + ) + const provider = new DegradedDaemonPtyProvider({ + current: createDaemonAdapter('daemon'), + legacy: [], + fallback: createProvider('fallback'), + probeCurrentDaemonSpawn + }) + + const first = provider.recoverFreshSpawnRouting() + const second = provider.recoverFreshSpawnRouting() + expect(probeCurrentDaemonSpawn).toHaveBeenCalledOnce() + resolveProbe?.(true) + + await expect(Promise.all([first, second])).resolves.toEqual([true, true]) + await expect(provider.recoverFreshSpawnRouting()).resolves.toBe(true) + expect(probeCurrentDaemonSpawn).toHaveBeenCalledOnce() + }) + + it('does not retain recovered daemon ownership after exit beats the spawn reply', async () => { + const current = createDaemonAdapter('daemon') + const provider = new DegradedDaemonPtyProvider({ + current, + legacy: [], + fallback: createProvider('fallback'), + probeCurrentDaemonSpawn: vi.fn(async () => true) + }) + vi.mocked(current.spawn).mockImplementation(async () => { + current.emitExit('daemon-fast-exit', 0) + return { id: 'daemon-fast-exit', exitedBeforeSpawnReply: true } + }) + + await provider.recoverFreshSpawnRouting() + await expect(provider.spawn({ cols: 80, rows: 24 })).resolves.toMatchObject({ + id: 'daemon-fast-exit', + exitedBeforeSpawnReply: true + }) + + expect(provider.getCurrentDaemonSessionIds()).toEqual([]) + }) + it('routes a previously daemon-backed id to fallback after daemon exit removes the mapping', async () => { const current = createDaemonAdapter('daemon', ['daemon-session']) const fallback = createProvider('fallback') diff --git a/src/main/daemon/degraded-daemon-pty-provider.ts b/src/main/daemon/degraded-daemon-pty-provider.ts index a607495d3b8..e8a584f8cbd 100644 --- a/src/main/daemon/degraded-daemon-pty-provider.ts +++ b/src/main/daemon/degraded-daemon-pty-provider.ts @@ -11,18 +11,22 @@ import type { PtySpawnOptions, PtySpawnResult } from '../providers/types' -import { findDaemonAdapter, listProviderSessionIds } from './degraded-daemon-session-routing' +import { + discoverDegradedDaemonSessions, + findDaemonAdapter, + listProviderSessionIds +} from './degraded-daemon-session-routing' import { probePtyOwners } from './daemon-pty-liveness-probe' +import { DegradedDaemonFreshSpawnRouter } from './degraded-daemon-fresh-spawn-routing' export class DegradedDaemonPtyProvider implements IPtyProvider { - readonly routesFreshSpawnsToLocalProvider = true - // Why: surface that fresh PTYs lack daemon persistence until restart. readonly isDegraded = true private current: DaemonPtyAdapter private legacy: DaemonPtyAdapter[] private fallback: IPtyProvider private sessionProviders = new Map() + private freshSpawns: DegradedDaemonFreshSpawnRouter private unsubscribers: (() => void)[] = [] private dataListeners: ((payload: PtyDataEvent) => void)[] = [] private exitListeners: ((payload: { id: string; code: number }) => void)[] = [] @@ -31,10 +35,17 @@ export class DegradedDaemonPtyProvider implements IPtyProvider { current: DaemonPtyAdapter legacy: DaemonPtyAdapter[] fallback: IPtyProvider + probeCurrentDaemonSpawn?: () => Promise }) { this.current = opts.current this.legacy = opts.legacy this.fallback = opts.fallback + this.freshSpawns = new DegradedDaemonFreshSpawnRouter( + opts.current, + opts.fallback, + this.sessionProviders, + opts.probeCurrentDaemonSpawn ?? null + ) for (const provider of this.allProviders()) { this.unsubscribers.push( @@ -53,30 +64,25 @@ export class DegradedDaemonPtyProvider implements IPtyProvider { } } - async discoverDaemonSessions(): Promise { - for (const adapter of this.allDaemonAdapters()) { - try { - const sessions = await adapter.listProcesses() - for (const session of sessions) { - this.sessionProviders.set(session.id, adapter) - } - } catch (error) { - console.warn('[daemon] Failed to discover degraded daemon sessions', error) - } - } + discoverDaemonSessions(): Promise { + return discoverDegradedDaemonSessions(this.allDaemonAdapters(), this.sessionProviders) } - async spawn(opts: PtySpawnOptions): Promise { - const mapped = opts.sessionId ? this.sessionProviders.get(opts.sessionId) : undefined - const target = mapped ?? this.fallback - const result = await target.spawn(opts) - this.sessionProviders.set(result.id, target) - return result + get routesFreshSpawnsToLocalProvider(): true | undefined { + return this.freshSpawns.routesToFallback } - async attach(id: string): Promise { - await this.providerFor(id).attach(id) - } + recoverFreshSpawnRouting = (): Promise => this.freshSpawns.recover() + + supportsGitCredentialGuardHost = (id?: string): boolean => + this.freshSpawns.supportsGitGuardHost(id) + + canProvideAuthoritativeBufferSnapshot = (id: string): boolean => + this.freshSpawns.canProvideSnapshot(id) + + spawn = (opts: PtySpawnOptions): Promise => this.freshSpawns.spawn(opts) + + attach = (id: string): Promise => this.providerFor(id).attach(id) hasPty(id: string): boolean { const mapped = this.sessionProviders.get(id) @@ -147,9 +153,7 @@ export class DegradedDaemonPtyProvider implements IPtyProvider { return (await this.providerFor(id).getBufferSnapshot?.(id, opts)) ?? null } - async clearBuffer(id: string): Promise { - await this.providerFor(id).clearBuffer(id) - } + clearBuffer = (id: string): Promise => this.providerFor(id).clearBuffer(id) async closeStartupQueryAuthority(id: string): Promise { return (await this.providerFor(id).closeStartupQueryAuthority?.(id)) ?? 0 diff --git a/src/main/daemon/degraded-daemon-session-routing.ts b/src/main/daemon/degraded-daemon-session-routing.ts index 2ff91cf128d..30d934f3834 100644 --- a/src/main/daemon/degraded-daemon-session-routing.ts +++ b/src/main/daemon/degraded-daemon-session-routing.ts @@ -1,6 +1,21 @@ import type { IPtyProvider } from '../providers/types' import type { DaemonPtyAdapter } from './daemon-pty-adapter' +export async function discoverDegradedDaemonSessions( + adapters: readonly DaemonPtyAdapter[], + sessionProviders: Map +): Promise { + for (const adapter of adapters) { + try { + for (const session of await adapter.listProcesses()) { + sessionProviders.set(session.id, adapter) + } + } catch (error) { + console.warn('[daemon] Failed to discover degraded daemon sessions', error) + } + } +} + export function listProviderSessionIds( sessionProviders: ReadonlyMap, provider: IPtyProvider diff --git a/src/main/daemon/headless-emulator-fidelity.fuzz.test.ts b/src/main/daemon/headless-emulator-fidelity.fuzz.test.ts index 3eb708b3cf2..7642e958eec 100644 --- a/src/main/daemon/headless-emulator-fidelity.fuzz.test.ts +++ b/src/main/daemon/headless-emulator-fidelity.fuzz.test.ts @@ -10,10 +10,10 @@ import { POST_REPLAY_LIVE_SNAPSHOT_RESET_PARITY, SNAPSHOT_REPLAY_PREAMBLE_ALT, SNAPSHOT_REPLAY_PREAMBLE_NORMAL, - bufferHasSerializeHostileWrappedRow, createRendererParityTerminal, cursorPosition, normalBufferRowsTrimmed, + visibleRowWraps, visibleRowStyles, visibleRows, writeChunksToTerminal @@ -56,8 +56,6 @@ type FidelityDiff = { stage: string expected: unknown actual: unknown - /** True when the buffer trips the known upstream addon-serialize blank-leading-wrapped-row bug (see bufferHasSerializeHostileWrappedRow). */ - knownSerializeWrapBug?: boolean } function buildCase(seed: number): FidelityCase { @@ -155,9 +153,6 @@ async function runFidelityCase(testCase: FidelityCase): Promise { }) it(`matches an always-visible renderer twin across ${ITERATIONS} seeded agent-TUI streams`, async () => { - // Bug A (serialize wrap) is tolerated + counted so deep mode surfaces only new divergences; B and C are fixed, so their regressions fail loudly. - let knownSerializeWrapBugHits = 0 for (let i = 0; i < ITERATIONS; i++) { const seed = FIXED_SEED ?? 1 + i const testCase = buildCase(seed) const diff = await runFidelityCase(testCase) - if (diff?.knownSerializeWrapBug) { - knownSerializeWrapBugHits += 1 - continue - } if (diff) { const minimized = await minimizeFailure(testCase) const minimizedDiff = await runFidelityCase(minimized) expect.fail(formatFailure(minimized, minimizedDiff ?? diff)) } } - // Guard the tolerance: the predicate tripping on most seeds means the gate has gone degenerate. - expect(knownSerializeWrapBugHits).toBeLessThan(Math.max(3, ITERATIONS * 0.5)) }, 600_000) - // HEADLINE FINDING (do not delete while unfixed upstream): @xterm/addon-serialize 0.15.0-beta.287 - // doesn't round-trip null cells at a soft-wrap boundary, garbling every snapshot restore of a TUI that - // erased inside a soft-wrapped line. Repros below — V1 cell loss (seed 31, SerializeAddon.ts ~L214 - // wrap-validity ternary), V2 stray '-' filler (seed 157). Unskip once the upstream fix lands. - it.skip('round-trips a wrapped line whose continuation row starts with an erased cell', async () => { + it('round-trips a wrapped line whose continuation row starts with an erased cell', async () => { const emulator = new HeadlessEmulator({ cols: 20, rows: 6 }) const control = createRendererParityTerminal({ cols: 20, rows: 6 }) const restored = createRendererParityTerminal({ cols: 20, rows: 6 }) @@ -267,6 +250,9 @@ describe('headless emulator snapshot fidelity fuzz', () => { POST_REPLAY_LIVE_SNAPSHOT_RESET_PARITY ]) expect(visibleRows(restored.terminal)).toEqual(visibleRows(control.terminal)) + expect(visibleRowStyles(restored.terminal)).toEqual(visibleRowStyles(control.terminal)) + expect(visibleRowWraps(restored.terminal)).toEqual(visibleRowWraps(control.terminal)) + expect(cursorPosition(restored.terminal)).toEqual(cursorPosition(control.terminal)) } finally { emulator.dispose() control.terminal.dispose() @@ -274,8 +260,7 @@ describe('headless emulator snapshot fidelity fuzz', () => { } }) - // V2 repro of the headline finding (stray '-' on a fully erased wrapped source row); unskip with V1. - it.skip('round-trips a wrapped line whose source row was fully erased', async () => { + it('round-trips a wrapped line whose source row was fully erased', async () => { const emulator = new HeadlessEmulator({ cols: 20, rows: 6 }) const control = createRendererParityTerminal({ cols: 20, rows: 6 }) const restored = createRendererParityTerminal({ cols: 20, rows: 6 }) @@ -292,8 +277,10 @@ describe('headless emulator snapshot fidelity fuzz', () => { snapshot.rehydrateSequences + snapshot.snapshotAnsi, POST_REPLAY_LIVE_SNAPSHOT_RESET_PARITY ]) - // Fails today: restored row 0 shows '-' where the live row is blank. expect(visibleRows(restored.terminal)).toEqual(visibleRows(control.terminal)) + expect(visibleRowStyles(restored.terminal)).toEqual(visibleRowStyles(control.terminal)) + expect(visibleRowWraps(restored.terminal)).toEqual(visibleRowWraps(control.terminal)) + expect(cursorPosition(restored.terminal)).toEqual(cursorPosition(control.terminal)) } finally { emulator.dispose() control.terminal.dispose() diff --git a/src/main/daemon/hibernation-cold-restore-repro.test.ts b/src/main/daemon/hibernation-cold-restore-repro.test.ts index 561c7de261e..c8e8ea232f4 100644 --- a/src/main/daemon/hibernation-cold-restore-repro.test.ts +++ b/src/main/daemon/hibernation-cold-restore-repro.test.ts @@ -5,6 +5,7 @@ import { mkdtempSync, rmSync } from 'node:fs' import { HistoryManager } from './history-manager' import { HistoryReader } from './history-reader' import { HeadlessEmulator } from './headless-emulator' +import { POST_REPLAY_MODE_RESET } from '../../shared/terminal-mode-reset-profiles' // Reproduces the "blank pane after agent hibernation" bug: alt-screen TUI snapshots have scrollbackAnsi='', so the adapter's // `if (scrollback)` gate (daemon-pty-adapter.ts:230) dropped the cold-restore payload and repainted blank despite an intact snapshotAnsi. @@ -95,9 +96,6 @@ describe('agent hibernation cold-restore (alt-screen TUI)', () => { expect(adapterScrollback).not.toBeNull() // Must end in the normal buffer (no alt-screen re-entry) so it won't fight the agent's own repaint when resume relaunches it. - // POST_REPLAY_MODE_RESET copied literally from renderer layout-serialization.ts (main-process test can't import renderer) — keep in sync. - const POST_REPLAY_MODE_RESET = - '\x1b[0 q\x1b[<99u\x1b[=0u\x1b[?25h\x1b[?9l\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?1016l\x1b[?1004l\x1b[?2004l' const fresh = new HeadlessEmulator({ cols: 80, rows: 24 }) fresh.writeSync('\x1b[2J\x1b[3J\x1b[H') fresh.writeSync(adapterScrollback as string) diff --git a/src/main/daemon/pty-subprocess.test.ts b/src/main/daemon/pty-subprocess.test.ts index fe832e9131f..fdde466e9eb 100644 --- a/src/main/daemon/pty-subprocess.test.ts +++ b/src/main/daemon/pty-subprocess.test.ts @@ -196,6 +196,34 @@ describe('createPtySubprocess', () => { ) }) + it('expands variables in PATH before spawning a Windows shell', () => { + spawnMock.mockReturnValue(mockPtyProcess()) + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { value: 'win32' }) + + try { + createPtySubprocess({ + sessionId: 'test', + cols: 80, + rows: 24, + cwd: 'C:\\repo', + env: { + ORCA_AGENT_TEAMS_TEAM_ID: 'team-test', + ORCA_PATH_ROOT: 'C:\\Users\\orca\\AppData\\Local', + PATH: '%orca_path_root%\\agy\\bin;C:\\Windows' + } + }) + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + expect(spawnMock.mock.calls.at(-1)?.[2].env.PATH).toBe( + 'C:\\Users\\orca\\AppData\\Local\\agy\\bin;C:\\Windows' + ) + }) + it('appends Git prompt guards after the detached daemon inherited config', () => { const proc = mockPtyProcess() spawnMock.mockReturnValue(proc) @@ -2057,8 +2085,10 @@ describe('createPtySubprocess', () => { it('preserves a daemon-owned custom Codex home while deleting a stale private marker', () => { const proc = mockPtyProcess() spawnMock.mockReturnValue(proc) + const platform = Object.getOwnPropertyDescriptor(process, 'platform') const previousCodexHome = process.env.CODEX_HOME const previousOrcaCodexHome = process.env.ORCA_CODEX_HOME + Object.defineProperty(process, 'platform', { value: 'linux' }) process.env.CODEX_HOME = '/daemon/user/codex-home' process.env.ORCA_CODEX_HOME = '/daemon/stale/managed-home' @@ -2071,6 +2101,9 @@ describe('createPtySubprocess', () => { envToDelete: ['ORCA_CODEX_HOME'] }) } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } if (previousCodexHome === undefined) { delete process.env.CODEX_HOME } else { @@ -2113,6 +2146,77 @@ describe('createPtySubprocess', () => { expect(lastCall[2].env.ORCA_ATTRIBUTION_SHIM_DIR).toBeUndefined() }) + it('collapses its own env merge onto the requested Windows `Path` spelling', () => { + const proc = mockPtyProcess() + spawnMock.mockReturnValue(proc) + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + + Object.defineProperty(process, 'platform', { value: 'win32' }) + try { + createPtySubprocess({ + sessionId: 'test', + cols: 80, + rows: 24, + // Why: buildPtyHostEnv collapses Windows PATH onto one spelling before the daemon wire; + // the daemon then spreads its own block underneath and can re-mint the other one. + env: { + Path: '/tmp/orca-agent-teams-bin:/usr/bin', + ORCA_AGENT_TEAMS_TEAM_ID: 'team-test' + } + }) + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + const env = spawnMock.mock.calls.at(-1)![2].env + expect(Object.keys(env).filter((key) => /^path$/i.test(key))).toEqual(['Path']) + expect(env.Path.split(':')[0]).toBe('/tmp/orca-agent-teams-bin') + }) + + it('keeps the daemon `PATH` block when the requested env has no path key', () => { + const proc = mockPtyProcess() + spawnMock.mockReturnValue(proc) + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + + Object.defineProperty(process, 'platform', { value: 'win32' }) + try { + createPtySubprocess({ sessionId: 'test', cols: 80, rows: 24, env: { FOO: 'bar' } }) + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + const env = spawnMock.mock.calls.at(-1)![2].env + expect(env.PATH).toBe(process.env.PATH) + }) + + it('preserves a duplicated path block supplied by main', () => { + const proc = mockPtyProcess() + spawnMock.mockReturnValue(proc) + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + + Object.defineProperty(process, 'platform', { value: 'win32' }) + try { + createPtySubprocess({ + sessionId: 'test', + cols: 80, + rows: 24, + env: { PATH: 'C:\\Live', Path: 'C:\\Shadowed' } + }) + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + const env = spawnMock.mock.calls.at(-1)![2].env + expect(env.PATH).toBe('C:\\Live') + expect(env.Path).toBe('C:\\Shadowed') + }) + it('combines HOMEDRIVE and HOMEPATH for Windows default cwd', () => { const proc = mockPtyProcess() spawnMock.mockReturnValue(proc) diff --git a/src/main/daemon/pty-subprocess.ts b/src/main/daemon/pty-subprocess.ts index 3978dc9f884..ca8527fb11f 100644 --- a/src/main/daemon/pty-subprocess.ts +++ b/src/main/daemon/pty-subprocess.ts @@ -32,6 +32,7 @@ import { isHostCodexHomeForWsl, isWslCodexHomeForHost } from '../pty/codex-home- import { removeInheritedNoColor } from '../pty/terminal-color-env' import { removeAppImageRuntimeEnv } from '../pty/appimage-terminal-env' import { stripInheritedBuildModeEnv } from '../pty/build-mode-env' +import { resolvePathEnvKey } from '../pty/windows-environment-path' import { parseWslPath } from '../wsl' import { addWslEnvKeys } from '../wsl-env' import { @@ -65,7 +66,12 @@ import { getAgentForegroundContextPaths } from '../providers/agent-foreground-co import { assertSafeAgentStartupCwd, resolveSafePtyDefaultCwd } from '../providers/pty-default-cwd' import { ORCA_HERMES_STARTUP_QUERY_ENV } from '../../shared/hermes-startup-query' import type { TuiAgent } from '../../shared/types' +import { + expandWindowsEnvironmentVariables, + expandWindowsPathEnvironmentVariables +} from '../../shared/windows-environment-expansion' import { forceKillPosixPtyProcessGroups } from '../pty/posix-pty-process-groups' +import { readPtySlavePath } from '../../shared/pty-slave-line-discipline-echo' const PANE_IDENTITY_ENV_KEYS = [ 'ORCA_PANE_KEY', @@ -73,6 +79,7 @@ const PANE_IDENTITY_ENV_KEYS = [ 'ORCA_WORKTREE_ID', 'ORCA_AGENT_LAUNCH_TOKEN' ] as const +const WINDOWS_PATH_ENV_KEY_RE = /^path$/i const FOREGROUND_AGENT_CACHE_TTL_MS = 1000 const SHELL_FOREGROUND_REFRESH_RETRY_MS = 5_000 // Why: a Windows refresh forks a heavy powershell.exe CIM scan (~10-40x POSIX `ps`); idle shells retry slower, output re-arms the fast retry. @@ -161,6 +168,36 @@ function removeUnspecifiedPaneIdentityEnv( } } +/** Removes the second PATH key only when the daemon's env merge created it. */ +function collapseWindowsPathEnvKeys( + env: Record, + requestedEnv: Record | undefined +): void { + if (process.platform !== 'win32') { + return + } + const pathKeys = Object.keys(env).filter((key) => WINDOWS_PATH_ENV_KEY_RE.test(key)) + if (pathKeys.length < 2) { + return + } + // Why: a one-key main patch is authoritative; zero or two keys came from inherited state. + const requestedKeys = requestedEnv + ? Object.keys(requestedEnv).filter((key) => WINDOWS_PATH_ENV_KEY_RE.test(key)) + : [] + if (requestedKeys.length !== 1) { + return + } + const survivingKey = requestedKeys[0] + if (!survivingKey || env[survivingKey] === undefined) { + return + } + for (const key of pathKeys) { + if (key !== survivingKey) { + delete env[key] + } + } +} + /** * Promotes the agent-teams shim path ahead of inherited PATH entries. */ @@ -171,12 +208,18 @@ function promoteAgentTeamsShimPath( if (!env.ORCA_AGENT_TEAMS_TEAM_ID || !requestedPath) { return } - const shimDir = requestedPath.split(delimiter)[0] + const normalizedRequestedPath = + process.platform === 'win32' + ? expandWindowsEnvironmentVariables(requestedPath, env) + : requestedPath + const pathDelimiter = process.platform === 'win32' ? ';' : delimiter + const shimDir = normalizedRequestedPath.split(pathDelimiter)[0] if (!shimDir) { return } - const currentParts = env.PATH?.split(delimiter).filter(Boolean) ?? [] - env.PATH = [shimDir, ...currentParts.filter((part) => part !== shimDir)].join(delimiter) + const pathKey = resolvePathEnvKey(env, process.platform) + const currentParts = env[pathKey]?.split(pathDelimiter).filter(Boolean) ?? [] + env[pathKey] = [shimDir, ...currentParts.filter((part) => part !== shimDir)].join(pathDelimiter) } /** @@ -582,7 +625,6 @@ export function createPtySubprocess(opts: PtySubprocessOptions): SubprocessHandl removeInheritedNoColor(env) env.LANG ??= 'en_US.UTF-8' - // Why: shellOverride must win over env.COMSPEC, or Windows always resolves to cmd.exe/PowerShell regardless of the user's pick. const resolvedWslContext = resolveWslSessionContext(opts) // Why: older persisted tabs can carry a PowerShell/cmd shellOverride; ignore it so WSL reconnects still enter the distro. @@ -768,7 +810,14 @@ export function createPtySubprocess(opts: PtySubprocessOptions): SubprocessHandl ) { addWslEnvKeys(env, [POWERLEVEL10K_WIZARD_DISABLE_ENV]) } - promoteAgentTeamsShimPath(env, opts.env?.PATH) + const requestedEnv = opts.env + expandWindowsPathEnvironmentVariables(env) + // Why: collapse before promoting so the shim lands on the spelling the child actually inherits. + collapseWindowsPathEnvKeys(env, requestedEnv) + const requestedPath = requestedEnv + ? requestedEnv[resolvePathEnvKey(requestedEnv, process.platform)] + : undefined + promoteAgentTeamsShimPath(env, requestedPath) // Why: asar packaging can strip +x from node-pty's spawn-helper; the daemon is a separate forked process from the main-process fix. ensureNodePtySpawnHelperExecutable() @@ -991,9 +1040,11 @@ export function createPtySubprocess(opts: PtySubprocessOptions): SubprocessHandl } }) + const slavePath = readPtySlavePath(proc) return { pid: proc.pid, shellPath, + ...(slavePath ? { slavePath } : {}), ...(startupCommandDeliveredInShellArgs ? { startupCommandDeliveredInShellArgs: true } : {}), getForegroundProcess: () => { // Why: node-pty's `.process` reports the live foreground name but reads a recycled pid on a reaped pty, so bail when dead. diff --git a/src/main/daemon/repro-12101-mouse-tracking-survives-agent-death.test.ts b/src/main/daemon/repro-12101-mouse-tracking-survives-agent-death.test.ts new file mode 100644 index 00000000000..0e99e002941 --- /dev/null +++ b/src/main/daemon/repro-12101-mouse-tracking-survives-agent-death.test.ts @@ -0,0 +1,274 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { mkdtempSync, rmSync } from 'node:fs' +import { Terminal } from '@xterm/headless' +import { Session } from './session' +import { HistoryManager } from './history-manager' +import { HistoryReader } from './history-reader' +import { getRecoveredHistorySeedSegments } from './terminal-history-seed-segments' +import { iterateTerminalHistorySeedChunks } from './terminal-history-seed-chunks' + +// Repro for #12101: a TUI that armed DECSET mouse tracking (Claude Code, vim, +// htop) is force-killed and never emits the matching DECRST. Nothing in the +// daemon substitutes the reset, so `TerminalModes.mouseTracking` is latched into +// the on-disk checkpoint and then re-derived — from the DEAD process's own bytes — +// into every subsequent fresh emulator. The revived pane runs a bare shell that +// never armed mouse reporting, yet its snapshot re-arms it, so pointer motion +// echoes literal SGR reports (^[[<35;col;rowM) into the prompt. +// +// This drives the REAL Session / HeadlessEmulator / TerminalMouseModeMirror / +// buildRehydrateSequences / HistoryManager / HistoryReader, with a fake +// subprocess standing in for node-pty (a real PTY can't be SIGKILLed +// deterministically mid-DECSET in vitest). The kill goes through Session.kill()'s +// real teardown; only killWithDescendantSweep is stubbed so the test never +// signals a real pid. + +const killWithDescendantSweepMock = vi.hoisted(() => vi.fn()) +vi.mock('../pty-descendant-termination', () => ({ + killWithDescendantSweep: killWithDescendantSweepMock +})) + +// The variant `reattachReplayResetSequence` picks when the pane still looks like a +// live agent, which is exactly the stale state a SIGKILLed agent leaves behind: it +// deliberately OMITS RESET_MOUSE_REPORTING to keep real TUI scroll gestures alive. +import { POST_REPLAY_LIVE_AGENT_REATTACH_RESET } from '../../shared/terminal-mode-reset-profiles' + +const ANY_MOTION_TRACKING_ON = '\x1b[?1003h' +const SGR_ENCODING_ON = '\x1b[?1006h' +const ANY_MOTION_TRACKING_OFF = '\x1b[?1003l' +const SGR_ENCODING_OFF = '\x1b[?1006l' + +function createFakeSubprocess(foregroundProcess: string) { + let onData: ((data: string) => void) | null = null + let onExit: ((code: number) => void) | null = null + const written: string[] = [] + const signals: string[] = [] + return { + written, + signals, + forceKilled: false, + pid: 4242, + getForegroundProcess: () => foregroundProcess, + write: (data: string) => void written.push(data), + resize: () => {}, + kill: () => {}, + forceKill(this: { forceKilled: boolean }) { + this.forceKilled = true + }, + signal: (sig: string) => void signals.push(sig), + onData: (cb: (data: string) => void) => void (onData = cb), + onExit: (cb: (code: number) => void) => void (onExit = cb), + dispose: () => {}, + /** PTY output — same channel node-pty uses, so Session's real ingest runs. */ + emit: (data: string) => onData?.(data), + /** SIGKILL reaped: exit fires with no DECRST ever sent. */ + simulateKilledExit: () => onExit?.(-1) + } +} + +/** Session.emitSubprocessOutput awaits xterm's async parse; poll until the + * emulator has committed the bytes so snapshots are taken on a settled stream. */ +async function waitForEmulatorParse(session: Session): Promise { + for (let i = 0; i < 200; i += 1) { + await new Promise((resolve) => setTimeout(resolve, 1)) + if (session.getSnapshot()?.snapshotAnsi.includes('$ ')) { + return + } + } + throw new Error('setup: emulator never parsed the agent output') +} + +describe('#12101 mouse tracking survives the death of the process that armed it', () => { + let dir: string + const sessionId = 'repo-1::/Users/dev/feature-branch' + + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), 'repro-12101-')) + killWithDescendantSweepMock.mockReset() + }) + + afterEach(() => { + rmSync(dir, { recursive: true, force: true }) + vi.useRealTimers() + }) + + it('re-arms mouse reporting in the fresh shell that replaces a force-killed agent', async () => { + const manager = new HistoryManager(dir) + const reader = new HistoryReader(dir) + + // 1. A live agent TUI arms any-motion tracking + SGR encoding. + const agentPty = createFakeSubprocess('claude') + const agent = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: agentPty, + launchAgent: 'claude', + shellReadySupported: false + }) + agentPty.emit(`${ANY_MOTION_TRACKING_ON}${SGR_ENCODING_ON}`) + agentPty.emit('user@host ~ % claude\r\nclaude> analyzing...\r\nuser@host ~ $ ') + await waitForEmulatorParse(agent) + + const armed = agent.getSnapshot() + expect(armed?.modes.mouseTracking).toBe(true) + expect(armed?.modes.mouseTrackingMode).toBe('any') + expect(armed?.rehydrateSequences).toContain(ANY_MOTION_TRACKING_ON) + + // 2. Sleep/hibernation takes its final teardown checkpoint while the agent + // is still alive with mouse armed (daemon-pty-adapter's {final,teardown}). + await manager.openSession(sessionId, { cwd: '/Users/dev/feature-branch', cols: 80, rows: 24 }) + await manager.checkpoint(sessionId, armed!) + + // 3. Force-kill. Real Session teardown; the child is reaped without ever + // emitting DECRST, and nothing writes one on its behalf. + agent.kill() + agentPty.simulateKilledExit() + agent.dispose() // TerminalHost.reapSession + expect(killWithDescendantSweepMock).toHaveBeenCalled() + const teardownBytes = agentPty.written.join('') + expect(teardownBytes).not.toContain(ANY_MOTION_TRACKING_OFF) + expect(teardownBytes).not.toContain(SGR_ENCODING_OFF) + + // 4. Wake: the session is still cold-restore eligible (killed with + // keepHistory, so endedAt stays null) and a FRESH shell takes its place, + // seeded with the recovered history exactly as daemon-server does. + const restoreInfo = await reader.detectColdRestore(sessionId) + expect(restoreInfo).not.toBeNull() + const seedChunks = [ + ...iterateTerminalHistorySeedChunks(getRecoveredHistorySeedSegments(restoreInfo!)) + ] + + const shellPty = createFakeSubprocess('zsh') + const shell = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: shellPty, + shellReadySupported: false, + historySeedChunks: seedChunks + }) + const revived = shell.getSnapshot() + try { + // #12101: the replacement shell's OWN state says mouse tracking is on, + // so every snapshot it serves — reattach, checkpoint, mobile — re-arms it. + // Soft so one run reports both re-arming channels, not just the first. + expect.soft(revived?.modes.mouseTracking).toBe(false) + expect.soft(revived?.modes.mouseTrackingMode).toBe('none') + expect.soft(revived?.rehydrateSequences).toBe('') + // Independent second channel: SerializeAddon's own mode trailer re-emits + // the DECSET from xterm's mouseTrackingMode, so dropping rehydrate alone + // would not disarm the pane. + expect.soft(revived?.snapshotAnsi).not.toContain(ANY_MOTION_TRACKING_ON) + } finally { + shell.dispose() + } + }) + + it('leaves the reattached renderer xterm armed against a dead agent (SGR reports into the prompt)', async () => { + const manager = new HistoryManager(dir) + const reader = new HistoryReader(dir) + + const agentPty = createFakeSubprocess('claude') + const agent = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: agentPty, + launchAgent: 'claude', + shellReadySupported: false + }) + agentPty.emit(`${ANY_MOTION_TRACKING_ON}${SGR_ENCODING_ON}`) + agentPty.emit('user@host ~ $ ') + await waitForEmulatorParse(agent) + + await manager.openSession(sessionId, { cwd: '/Users/dev/feature-branch', cols: 80, rows: 24 }) + await manager.checkpoint(sessionId, agent.getSnapshot()!) + agent.kill() + agentPty.simulateKilledExit() + agent.dispose() + + const restoreInfo = await reader.detectColdRestore(sessionId) + const shellPty = createFakeSubprocess('zsh') + const shell = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: shellPty, + shellReadySupported: false, + historySeedChunks: [ + ...iterateTerminalHistorySeedChunks(getRecoveredHistorySeedSegments(restoreInfo!)) + ] + }) + const revived = shell.getSnapshot()! + + // Reattach paint into a REAL renderer xterm, using the weakest profile in the + // family — the one a stale agent title used to select here. The renderer now + // forces the fresh-shell reset on a cold restore, so this pins the independent + // half: the seed alone must leave the revived session unarmed, because the + // daemon emulator's own state is what mobile and every other consumer read. + const term = new Terminal({ cols: 80, rows: 24, allowProposedApi: true }) + try { + await new Promise((resolve) => term.write('\x1b[2J\x1b[3J\x1b[H', resolve)) + await new Promise((resolve) => + term.write(revived.rehydrateSequences + revived.snapshotAnsi, resolve) + ) + await new Promise((resolve) => + term.write(POST_REPLAY_LIVE_AGENT_REATTACH_RESET, resolve) + ) + // The observable symptom: a bare `zsh` pane whose xterm reports pointer + // motion, so every mouse move types ^[[<35;col;rowM at the prompt. + expect(term.modes.mouseTrackingMode).toBe('none') + } finally { + term.dispose() + shell.dispose() + } + }) + + it('control: a TUI that DID emit DECRST before exiting restores a clean shell', async () => { + const manager = new HistoryManager(dir) + const reader = new HistoryReader(dir) + + const agentPty = createFakeSubprocess('vim') + const agent = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: agentPty, + shellReadySupported: false + }) + agentPty.emit(`${ANY_MOTION_TRACKING_ON}${SGR_ENCODING_ON}`) + agentPty.emit('user@host ~ $ ') + await waitForEmulatorParse(agent) + agentPty.emit(`${ANY_MOTION_TRACKING_OFF}${SGR_ENCODING_OFF}`) + for (let i = 0; i < 50 && agent.getSnapshot()?.modes.mouseTracking !== false; i += 1) { + await new Promise((resolve) => setTimeout(resolve, 1)) + } + + await manager.openSession(sessionId, { cwd: '/Users/dev/feature-branch', cols: 80, rows: 24 }) + await manager.checkpoint(sessionId, agent.getSnapshot()!) + agent.kill() + agentPty.simulateKilledExit() + agent.dispose() + + const restoreInfo = await reader.detectColdRestore(sessionId) + const shellPty = createFakeSubprocess('zsh') + const shell = new Session({ + sessionId, + cols: 80, + rows: 24, + subprocess: shellPty, + shellReadySupported: false, + historySeedChunks: [ + ...iterateTerminalHistorySeedChunks(getRecoveredHistorySeedSegments(restoreInfo!)) + ] + }) + try { + expect(shell.getSnapshot()?.modes.mouseTracking).toBe(false) + expect(shell.getSnapshot()?.rehydrateSequences).toBe('') + } finally { + shell.dispose() + } + }) +}) diff --git a/src/main/daemon/repro-7329-remote-snapshot-corruption.test.ts b/src/main/daemon/repro-7329-remote-snapshot-corruption.test.ts index 8f8256519a4..d42fa33edaf 100644 --- a/src/main/daemon/repro-7329-remote-snapshot-corruption.test.ts +++ b/src/main/daemon/repro-7329-remote-snapshot-corruption.test.ts @@ -1,6 +1,8 @@ import { describe, expect, it } from 'vitest' import { Terminal } from '@xterm/headless' import { HeadlessEmulator } from './headless-emulator' +// The reattach path the remote onSnapshot uses. +import { POST_REPLAY_REATTACH_RESET } from '../../shared/terminal-mode-reset-profiles' // Repro for #7329: "remote server + terminal" — typing gets escape sequences // injected/wrapped around it and follow-up commands are corrupted. @@ -11,12 +13,6 @@ import { HeadlessEmulator } from './headless-emulator' // This test drives the REAL daemon serializer and a REAL renderer-side xterm to // see what the user's terminal ends up looking like after a subscribe/reattach. -const RESET_TERMINAL_CURSOR_STYLE = '\x1b[0 q' -const RESET_KITTY_KEYBOARD_PROTOCOL = '\x1b[<99u\x1b[=0u' -const RESET_MOUSE_REPORTING = '\x1b[?9l\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?1016l' -// Verbatim from layout-serialization.ts (the reattach path the remote onSnapshot uses). -const POST_REPLAY_REATTACH_RESET = `${RESET_TERMINAL_CURSOR_STYLE}${RESET_KITTY_KEYBOARD_PROTOCOL}\x1b[?25h${RESET_MOUSE_REPORTING}\x1b[?1004l` - function writeXterm(term: Terminal, data: string): Promise { return new Promise((resolve) => term.write(data, resolve)) } diff --git a/src/main/daemon/session.ts b/src/main/daemon/session.ts index 7d96484edea..d9c5553d3e8 100644 --- a/src/main/daemon/session.ts +++ b/src/main/daemon/session.ts @@ -26,6 +26,7 @@ import type { TerminalSnapshot } from './types' import type { PtyOwnerBackend } from '../../shared/pty-owner-backend' +import { createPtySlaveEchoProbe } from '../../shared/pty-slave-line-discipline-echo' const SHELL_READY_TIMEOUT_MS = 15_000 // Why: Codex skips marker-gated command delivery; this only bounds older daemon/local paths that still report shell-ready for Codex. @@ -53,6 +54,9 @@ export type SubprocessHandle = { /** Shell the subprocess actually spawned, after fallbacks. The host reconciles the caller's shell-ready * assumption against it so a fallback shell without a ready marker never gates startup commands. */ shellPath?: string + /** Slave device path, so startup replies can read the line discipline's ECHO bit before + * writing. Absent on handles with no POSIX slave to read (ConPTY, tests). */ + slavePath?: string write(data: string): void resize(cols: number, rows: number): void /** Stop reading the PTY fd (node-pty pause()) so a flooding child blocks on write. Optional: @@ -164,11 +168,13 @@ export class Session { } this.postReadyFlushGate = new PostReadyFlushGate(() => this.flushPreReadyQueue()) + const echoProbe = createPtySlaveEchoProbe(this.subprocess.slavePath) this.startupIngress = new PtyStartupIngress({ ...(opts.startupIngress ? { intent: opts.startupIngress } : {}), ...(opts.ownerBackend ? { ownerBackend: opts.ownerBackend } : {}), write: (data) => this.subprocess.write(data), - onEmission: (emission) => this.emitSubprocessOutput(emission) + onEmission: (emission) => this.emitSubprocessOutput(emission), + ...(echoProbe ? { echoProbe } : {}) }) this.subprocess.onData((data) => this.handleSubprocessData(data)) this.subprocess.onExit((code) => this.handleSubprocessExit(code)) diff --git a/src/main/daemon/terminal-history-seed-segments.test.ts b/src/main/daemon/terminal-history-seed-segments.test.ts new file mode 100644 index 00000000000..7852a7eac89 --- /dev/null +++ b/src/main/daemon/terminal-history-seed-segments.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, it } from 'vitest' +import { HeadlessEmulator } from './headless-emulator' +import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences' +import { getRecoveredHistorySeedSegments } from './terminal-history-seed-segments' +import { COLD_RESTORE_SEED_MODE_RESET } from '../../shared/terminal-mode-reset-profiles' +import type { ColdRestoreInfo } from './terminal-history-cold-restore-info' +import type { TerminalModes } from './types' + +const ARMED_MODES: TerminalModes = { + bracketedPaste: false, + mouseTracking: true, + mouseTrackingMode: 'any', + sgrMouseMode: true, + applicationCursor: false, + alternateScreen: false +} + +// Why import rather than restate: the exact bytes are pinned in +// terminal-mode-reset-profiles.test.ts; this suite pins placement within the seed. +const MOUSE_OFF = COLD_RESTORE_SEED_MODE_RESET + +function restoreInfo(overrides: Partial = {}): ColdRestoreInfo { + return { + snapshotAnsi: 'user@host ~ $ \x1b[?1003h', + scrollbackAnsi: 'user@host ~ $ ', + rehydrateSequences: buildRehydrateSequences(ARMED_MODES), + cwd: '/w', + cols: 80, + rows: 24, + modes: ARMED_MODES, + ...overrides + } +} + +describe('getRecoveredHistorySeedSegments', () => { + it('disarms mouse reporting after the snapshot but before the torn escape tail', () => { + const segments = getRecoveredHistorySeedSegments( + restoreInfo({ pendingEscapeTailAnsi: '\x1b[3' }) + ) + expect(segments).toEqual([ + '\x1b[?1003h\x1b[?1006h', + 'user@host ~ $ \x1b[?1003h', + MOUSE_OFF, + '\x1b[3' + ]) + }) + + it('disarms mouse reporting on the alt-screen normal-buffer branch too', () => { + expect( + getRecoveredHistorySeedSegments( + restoreInfo({ modes: { ...ARMED_MODES, alternateScreen: true } }) + ) + ).toEqual(['user@host ~ $ ', MOUSE_OFF]) + }) + + it('stays empty when there is no recovered normal buffer', () => { + expect( + getRecoveredHistorySeedSegments( + restoreInfo({ + modes: { ...ARMED_MODES, alternateScreen: true }, + scrollbackAnsi: '', + snapshotAnsi: '' + }) + ) + ).toEqual([]) + }) + + it('keeps the empty "nothing to recover" sentinel on the normal-screen branch', () => { + // Why: daemon-pty-adapter keys the probe-race kill+respawn and the history + // re-anchor on `length === 0`, so the reset must never be the only segment. + expect( + getRecoveredHistorySeedSegments( + restoreInfo({ + modes: { ...ARMED_MODES, mouseTracking: false, mouseTrackingMode: 'none' }, + scrollbackAnsi: '', + snapshotAnsi: '', + rehydrateSequences: '' + }) + ) + ).toEqual([]) + }) + + it('keeps a torn escape last when it is the only recovered data', () => { + expect( + getRecoveredHistorySeedSegments( + restoreInfo({ + scrollbackAnsi: '', + snapshotAnsi: '', + rehydrateSequences: '', + pendingEscapeTailAnsi: '\x1b[3' + }) + ) + ).toEqual([MOUSE_OFF, '\x1b[3']) + }) + + it('leaves the revived emulator unarmed while preserving scrollback (#12101)', () => { + const emulator = new HeadlessEmulator({ cols: 80, rows: 24 }) + try { + for (const segment of getRecoveredHistorySeedSegments(restoreInfo())) { + expect(emulator.writeSync(segment)).toBe(true) + } + const snapshot = emulator.getSnapshot() + expect(snapshot.modes.mouseTracking).toBe(false) + expect(snapshot.modes.mouseTrackingMode).toBe('none') + expect(snapshot.modes.sgrMouseMode).toBe(false) + expect(snapshot.rehydrateSequences).toBe('') + expect(snapshot.snapshotAnsi).not.toContain('\x1b[?1003h') + expect(snapshot.snapshotAnsi).toContain('user@host ~ $') + } finally { + emulator.dispose() + } + }) + + it('does not touch the live-session reattach payload (mobile scroll gestures)', () => { + // Why: only recovery seeding knows the arming TUI is dead; live reattach + // snapshots must keep re-arming or an alt-screen TUI loses scroll forever. + expect(buildRehydrateSequences(ARMED_MODES)).toBe('\x1b[?1003h\x1b[?1006h') + }) +}) diff --git a/src/main/daemon/terminal-history-seed-segments.ts b/src/main/daemon/terminal-history-seed-segments.ts index 78732e81931..670cef152b8 100644 --- a/src/main/daemon/terminal-history-seed-segments.ts +++ b/src/main/daemon/terminal-history-seed-segments.ts @@ -1,13 +1,29 @@ import type { ColdRestoreInfo } from './terminal-history-cold-restore-info' +import { COLD_RESTORE_SEED_MODE_RESET } from '../../shared/terminal-mode-reset-profiles' + +// Why the reset belongs in the seed and not only at replay: the recovered stream +// re-arms mouse reporting from two independent sources (rehydrateSequences AND +// SerializeAddon's own mode trailer inside snapshotAnsi), and the seed is what +// feeds the daemon's emulator — so without it every downstream consumer that +// re-serializes from that emulator, including mobile, inherits the dead TUI's +// modes no matter which profile the desktop renderer applies. See +// COLD_RESTORE_SEED_MODE_RESET for the precondition and the choice of bits. export function getRecoveredHistorySeedSegments(restoreInfo: ColdRestoreInfo): readonly string[] { if (restoreInfo.modes.alternateScreen) { const normalBuffer = restoreInfo.scrollbackAnsi || restoreInfo.snapshotAnsi - return normalBuffer ? [normalBuffer] : [] + return normalBuffer ? [normalBuffer, COLD_RESTORE_SEED_MODE_RESET] : [] } - return [ - restoreInfo.rehydrateSequences, - restoreInfo.snapshotAnsi, - ...(restoreInfo.pendingEscapeTailAnsi ? [restoreInfo.pendingEscapeTailAnsi] : []) - ].filter((segment) => segment.length > 0) + const recovered = [restoreInfo.rehydrateSequences, restoreInfo.snapshotAnsi].filter( + (segment) => segment.length > 0 + ) + const escapeTail = restoreInfo.pendingEscapeTailAnsi + // Why: an empty list is daemon-pty-adapter's "nothing to recover" sentinel (it gates + // the probe-race respawn and the history re-anchor), so the reset must never pad it. + if (recovered.length === 0 && !escapeTail) { + return [] + } + // Why after the snapshot: it must undo the snapshot's own mode trailer, and + // pendingEscapeTailAnsi is a torn escape that has to stay at the very end. + return [...recovered, COLD_RESTORE_SEED_MODE_RESET, ...(escapeTail ? [escapeTail] : [])] } diff --git a/src/main/daemon/terminal-host-agent-session-claim.ts b/src/main/daemon/terminal-host-agent-session-claim.ts index b9fc70cf47b..cea1c925dd7 100644 --- a/src/main/daemon/terminal-host-agent-session-claim.ts +++ b/src/main/daemon/terminal-host-agent-session-claim.ts @@ -4,7 +4,6 @@ import type { CreateOrAttachOptions, CreateOrAttachResult } from './terminal-hos export type InternalCreateOrAttachOptions = CreateOrAttachOptions & { agentSessionGeneration?: string - attachOnly?: boolean } export async function createOrAttachClaimedAgentSession(args: { diff --git a/src/main/daemon/terminal-host-attach-only.test.ts b/src/main/daemon/terminal-host-attach-only.test.ts new file mode 100644 index 00000000000..b99dd40b64e --- /dev/null +++ b/src/main/daemon/terminal-host-attach-only.test.ts @@ -0,0 +1,68 @@ +import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' +import type { SubprocessHandle } from './session' +import { TerminalHost, type TerminalHostOptions } from './terminal-host' + +type SpawnSubprocess = TerminalHostOptions['spawnSubprocess'] + +describe('TerminalHost attach-only sessions', () => { + let host: TerminalHost + let spawnSubprocess: Mock + + beforeEach(() => { + spawnSubprocess = vi.fn(() => { + let onExit: ((code: number) => void) | undefined + return { + pid: 99999, + getForegroundProcess: vi.fn(() => null), + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(() => onExit?.(0)), + forceKill: vi.fn(() => onExit?.(137)), + signal: vi.fn(), + onData: vi.fn(), + onExit: vi.fn((callback) => { + onExit = callback + }), + dispose: vi.fn() + } as SubprocessHandle + }) + host = new TerminalHost({ spawnSubprocess }) + }) + + afterEach(async () => { + await host.dispose() + }) + + it('attaches only to an existing stable session', async () => { + await host.createOrAttach({ + sessionId: 'stable-pane-session', + cols: 80, + rows: 24, + streamClient: { onData: vi.fn(), onExit: vi.fn() } + }) + + const result = await host.createOrAttach({ + sessionId: 'stable-pane-session', + cols: 120, + rows: 40, + attachOnly: true, + streamClient: { onData: vi.fn(), onExit: vi.fn() } + }) + + expect(result.isNew).toBe(false) + expect(spawnSubprocess).toHaveBeenCalledOnce() + }) + + it('does not create when an attach-only stable session is absent', async () => { + await expect( + host.createOrAttach({ + sessionId: 'missing-stable-pane-session', + cols: 80, + rows: 24, + attachOnly: true, + streamClient: { onData: vi.fn(), onExit: vi.fn() } + }) + ).rejects.toThrow('Session not found: missing-stable-pane-session') + expect(spawnSubprocess).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/daemon/terminal-host-create-contract.ts b/src/main/daemon/terminal-host-create-contract.ts index 3a3e9b1c904..114aae91ad2 100644 --- a/src/main/daemon/terminal-host-create-contract.ts +++ b/src/main/daemon/terminal-host-create-contract.ts @@ -19,6 +19,8 @@ export type CreateOrAttachOptions = { command?: string startupCommandDelivery?: StartupCommandDelivery launchAgent?: TuiAgent + /** Missing ownership is not permission to create during stable-pane adoption. */ + attachOnly?: boolean /** Explicit shell the renderer asked for, forwarded to the subprocess. */ shellOverride?: string terminalWindowsWslDistro?: string | null diff --git a/src/main/daemon/terminal-snapshot-color-parity.test.ts b/src/main/daemon/terminal-snapshot-color-parity.test.ts new file mode 100644 index 00000000000..576a20db431 --- /dev/null +++ b/src/main/daemon/terminal-snapshot-color-parity.test.ts @@ -0,0 +1,202 @@ +import { describe, expect, it } from 'vitest' +import { + POST_REPLAY_LIVE_SNAPSHOT_RESET_PARITY, + SNAPSHOT_REPLAY_PREAMBLE_ALT, + SNAPSHOT_REPLAY_PREAMBLE_NORMAL, + buildParityMainBufferSnapshot, + createRendererParityTerminal, + cursorPosition, + normalBufferRowsTrimmed, + normalBufferStylesTrimmed, + visibleRowStyles, + visibleRowWraps, + visibleRows, + writeChunksToTerminal +} from '../../shared/terminal-restore-parity-fixture' + +type ParityTerminal = ReturnType + +async function restoreSerializedTerminal(source: ParityTerminal): Promise { + const snapshot = buildParityMainBufferSnapshot(source, 1, { scrollbackRows: 5000 }) + const restored = createRendererParityTerminal({ cols: snapshot.cols, rows: snapshot.rows }) + const preamble = + snapshot.alternateScreen && snapshot.scrollbackAnsi !== undefined + ? `\x1b[?1049l\x1b[2J\x1b[3J\x1b[H${snapshot.scrollbackAnsi}${SNAPSHOT_REPLAY_PREAMBLE_ALT}` + : snapshot.alternateScreen + ? SNAPSHOT_REPLAY_PREAMBLE_ALT + : SNAPSHOT_REPLAY_PREAMBLE_NORMAL + await writeChunksToTerminal(restored.terminal, [ + preamble, + snapshot.data, + POST_REPLAY_LIVE_SNAPSHOT_RESET_PARITY + ]) + return restored +} + +function expectActiveBufferParity(source: ParityTerminal, restored: ParityTerminal): void { + expect(visibleRows(restored.terminal)).toEqual(visibleRows(source.terminal)) + expect(visibleRowStyles(restored.terminal)).toEqual(visibleRowStyles(source.terminal)) + expect(visibleRowWraps(restored.terminal)).toEqual(visibleRowWraps(source.terminal)) + expect(cursorPosition(restored.terminal)).toEqual(cursorPosition(source.terminal)) +} + +describe('terminal snapshot color parity', () => { + it('preserves Codex truecolor backgrounds, BCE rows, and default trailing cells', async () => { + const source = createRendererParityTerminal({ cols: 24, rows: 6 }) + let restored: ParityTerminal | undefined + try { + await writeChunksToTerminal(source.terminal, [ + '\x1b[48;2;33;58;43m\x1b[2K\x1b[0m', + '\x1b[2;1H\x1b[48;2;74;34;29mremoved\x1b[0m', + '\x1b[3;1H\x1b[48;2;65;69;76m> prompt\x1b[0m', + '\x1b[4;1H\x1b[48;2;33;58;43madded\x1b[K\x1b[0m' + ]) + restored = await restoreSerializedTerminal(source) + + expectActiveBufferParity(source, restored) + const buffer = restored.terminal.buffer.active + expect(buffer.getLine(0)?.getCell(0)?.getBgColor()).toBe(0x213a2b) + expect(buffer.getLine(0)?.getCell(23)?.getBgColor()).toBe(0x213a2b) + expect(buffer.getLine(1)?.getCell(6)?.getBgColor()).toBe(0x4a221d) + expect(buffer.getLine(1)?.getCell(7)?.getBgColor()).toBe(-1) + expect(buffer.getLine(2)?.getCell(0)?.getBgColor()).toBe(0x41454c) + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) + + it('preserves styled scrollback in the normal buffer', async () => { + const source = createRendererParityTerminal({ cols: 18, rows: 3 }) + let restored: ParityTerminal | undefined + try { + const lines = Array.from( + { length: 7 }, + (_, index) => + `\x1b[48;2;${33 + index};${58 + index};${43 + index}mline-${index}\x1b[0m${index < 6 ? '\r\n' : ''}` + ) + await writeChunksToTerminal(source.terminal, lines) + restored = await restoreSerializedTerminal(source) + + expect(source.terminal.buffer.normal.baseY).toBeGreaterThan(0) + expectActiveBufferParity(source, restored) + expect(normalBufferRowsTrimmed(restored.terminal)).toEqual( + normalBufferRowsTrimmed(source.terminal) + ) + expect(normalBufferStylesTrimmed(restored.terminal)).toEqual( + normalBufferStylesTrimmed(source.terminal) + ) + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) + + it('preserves inverse null backgrounds without materializing wide-wrap padding', async () => { + const source = createRendererParityTerminal({ cols: 10, rows: 4 }) + let restored: ParityTerminal | undefined + try { + await writeChunksToTerminal(source.terminal, [`\x1b[7m${'A'.repeat(9)}你\x1b[0m`]) + const sourcePadding = source.terminal.buffer.active.getLine(0)?.getCell(9) + expect(sourcePadding?.getChars()).toBe('') + expect(sourcePadding?.isInverse()).toBeTruthy() + expect(source.terminal.buffer.active.getLine(1)?.isWrapped).toBe(true) + + restored = await restoreSerializedTerminal(source) + + expectActiveBufferParity(source, restored) + const restoredPadding = restored.terminal.buffer.active.getLine(0)?.getCell(9) + expect(restoredPadding?.getChars()).toBe('') + expect(restoredPadding?.isInverse()).toBeTruthy() + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) + + it('materializes final-column nulls that do not match the next wrapped glyph', async () => { + const source = createRendererParityTerminal({ cols: 10, rows: 4 }) + let restored: ParityTerminal | undefined + try { + await writeChunksToTerminal(source.terminal, ['123456789你\x1b[1;9H\x1b[7m界\x1b[1;9HX']) + const sourceNull = source.terminal.buffer.active.getLine(0)?.getCell(9) + const nextGlyph = source.terminal.buffer.active.getLine(1)?.getCell(0) + expect(sourceNull?.getChars()).toBe('') + expect(sourceNull?.isInverse()).toBeTruthy() + expect(nextGlyph?.getWidth()).toBe(2) + expect(nextGlyph?.isInverse()).toBeFalsy() + + restored = await restoreSerializedTerminal(source) + + expect(visibleRows(restored.terminal).map((row) => row.trimEnd())).toEqual( + visibleRows(source.terminal).map((row) => row.trimEnd()) + ) + expect(visibleRowStyles(restored.terminal)).toEqual(visibleRowStyles(source.terminal)) + expect(visibleRowWraps(restored.terminal)).toEqual(visibleRowWraps(source.terminal)) + expect(cursorPosition(restored.terminal)).toEqual(cursorPosition(source.terminal)) + const restoredBlank = restored.terminal.buffer.active.getLine(0)?.getCell(9) + expect(restoredBlank?.getChars()).toBe(' ') + expect(restoredBlank?.isInverse()).toBeTruthy() + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) + + it('suppresses null-cell decorations when materializing an inverse background', async () => { + const source = createRendererParityTerminal({ cols: 40, rows: 4 }) + let restored: ParityTerminal | undefined + try { + await writeChunksToTerminal(source.terminal, [ + `\x1b[1;30H你\x1b[H\x1b[7;4;9;53m${'A'.repeat(30)}\x1b[0m\x1b[CZ` + ]) + const sourceNull = source.terminal.buffer.active.getLine(0)?.getCell(30) + expect(sourceNull?.getChars()).toBe('') + expect(sourceNull?.isInverse()).toBeTruthy() + expect(sourceNull?.isUnderline()).toBeTruthy() + expect(sourceNull?.isStrikethrough()).toBeTruthy() + expect(sourceNull?.isOverline()).toBeTruthy() + + restored = await restoreSerializedTerminal(source) + + expectActiveBufferParity(source, restored) + const restoredBlank = restored.terminal.buffer.active.getLine(0)?.getCell(30) + expect(restoredBlank?.getChars()).toBe(' ') + expect(restoredBlank?.isInverse()).toBeTruthy() + expect(restoredBlank?.isUnderline()).toBeFalsy() + expect(restoredBlank?.isStrikethrough()).toBeFalsy() + expect(restoredBlank?.isOverline()).toBeFalsy() + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) + + it('preserves the normal buffer and colored alternate-screen frame', async () => { + const source = createRendererParityTerminal({ cols: 24, rows: 5 }) + let restored: ParityTerminal | undefined + try { + await writeChunksToTerminal(source.terminal, [ + '\x1b[48;2;74;34;29mshell history\x1b[0m\r\nsecond line', + '\x1b[?1049h\x1b[2J\x1b[H', + '\x1b[48;2;65;69;76m\x1b[2K\x1b[0m', + '\x1b[2;1H\x1b[48;2;33;58;43mworking\x1b[K\x1b[0m' + ]) + restored = await restoreSerializedTerminal(source) + + expect(source.terminal.buffer.active.type).toBe('alternate') + expect(restored.terminal.buffer.active.type).toBe('alternate') + expectActiveBufferParity(source, restored) + expect(normalBufferRowsTrimmed(restored.terminal)).toEqual( + normalBufferRowsTrimmed(source.terminal) + ) + expect(normalBufferStylesTrimmed(restored.terminal)).toEqual( + normalBufferStylesTrimmed(source.terminal) + ) + expect(restored.terminal.buffer.active.getLine(1)?.getCell(23)?.getBgColor()).toBe(0x213a2b) + } finally { + source.terminal.dispose() + restored?.terminal.dispose() + } + }) +}) diff --git a/src/main/daemon/types.ts b/src/main/daemon/types.ts index bc0be4070d7..865572ea0b1 100644 --- a/src/main/daemon/types.ts +++ b/src/main/daemon/types.ts @@ -68,6 +68,8 @@ export type CreateOrAttachRequest = { command?: string startupCommandDelivery?: StartupCommandDelivery launchAgent?: TuiAgent + /** Rejects an absent session instead of interpreting mount uncertainty as create permission. */ + attachOnly?: boolean /** Explicit Windows shell override selected by the user (e.g. 'wsl.exe'). * The daemon forwards this to its subprocess spawner so each tab honors * the shell picked in the "+" menu or the persisted default-shell setting, diff --git a/src/main/git-bash.test.ts b/src/main/git-bash.test.ts index 5cfdc33b533..b582a7414db 100644 --- a/src/main/git-bash.test.ts +++ b/src/main/git-bash.test.ts @@ -53,10 +53,86 @@ describe('Git Bash path discovery', () => { ).toBe('C:\\Users\\alice\\AppData\\Local\\Programs\\Git\\bin\\bash.exe') }) + // Why: resolveWindowsGitBashShellPath has no platform guard of its own, so passing options + // explicitly keeps these assertions meaningful on non-Windows CI hosts. it('honors an explicit bash.exe path for future user-configurable launch paths', () => { - expect(resolveWindowsGitBashShellPath('D:\\PortableGit\\bin\\bash.exe')).toBe( - 'D:\\PortableGit\\bin\\bash.exe' - ) + expect( + resolveWindowsGitBashShellPath('D:\\PortableGit\\bin\\bash.exe', { + platform: 'win32', + env: {}, + exists: (path) => path === 'D:\\PortableGit\\bin\\bash.exe' + }) + ).toBe('D:\\PortableGit\\bin\\bash.exe') + }) + + it('rejects an explicit Git Bash path that is no longer installed', () => { + expect( + resolveWindowsGitBashShellPath('D:\\PortableGit\\bin\\bash.exe', { + platform: 'win32', + env: {}, + exists: () => false + }) + ).toBeNull() + }) + + it('resolves a bare bash entry through Git Bash discovery', () => { + expect( + resolveWindowsGitBashShellPath('bash', { + platform: 'win32', + env: { ProgramFiles: 'C:\\Program Files' }, + exists: (path) => path === 'C:\\Program Files\\Git\\bin\\bash.exe' + }) + ).toBe('C:\\Program Files\\Git\\bin\\bash.exe') + }) + + it('returns null for a bare bash entry when Git Bash is not installed', () => { + expect( + resolveWindowsGitBashShellPath('bash', { + platform: 'win32', + env: { ProgramFiles: 'C:\\Program Files' }, + exists: () => false + }) + ).toBeNull() + }) + + it('resolves an extension-less Git Bash path to the bash.exe it names', () => { + expect( + resolveWindowsGitBashShellPath('C:\\Program Files\\Git\\bin\\bash', { + platform: 'win32', + env: {}, + exists: (path) => path === 'C:\\Program Files\\Git\\bin\\bash.exe' + }) + ).toBe('C:\\Program Files\\Git\\bin\\bash.exe') + }) + + it('returns null for an extension-less Git Bash path with no bash.exe beside it', () => { + expect( + resolveWindowsGitBashShellPath('C:\\Program Files\\Git\\bin\\bash', { + platform: 'win32', + env: {}, + exists: () => false + }) + ).toBeNull() + }) + + it('does not treat an extension-less non-Git bash path as Git Bash', () => { + expect( + resolveWindowsGitBashShellPath('C:\\cygwin64\\bin\\bash', { + platform: 'win32', + env: {}, + exists: () => true + }) + ).toBeNull() + }) + + it('does not probe a bash-prefixed path that is not bash itself', () => { + expect( + resolveWindowsGitBashShellPath('C:\\Program Files\\Git\\bin\\bash.old', { + platform: 'win32', + env: {}, + exists: () => true + }) + ).toBeNull() }) it('recognizes Git Bash executable paths case-insensitively', () => { @@ -64,7 +140,13 @@ describe('Git Bash path discovery', () => { }) it('does not classify arbitrary bash.exe paths as Git Bash', () => { - expect(resolveWindowsGitBashShellPath('C:\\msys64\\usr\\bin\\bash.exe')).toBeNull() + expect( + resolveWindowsGitBashShellPath('C:\\msys64\\usr\\bin\\bash.exe', { + platform: 'win32', + env: {}, + exists: () => true + }) + ).toBeNull() expect(isWindowsGitBashShellPath('C:\\cygwin64\\bin\\bash.exe')).toBe(false) }) diff --git a/src/main/git-bash.ts b/src/main/git-bash.ts index 1756f132bf9..e5841e47729 100644 --- a/src/main/git-bash.ts +++ b/src/main/git-bash.ts @@ -126,13 +126,24 @@ export function resolveWindowsGitBashShellPath( return resolveGitBashPath(options) } + // Why: resolveWindowsShellStartupFamily classifies extension-less `bash` as POSIX too, so both + // spellings must resolve here or setup/PTY shell selection disagrees with the quoting family. const shellBasename = pathWin32.basename(trimmed).toLowerCase() - if (shellBasename !== 'bash.exe') { + if (shellBasename !== 'bash.exe' && shellBasename !== 'bash') { return null } if (pathWin32.isAbsolute(trimmed) || trimmed.includes('\\') || trimmed.includes('/')) { - return isGitForWindowsBashPath(trimmed) ? trimmed : null + // Why: an uninstalled/stale configured path must resolve to null like the discovery + // branch above, so setup does not commit to a bash the PTY will never spawn. + const exists = options.exists ?? existsSync + if (shellBasename === 'bash') { + // Why: Git for Windows ships only bash.exe, so an extension-less path is a request for it. + // This branch synthesizes a path the user never typed, so it must confirm the file is there. + const candidate = `${trimmed}.exe` + return isGitForWindowsBashPath(candidate) && exists(candidate) ? candidate : null + } + return isGitForWindowsBashPath(trimmed) && exists(trimmed) ? trimmed : null } return resolveGitBashPath(options) diff --git a/src/main/github/client-work-items-query-paging.test.ts b/src/main/github/client-work-items-query-paging.test.ts index f9cf934e24e..7af6b124c34 100644 --- a/src/main/github/client-work-items-query-paging.test.ts +++ b/src/main/github/client-work-items-query-paging.test.ts @@ -63,7 +63,8 @@ vi.mock('./gh-utils', () => ({ release: releaseMock, _resetOwnerRepoCache: vi.fn(), classifyGhError: (stderr: string) => ({ type: 'unknown', message: stderr }), - classifyListIssuesError: (stderr: string) => ({ type: 'unknown', message: stderr }) + classifyListIssuesError: (stderr: string) => ({ type: 'unknown', message: stderr }), + classifyListPrsError: (stderr: string) => ({ type: 'unknown', message: stderr }) })) vi.mock('../git/runner', () => ({ @@ -266,6 +267,22 @@ describe('listWorkItems query paging', () => { expect(items.map((item) => item.number)).toEqual([4, 3]) }) + it('lifts a swallowed PR-side failure onto errors.prs instead of reading as end-of-data', async () => { + getIssueOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' }) + getOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' }) + // Non-availability failure (plain 403): swallowed into [], must still surface. + ghExecFileAsyncMock.mockRejectedValueOnce(new Error('HTTP 403: Forbidden')) + + const envelope = await listWorkItems('/repo-root', 10, 'is:pr is:open', 2) + + expect(envelope.items).toEqual([]) + expect(envelope.errors?.issues).toBeUndefined() + expect(envelope.errors?.prs).toEqual({ + type: 'unknown', + message: expect.stringContaining('HTTP 403') + }) + }) + it('filters pull request rows out of issue Search API results', async () => { getIssueOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' }) getOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' }) diff --git a/src/main/github/client-work-items.test.ts b/src/main/github/client-work-items.test.ts index 0226b2af42f..84119b3b2a2 100644 --- a/src/main/github/client-work-items.test.ts +++ b/src/main/github/client-work-items.test.ts @@ -55,7 +55,8 @@ vi.mock('./gh-utils', () => ({ release: releaseMock, _resetOwnerRepoCache: vi.fn(), classifyGhError: (stderr: string) => ({ type: 'unknown', message: stderr }), - classifyListIssuesError: (stderr: string) => ({ type: 'unknown', message: stderr }) + classifyListIssuesError: (stderr: string) => ({ type: 'unknown', message: stderr }), + classifyListPrsError: (stderr: string) => ({ type: 'unknown', message: stderr }) })) vi.mock('../git/runner', () => ({ diff --git a/src/main/github/client.ts b/src/main/github/client.ts index 3684d7729b1..24772ebee4b 100644 --- a/src/main/github/client.ts +++ b/src/main/github/client.ts @@ -55,6 +55,7 @@ import { release, classifyGhError, classifyListIssuesError, + classifyListPrsError, ghRepoExecOptions, githubRepoContext, getRemoteUrlForRepo, @@ -1122,10 +1123,11 @@ function buildWorkItemListRequest(args: { return { args: out, offset: (page - 1) * limit } } -// Why: shared shape so listWorkItems can lift the issue-side error (#1076 silent wrongness) into the IPC envelope; PR errors out of scope (§6). +// Why: shared shape so listWorkItems can lift per-side errors (#1076 silent wrongness) into the IPC envelope — a swallowed side reads as end-of-data to pagination (#11485). type PartialWorkItemsResult = { items: MainWorkItem[] issuesError?: ClassifiedError + prsError?: ClassifiedError } function assertSshRepoHasResolvedGitHubSource(args: { @@ -1279,6 +1281,7 @@ async function listQueriedWorkItems( let successfulRequestCount = 0 let nonAvailabilityFailureCount = 0 let availabilityError: unknown + let prsError: ClassifiedError | undefined // Why: surface the issue-side error separately for the IPC envelope; PR-side keeps prior swallow-and-log (parent doc §6). const issueFetch = (async (): Promise => { @@ -1350,6 +1353,7 @@ async function listQueriedWorkItems( } catch (err) { console.warn('listQueriedWorkItems PRs partial failure:', err) const stderr = err instanceof Error ? err.message : String(err) + prsError = classifyListPrsError(stderr) if (classifyGitHubUnavailable(stderr)) { availabilityError ??= err } else { @@ -1366,7 +1370,8 @@ async function listQueriedWorkItems( } return { items: sortWorkItemsByNumber([...issueResult.items, ...prItems]).slice(0, limit), - issuesError: issueResult.issuesError + issuesError: issueResult.issuesError, + prsError } } @@ -1424,7 +1429,13 @@ export async function listWorkItems( localGitOptions ) - const errors = partial.issuesError ? { issues: partial.issuesError } : undefined + const errors = + partial.issuesError || partial.prsError + ? { + ...(partial.issuesError ? { issues: partial.issuesError } : {}), + ...(partial.prsError ? { prs: partial.prsError } : {}) + } + : undefined return { items: partial.items, sources: { diff --git a/src/main/github/gh-error-classification.ts b/src/main/github/gh-error-classification.ts index 2de37919d25..4d2453899ac 100644 --- a/src/main/github/gh-error-classification.ts +++ b/src/main/github/gh-error-classification.ts @@ -55,3 +55,11 @@ export function classifyListIssuesError(stderr: string): ClassifiedError { } return { type: c.type, message: readMessages[c.type] } } + +// Why: PR-side list failures need the same read-op classification — pagination +// decisions key on the type, and swallowing them made failures look like +// end-of-data (#11485). +export function classifyListPrsError(stderr: string): ClassifiedError { + const c = classifyGhError(stderr) + return { type: c.type, message: `Failed to load pull requests: ${stderr.trim()}` } +} diff --git a/src/main/github/gh-utils.test.ts b/src/main/github/gh-utils.test.ts index 0d7329e21e3..ca9098e53bf 100644 --- a/src/main/github/gh-utils.test.ts +++ b/src/main/github/gh-utils.test.ts @@ -38,6 +38,7 @@ import { __resetLocalGitConfigSignatureCacheForTests, readLocalGitConfigSignature } from './local-git-config-signature' +import { GITHUB_SEARCH_RESULT_WINDOW_ERROR_PATTERN } from '../../shared/github-work-items-query-bounds' describe('github owner/repo resolution', () => { beforeEach(() => { @@ -807,4 +808,17 @@ describe('gh error classification', () => { message: 'Issues are disabled on this repository.' }) }) + + // Why: the renderer detects the Search API 1000-result window by matching + // GITHUB_SEARCH_RESULT_WINDOW_ERROR_PATTERN against this message (#11485) — + // trimming the raw stderr out of the validation_error copy, or drifting the + // pattern off GitHub's real wording, would silently downgrade every window + // 422 to a generic failure. The stderr stays verbatim so this pins both ends. + it('keeps the search-window phrase in validation_error list messages', () => { + const stderr = + 'Command failed: gh api --hostname github.com search/issues\nValidation Failed: Only the first 1000 search results are available (HTTP 422)' + const classified = classifyListIssuesError(stderr) + expect(classified.type).toBe('validation_error') + expect(classified.message).toMatch(GITHUB_SEARCH_RESULT_WINDOW_ERROR_PATTERN) + }) }) diff --git a/src/main/github/gh-utils.ts b/src/main/github/gh-utils.ts index d2148edc3c1..d6770189924 100644 --- a/src/main/github/gh-utils.ts +++ b/src/main/github/gh-utils.ts @@ -9,7 +9,11 @@ import { extractExecError, parseRetryAfterMs } from '../git/exec-error' // WSL-aware routing. Repo-scoped callers should use the runner exports below. export const execFileAsync = promisify(execFile) export { ghExecFileAsync, gitExecFileAsync, extractExecError, parseRetryAfterMs } -export { classifyGhError, classifyListIssuesError } from './gh-error-classification' +export { + classifyGhError, + classifyListIssuesError, + classifyListPrsError +} from './gh-error-classification' export { _getOwnerRepoCacheSize, _resetOwnerRepoCache, diff --git a/src/main/gitlab/gitlab-known-host-probe.ts b/src/main/gitlab/gitlab-known-host-probe.ts index cc4ecf5fad2..577baf9ad67 100644 --- a/src/main/gitlab/gitlab-known-host-probe.ts +++ b/src/main/gitlab/gitlab-known-host-probe.ts @@ -1,4 +1,5 @@ import { runCoalescedProbe, type CoalescedProbes } from '../git/coalesced-probe' +import { NEGATIVE_ENTRY_TTL_MS } from '../git/remote-ref-probe-cache' import { glabExecFileAsync } from '../git/runner' import { getSshGitProviderGeneration } from '../providers/ssh-git-dispatch' import { DEFAULT_GITLAB_HOSTS, normalizeGitLabHost } from './project-ref-parser' @@ -8,8 +9,10 @@ export type LocalGitExecOptions = { } const GLAB_KNOWN_HOSTS_TIMEOUT_MS = 10_000 +const UNAUTHENTICATED_HOSTS_MAX_ENTRIES = 128 const knownHostsCacheByExecutionContext = new Map() const knownHostsInFlightByExecutionContext: CoalescedProbes = new Map() +const unauthenticatedHostExpiries = new Map() function knownHostsExecutionKey( connectionId?: string | null, @@ -26,6 +29,63 @@ function knownHostsExecutionKey( export function _resetKnownHostsCache(): void { knownHostsCacheByExecutionContext.clear() knownHostsInFlightByExecutionContext.clear() + unauthenticatedHostExpiries.clear() +} + +/** @internal - exposed for tests only */ +export function _resetGlabUnauthenticatedHosts(): void { + unauthenticatedHostExpiries.clear() +} + +function unauthenticatedHostKey( + host: string, + connectionId?: string | null, + localGitOptions: LocalGitExecOptions = {} +): string { + return `${knownHostsExecutionKey(connectionId, localGitOptions)}\0${normalizeGitLabHost(host)}` +} + +/** + * Why: `glab auth status --hostname` is how a self-hosted instance that plain + * `glab auth status` did not list gets discovered, so a remote that is not + * GitLab at all runs it too. Project-ref negatives expire now, and without this + * that becomes one `glab` spawn per repo per interval on the hosted-review poll. + * The answer is per host, not per repo, and expires on the same clock so a + * login still lands within an interval. + */ +export function isGlabHostKnownUnauthenticated( + host: string, + connectionId?: string | null, + localGitOptions: LocalGitExecOptions = {} +): boolean { + const key = unauthenticatedHostKey(host, connectionId, localGitOptions) + const expiresAt = unauthenticatedHostExpiries.get(key) + if (expiresAt === undefined) { + return false + } + if (expiresAt > Date.now()) { + return true + } + unauthenticatedHostExpiries.delete(key) + return false +} + +export function rememberGlabHostUnauthenticated( + host: string, + connectionId?: string | null, + localGitOptions: LocalGitExecOptions = {} +): void { + unauthenticatedHostExpiries.set( + unauthenticatedHostKey(host, connectionId, localGitOptions), + Date.now() + NEGATIVE_ENTRY_TTL_MS + ) + while (unauthenticatedHostExpiries.size > UNAUTHENTICATED_HOSTS_MAX_ENTRIES) { + const oldestKey = unauthenticatedHostExpiries.keys().next().value + if (oldestKey === undefined) { + return + } + unauthenticatedHostExpiries.delete(oldestKey) + } } export function rememberGlabKnownHost( @@ -52,6 +112,9 @@ export function rememberGlabKnownHosts( } seen.add(normalizedHost) additions.push(normalizedHost) + unauthenticatedHostExpiries.delete( + unauthenticatedHostKey(normalizedHost, connectionId, localGitOptions) + ) } if (additions.length === 0) { return diff --git a/src/main/gitlab/gitlab-project-ref-resolution.ts b/src/main/gitlab/gitlab-project-ref-resolution.ts index 4b33a4c438f..ee7203ce668 100644 --- a/src/main/gitlab/gitlab-project-ref-resolution.ts +++ b/src/main/gitlab/gitlab-project-ref-resolution.ts @@ -1,9 +1,14 @@ import { glabExecFileAsync } from '../git/runner' import { isTransientGitProbeError, readRemoteUrl } from '../git/remote-url-probe' +import { NEGATIVE_ENTRY_TTL_MS } from '../git/remote-ref-probe-cache' +import { getSshGitProviderGeneration } from '../providers/ssh-git-dispatch' import type { IssueSourcePreference } from '../../shared/types' import { clearProjectRefInFlight, runProjectRefProbeOnce } from './project-ref-inflight' import { + _resetGlabUnauthenticatedHosts, + isGlabHostKnownUnauthenticated, parseGlabAuthStatusHosts, + rememberGlabHostUnauthenticated, rememberGlabKnownHost, type LocalGitExecOptions } from './gitlab-known-host-probe' @@ -25,12 +30,16 @@ export { export type { LocalGitExecOptions } from './gitlab-known-host-probe' const PROJECT_REF_CACHE_MAX_ENTRIES = 512 -const projectRefCache = new Map() + +type CachedProjectRef = { value: ProjectRef | null; expiresAt: number } + +const projectRefCache = new Map() /** @internal - exposed for tests only */ export function _resetProjectRefCache(): void { projectRefCache.clear() clearProjectRefInFlight() + _resetGlabUnauthenticatedHosts() } /** @internal - exposed for tests only */ @@ -39,7 +48,14 @@ export function _getProjectRefCacheSize(): number { } function rememberProjectRefCacheEntry(cacheKey: string, value: ProjectRef | null): void { - projectRefCache.set(cacheKey, value) + // Why: "not GitLab" only holds until someone configures `origin` or logs into + // `glab` — a repo probed before either kept hosted-review detection stale for + // the life of the process. Negatives expire the way every other forge's do; + // positives still stay (see `createRemoteRefProbeCache`). + projectRefCache.set(cacheKey, { + value, + expiresAt: value === null ? Date.now() + NEGATIVE_ENTRY_TTL_MS : Number.POSITIVE_INFINITY + }) while (projectRefCache.size > PROJECT_REF_CACHE_MAX_ENTRIES) { const oldestKey = projectRefCache.keys().next().value if (oldestKey === undefined) { @@ -56,19 +72,30 @@ export async function getProjectRefForRemote( connectionId?: string | null, localGitOptions: LocalGitExecOptions = {} ): Promise { - const runtimeKey = connectionId ?? `local:${localGitOptions.wslDistro ?? 'host'}` + // Why: a reconnect replaces the host an answer came from under the same id, so + // the generation is part of the signature; `knownHosts` carries the glab auth + // state, so logging into a self-hosted instance re-asks rather than reusing a + // ref resolved while that host was unknown. + const runtimeKey = connectionId + ? `${connectionId}:${getSshGitProviderGeneration(connectionId)}` + : `local:${localGitOptions.wslDistro ?? 'host'}` const cacheKey = `${runtimeKey}\0${repoPath}\0${remoteName}\0${knownHosts.join(',')}` - if (projectRefCache.has(cacheKey)) { - return projectRefCache.get(cacheKey)! + const cached = projectRefCache.get(cacheKey) + if (cached) { + if (cached.expiresAt > Date.now()) { + return cached.value + } + projectRefCache.delete(cacheKey) } - return runProjectRefProbeOnce(cacheKey, () => + return runProjectRefProbeOnce(cacheKey, (ownsKey) => resolveProjectRefForRemote( repoPath, remoteName, knownHosts, connectionId, cacheKey, + ownsKey, localGitOptions ) ) @@ -80,8 +107,17 @@ async function resolveProjectRefForRemote( knownHosts: readonly string[], connectionId: string | null | undefined, cacheKey: string, + ownsKey: () => boolean, localGitOptions: LocalGitExecOptions ): Promise { + // Why: a probe abandoned as stale still runs, and the repo state it read is + // older than whatever its successor already published. It may answer its own + // callers; it may not overwrite the cache. + const publish = (value: ProjectRef | null): void => { + if (ownsKey()) { + rememberProjectRefCacheEntry(cacheKey, value) + } + } try { const stdout = await readRemoteUrl( { @@ -96,7 +132,7 @@ async function resolveProjectRefForRemote( } const result = parseGitLabProjectRef(stdout, knownHosts) if (result) { - rememberProjectRefCacheEntry(cacheKey, result) + publish(result) return result } const remoteCandidate = parseRemoteProjectRefCandidate(stdout) @@ -110,17 +146,20 @@ async function resolveProjectRefForRemote( )) ) { rememberGlabKnownHost(remoteCandidate.host, connectionId, localGitOptions) - rememberProjectRefCacheEntry(cacheKey, remoteCandidate) + publish(remoteCandidate) return remoteCandidate } } catch (error) { // Why: a wedged or killed probe is not evidence the remote is not GitLab — - // caching it would misdetect the forge for the life of the process (P1-D). + // caching it would misdetect the forge until the negative expires (P1-D). + // SSH failures stay uncached outright rather than adopting the generic + // cache's stable-missing-remote exception: keeping a connected host's + // detection fresh is worth the extra probe. if (connectionId || isTransientGitProbeError(error)) { return null } } - rememberProjectRefCacheEntry(cacheKey, null) + publish(null) return null } @@ -229,12 +268,22 @@ async function isGlabConfiguredForRemoteHost( connectionId?: string | null, localGitOptions: LocalGitExecOptions = {} ): Promise { + // Why: this probe is per host, but the project-ref miss that reaches it is per + // repo — without the memo, every non-GitLab repo re-spawns `glab` each time + // its negative expires. + if (isGlabHostKnownUnauthenticated(projectRef.host, connectionId, localGitOptions)) { + return false + } try { const result = await glabExecFileAsync( ['auth', 'status', '--hostname', projectRef.host], glabRepoExecOptions(repoPath, connectionId, localGitOptions) ) - return result !== undefined + if (result === undefined) { + rememberGlabHostUnauthenticated(projectRef.host, connectionId, localGitOptions) + return false + } + return true } catch (error) { const execLike = error as { stdout?: unknown; stderr?: unknown; message?: unknown } const output = @@ -242,6 +291,10 @@ async function isGlabConfiguredForRemoteHost( .filter((value): value is string => typeof value === 'string' && value.trim().length > 0) .join('\n') || String(error) const hosts = parseGlabAuthStatusHosts(output).map(normalizeGitLabHost) - return hosts.includes(normalizeGitLabHost(projectRef.host)) + if (hosts.includes(normalizeGitLabHost(projectRef.host))) { + return true + } + rememberGlabHostUnauthenticated(projectRef.host, connectionId, localGitOptions) + return false } } diff --git a/src/main/gitlab/gl-utils.test.ts b/src/main/gitlab/gl-utils.test.ts index 23e159671c6..e1937f3f2aa 100644 --- a/src/main/gitlab/gl-utils.test.ts +++ b/src/main/gitlab/gl-utils.test.ts @@ -28,16 +28,19 @@ import { import { rememberGlabKnownHost, rememberGlabKnownHosts } from './gitlab-known-host-probe' import { registerSshGitProvider, unregisterSshGitProvider } from '../providers/ssh-git-dispatch' import { REMOTE_URL_PROBE_TIMEOUT_MS } from '../git/remote-url-probe' +import { NEGATIVE_ENTRY_TTL_MS } from '../git/remote-ref-probe-cache' describe('gitlab project ref resolution', () => { beforeEach(() => { gitExecFileAsyncMock.mockReset() + glabExecFileAsyncMock.mockReset() sshExecMock.mockReset() unregisterSshGitProvider('conn-1') _resetProjectRefCache() }) afterEach(() => { + vi.useRealTimers() unregisterSshGitProvider('conn-1') }) @@ -211,6 +214,110 @@ describe('gitlab project ref resolution', () => { path: 'remote/orca' }) }) + + it('does not cache a local probe killed on its deadline as a definitive miss', async () => { + gitExecFileAsyncMock + .mockRejectedValueOnce(new Error('git timed out.')) + .mockResolvedValueOnce({ stdout: 'git@gitlab.com:fork/orca.git\n' }) + + await expect(getProjectRef('/repo')).resolves.toBeNull() + await expect(getProjectRef('/repo')).resolves.toEqual({ + host: 'gitlab.com', + path: 'fork/orca' + }) + expect(gitExecFileAsyncMock).toHaveBeenCalledTimes(2) + }) + + it('re-probes a repo whose GitLab remote could have been added since the miss', async () => { + vi.useFakeTimers() + vi.setSystemTime(1_000_000) + gitExecFileAsyncMock.mockRejectedValueOnce(new Error("error: No such remote 'origin'")) + + await expect(getProjectRef('/repo')).resolves.toBeNull() + await expect(getProjectRef('/repo')).resolves.toBeNull() + expect(gitExecFileAsyncMock).toHaveBeenCalledTimes(1) + + // Nothing watches `.git/config`, and SSH/WSL repos have no file to watch, so + // a remote configured after the miss is only visible once the negative ages out. + gitExecFileAsyncMock.mockResolvedValue({ stdout: 'git@gitlab.com:fork/orca.git\n' }) + vi.setSystemTime(1_000_000 + NEGATIVE_ENTRY_TTL_MS + 1) + + await expect(getProjectRef('/repo')).resolves.toEqual({ + host: 'gitlab.com', + path: 'fork/orca' + }) + expect(gitExecFileAsyncMock).toHaveBeenCalledTimes(2) + }) + + it('keeps a resolved project ref past the negative interval', async () => { + vi.useFakeTimers() + vi.setSystemTime(1_000_000) + gitExecFileAsyncMock.mockResolvedValue({ stdout: 'git@gitlab.com:fork/orca.git\n' }) + + await expect(getProjectRef('/repo')).resolves.toEqual({ + host: 'gitlab.com', + path: 'fork/orca' + }) + vi.setSystemTime(1_000_000 + NEGATIVE_ENTRY_TTL_MS * 10) + await expect(getProjectRef('/repo')).resolves.toEqual({ + host: 'gitlab.com', + path: 'fork/orca' + }) + + expect(gitExecFileAsyncMock).toHaveBeenCalledTimes(1) + }) + + it('re-resolves a self-hosted remote once glab auth knows its host', async () => { + gitExecFileAsyncMock.mockResolvedValue({ stdout: 'git@gitlab.internal:team/orca.git\n' }) + glabExecFileAsyncMock.mockRejectedValue(new Error('not authenticated')) + + await expect(getProjectRefForRemote('/repo', 'origin', ['gitlab.com'])).resolves.toBeNull() + await expect( + getProjectRefForRemote('/repo', 'origin', ['gitlab.com', 'gitlab.internal']) + ).resolves.toEqual({ host: 'gitlab.internal', path: 'team/orca' }) + }) + + it('asks glab about an unauthenticated host once per interval, not once per repo', async () => { + vi.useFakeTimers() + vi.setSystemTime(1_000_000) + gitExecFileAsyncMock.mockResolvedValue({ stdout: 'git@github.com:team/orca.git\n' }) + glabExecFileAsyncMock.mockRejectedValue(new Error('not authenticated')) + + // Expiring project-ref negatives must not turn the hosted-review poll into a + // `glab auth status` spawn per repo per interval — the answer is per host. + for (const repoPath of ['/repo-a', '/repo-b', '/repo-c']) { + await expect(getProjectRef(repoPath)).resolves.toBeNull() + } + expect(glabExecFileAsyncMock).toHaveBeenCalledTimes(1) + + vi.setSystemTime(1_000_000 + NEGATIVE_ENTRY_TTL_MS + 1) + for (const repoPath of ['/repo-a', '/repo-b', '/repo-c']) { + await expect(getProjectRef(repoPath)).resolves.toBeNull() + } + expect(glabExecFileAsyncMock).toHaveBeenCalledTimes(2) + }) + + it('does not serve a project ref resolved on a retired SSH connection', async () => { + sshExecMock + .mockResolvedValueOnce({ stdout: 'git@gitlab.com:before/orca.git\n', stderr: '' }) + .mockResolvedValueOnce({ stdout: 'git@gitlab.com:after/orca.git\n', stderr: '' }) + registerSshGitProvider('conn-1', { exec: sshExecMock } as never) + + await expect(getProjectRefForRemote('/repo', 'origin', undefined, 'conn-1')).resolves.toEqual({ + host: 'gitlab.com', + path: 'before/orca' + }) + + // A reconnect can swap the execution host under the same connection id. + unregisterSshGitProvider('conn-1') + registerSshGitProvider('conn-1', { exec: sshExecMock } as never) + + await expect(getProjectRefForRemote('/repo', 'origin', undefined, 'conn-1')).resolves.toEqual({ + host: 'gitlab.com', + path: 'after/orca' + }) + expect(sshExecMock).toHaveBeenCalledTimes(2) + }) }) describe('resolveIssueSource', () => { diff --git a/src/main/gitlab/project-ref-inflight.ts b/src/main/gitlab/project-ref-inflight.ts index a9de9d75797..cea4173c48f 100644 --- a/src/main/gitlab/project-ref-inflight.ts +++ b/src/main/gitlab/project-ref-inflight.ts @@ -9,7 +9,7 @@ export function clearProjectRefInFlight(): void { export async function runProjectRefProbeOnce( cacheKey: string, - createProbe: () => Promise + createProbe: (ownsKey: () => boolean) => Promise ): Promise { // Why: joining only a probe that is still young keeps a wedged host's dead // promise from pinning every later retry for the process lifetime (P1-D). diff --git a/src/main/gitlab/work-item-details.test.ts b/src/main/gitlab/work-item-details.test.ts index 7af04c89b76..38e434278d8 100644 --- a/src/main/gitlab/work-item-details.test.ts +++ b/src/main/gitlab/work-item-details.test.ts @@ -32,7 +32,7 @@ vi.mock('./gl-utils', () => ({ glabRepoExecOptions: glabRepoExecOptionsMock })) -import { getWorkItemDetails } from './work-item-details' +import { countDiffLines, getWorkItemDetails } from './work-item-details' describe('getWorkItemDetails', () => { beforeEach(() => { @@ -203,3 +203,84 @@ describe('getWorkItemDetails', () => { ) }) }) + +describe('countDiffLines', () => { + it('counts added and removed lines inside a hunk', () => { + expect(countDiffLines('@@ -1 +1 @@\n-old\n+new')).toEqual({ additions: 1, deletions: 1 }) + }) + + it('counts a removed line whose original content began with `--` (SQL/Lua comment)', () => { + // Why: prefix `-` + content `-- old comment` = diff line `--- old comment`, + // which collides with the `--- a/file` header under a plain startsWith check. + expect( + countDiffLines('--- a/db.sql\n+++ b/db.sql\n@@ -1,2 +1,2 @@\n keep\n--- old comment\n+new') + ).toEqual({ additions: 1, deletions: 1 }) + }) + + it('counts an added line whose original content began with `++`', () => { + // Why: prefix `+` + content `++ flag` = diff line `+++ flag`, colliding with `+++ b/file`. + expect(countDiffLines('--- a/f.lua\n+++ b/f.lua\n@@ -1 +1 @@\n-old\n+++ flag')).toEqual({ + additions: 1, + deletions: 1 + }) + }) + + it('counts the collision on a header-less payload, the shape GitLab actually returns', () => { + // Why: the `/diffs` entity emits `json_safe_diff`, which starts at `@@` — the + // `--- a/file` form is opt-in via `unidiff=true`, which this call path never sends. + // So this, not the header-prefixed variant, is the reachable regression input. + expect(countDiffLines('@@ -1 +1 @@\n--- old comment\n+++ new comment')).toEqual({ + additions: 1, + deletions: 1 + }) + }) + + it('counts an added line of `++i;` C-style increment content', () => { + expect(countDiffLines('@@ -1 +1 @@\n-i++;\n+++i;')).toEqual({ additions: 1, deletions: 1 }) + }) + + it('yields zero for a binary-notice diff', () => { + expect(countDiffLines('Binary files a/logo.png and b/logo.png differ')).toEqual({ + additions: 0, + deletions: 0 + }) + }) + + it('skips file headers before the first hunk and yields zero for a header-only diff', () => { + expect(countDiffLines('--- a/x\n+++ b/x')).toEqual({ additions: 0, deletions: 0 }) + }) + + it('keeps additions and deletions distinct under an asymmetric hunk', () => { + expect(countDiffLines('@@ -1 +1,2 @@\n-old\n+a\n+b')).toEqual({ additions: 2, deletions: 1 }) + }) + + it('accumulates counts across multiple hunks', () => { + expect(countDiffLines('@@ -1 +1 @@\n-a\n+b\n@@ -5 +5,2 @@\n-c\n+d\n+e')).toEqual({ + additions: 3, + deletions: 2 + }) + }) + + it('yields zero for the empty diff that binary and rename-only files carry', () => { + // Why: mapMRFile passes `raw.diff ?? ''`, so binary/too_large/rename-only entries land here. + expect(countDiffLines('')).toEqual({ additions: 0, deletions: 0 }) + }) + + it('yields zero when no hunk header is present, even with +/- lines', () => { + // Why: pins the deliberate behaviour change — without a `@@` there is no hunk, so + // leading +/- can only be file headers. Counting them is what caused the collision. + expect(countDiffLines('+added\n-removed')).toEqual({ additions: 0, deletions: 0 }) + }) + + it('ignores the no-newline marker and a trailing newline', () => { + expect(countDiffLines('@@ -1 +1 @@\n-old\n+new\n\\ No newline at end of file\n')).toEqual({ + additions: 1, + deletions: 1 + }) + }) + + it('counts hunk content whose own text begins with `@@`', () => { + // Why: the `@@` hunk check runs first, so it must not swallow `+`/`-` content. + expect(countDiffLines('@@ -1 +1 @@\n-@@ old\n+@@ new')).toEqual({ additions: 1, deletions: 1 }) + }) +}) diff --git a/src/main/gitlab/work-item-details.ts b/src/main/gitlab/work-item-details.ts index 066e539b815..85ddb450b17 100644 --- a/src/main/gitlab/work-item-details.ts +++ b/src/main/gitlab/work-item-details.ts @@ -169,11 +169,29 @@ async function fetchPipelineJobs( return data.map((job) => mapPipelineJob(job, pipelineId)) } -function countDiffLines(diff: string): { additions: number; deletions: number } { +/** + * Counts the added/removed lines in a single GitLab MR file's unified diff, + * feeding the +N/-N shown in the MR file list. `---`/`+++` are file headers + * only before the first `@@` hunk; every `+`/`-` line inside a hunk is content. + * Requires hunk headers: a diff with no `@@` counts zero, so do not reuse this + * for header-less agent-tool diffs (see `diffFromText` in shared/native-chat-diff). + * + * @internal - exposed for tests only. + */ +export function countDiffLines(diff: string): { additions: number; deletions: number } { let additions = 0 let deletions = 0 + // Why: `---`/`+++` are file headers only before the first hunk. A removed line + // whose original text began with `--` (SQL/Lua/Haskell `-- comment`) becomes a + // diff line `---`, colliding with the `--- a/file` header — so it must + // be counted once inside a hunk, not skipped. + let inHunk = false for (const line of diff.split('\n')) { - if (line.startsWith('+++') || line.startsWith('---')) { + if (line.startsWith('@@')) { + inHunk = true + continue + } + if (!inHunk) { continue } if (line.startsWith('+')) { diff --git a/src/main/hooks-runner.test.ts b/src/main/hooks-runner.test.ts index cd226bf9279..79827207aba 100644 --- a/src/main/hooks-runner.test.ts +++ b/src/main/hooks-runner.test.ts @@ -57,13 +57,15 @@ describe('createSetupRunnerScript', () => { ORCA_ROOT_PATH: '/test/repo', ORCA_WORKTREE_PATH: 'C:\\repo\\feature\\', ORCA_WORKSPACE_NAME: 'feature' - }) + }), + // Why: native Windows worktrees without a configured setup shell keep the cmd runner. + shell: { family: 'cmd' } }) expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith( 'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.cmd', [ '@echo off', - 'setlocal EnableExtensions', + 'setlocal EnableExtensions DisableDelayedExpansion', 'call pnpm install', 'if errorlevel 1 exit /b %errorlevel%', 'call pnpm build', @@ -80,6 +82,110 @@ describe('createSetupRunnerScript', () => { } }) + it('converts path env vars to MSYS form for a native Windows Git Bash runner', async () => { + const fs = await import('node:fs') + const originalPlatform = process.platform + + execFileSyncMock.mockReturnValue('C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh') + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const result = createSetupRunnerScript( + { ...makeRepo(), path: 'C:\\Users\\jinwo\\git\\orca' }, + 'C:\\repo\\feature', + 'pnpm install', + undefined, + { family: 'posix' } + ) + + expect(result).toEqual({ + runnerScriptPath: 'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh', + envVars: expect.objectContaining({ + ORCA_ROOT_PATH: '/c/Users/jinwo/git/orca', + ORCA_WORKTREE_PATH: '/c/repo/feature', + CONDUCTOR_ROOT_PATH: '/c/Users/jinwo/git/orca', + GHOSTX_ROOT_PATH: '/c/Users/jinwo/git/orca', + // Why: a display name, never a path — it must survive the conversion untouched. + ORCA_WORKSPACE_NAME: 'feature' + }), + shell: { family: 'posix' } + }) + expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith( + 'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh', + '#!/usr/bin/env bash\nset -e\npnpm install\n', + 'utf-8' + ) + // Why: chmod over a native Windows path is meaningless; only the WSL branch sets the bit. + expect(vi.mocked(fs.chmodSync)).not.toHaveBeenCalledWith( + 'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh', + 0o755 + ) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('leaves non-path setup env values alone under a Git Bash runner', async () => { + const originalPlatform = process.platform + + execFileSyncMock.mockReturnValue('C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh') + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const { TERMINAL_GIT_CREDENTIAL_GUARD_POLICY_ENV } = + await import('../shared/terminal-git-credential-guard') + const result = createSetupRunnerScript( + makeRepo(), + 'C:\\repo\\feature', + 'pnpm install', + undefined, + { family: 'posix' } + ) + + expect(result.envVars[TERMINAL_GIT_CREDENTIAL_GUARD_POLICY_ENV]).toBe('guard') + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('keeps native Windows env vars in Windows form for the default cmd runner', async () => { + const originalPlatform = process.platform + + execFileSyncMock.mockReturnValue('C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.cmd') + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const result = createSetupRunnerScript( + { ...makeRepo(), path: 'C:\\Users\\jinwo\\git\\orca' }, + 'C:\\repo\\feature', + 'pnpm install' + ) + + expect(result.envVars).toEqual( + expect.objectContaining({ + ORCA_ROOT_PATH: 'C:\\Users\\jinwo\\git\\orca', + ORCA_WORKTREE_PATH: 'C:\\repo\\feature' + }) + ) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('preserves exclamation marks in Windows runner script lines', async () => { + const { buildWindowsRunnerScript } = await import('./hooks') + + const runner = buildWindowsRunnerScript('echo hello!world!') + + // Why: launchers invoke the runner under cmd /v:on, so the runner must disable delayed + // expansion itself or `!world!` is consumed as a variable reference. + expect(runner).toContain('setlocal EnableExtensions DisableDelayedExpansion') + expect(runner).toContain('call echo hello!world!') + }) + it('derives ORCA_WORKSPACE_NAME from a POSIX worktree path', async () => { const originalPlatform = process.platform @@ -256,4 +362,55 @@ describe('createIssueCommandRunnerScript', () => { }) } }) + + it('carries the WSL launch shell for a Windows-drive worktree routed through WSL', async () => { + const originalPlatform = process.platform + + execFileSyncMock.mockReturnValue('/mnt/c/repo/.git/orca/issue-command-runner.sh') + Object.defineProperty(process, 'platform', { + configurable: true, + value: 'win32' + }) + + try { + const { createIssueCommandRunnerScript } = await import('./hooks') + const result = createIssueCommandRunnerScript( + makeRepo(), + 'C:\\repo\\feature', + 'codex exec "long command"', + { wslDistro: 'Ubuntu' } + ) + + // Why: the runner path is written back in native Windows form, so the launch needs /mnt again. + expect(result.runnerScriptPath).toBe('C:\\repo\\.git\\orca\\issue-command-runner.sh') + expect(result.shell).toEqual({ family: 'posix', executable: 'wsl.exe' }) + } finally { + Object.defineProperty(process, 'platform', { + configurable: true, + value: originalPlatform + }) + } + }) + + it('keeps native Windows issue runners on the cmd launch shell', async () => { + const originalPlatform = process.platform + + execFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.cmd') + Object.defineProperty(process, 'platform', { + configurable: true, + value: 'win32' + }) + + try { + const { createIssueCommandRunnerScript } = await import('./hooks') + const result = createIssueCommandRunnerScript(makeRepo(), 'C:\\repo\\feature', 'pnpm install') + + expect(result.shell).toEqual({ family: 'cmd' }) + } finally { + Object.defineProperty(process, 'platform', { + configurable: true, + value: originalPlatform + }) + } + }) }) diff --git a/src/main/hooks.test.ts b/src/main/hooks.test.ts index 6083638575d..b51a38e3321 100644 --- a/src/main/hooks.test.ts +++ b/src/main/hooks.test.ts @@ -537,7 +537,9 @@ describe('runner script builders', () => { try { const result = buildWindowsRunnerScript(script) - expect(result.startsWith('@echo off\r\nsetlocal EnableExtensions\r\n')).toBe(true) + expect( + result.startsWith('@echo off\r\nsetlocal EnableExtensions DisableDelayedExpansion\r\n') + ).toBe(true) expect(result).toContain('call pnpm install\r\nif errorlevel 1 exit /b %errorlevel%') expect(result).toContain('call npm run build\r\nif errorlevel 1 exit /b %errorlevel%') const usedLineSplit = splitSpy.mock.calls.some( @@ -1175,6 +1177,7 @@ describe('runHook', () => { } ) expect(result.runnerScriptPath).toContain('setup-runner.sh') + expect(result.shell).toEqual({ family: 'posix', executable: 'wsl.exe' }) expect(mkdirSyncMock).toHaveBeenCalled() expect(writeFileSyncMock).toHaveBeenCalledWith( expect.stringContaining('setup-runner.sh'), @@ -1252,6 +1255,116 @@ describe('createSetupRunnerScript', () => { } }) as unknown as Repo + it('writes POSIX setup runners for Git Bash on native Windows paths', async () => { + gitExecFileSyncMock.mockReset() + gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\setup-runner.sh\n') + const fs = await import('node:fs') + const writeFileSyncMock = vi.mocked(fs.writeFileSync) + const chmodSyncMock = vi.mocked(fs.chmodSync) + writeFileSyncMock.mockClear() + chmodSyncMock.mockClear() + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const result = createSetupRunnerScript( + makeRepo(), + 'C:\\repo-worktree', + 'pnpm install\r\nnpm run build', + undefined, + { family: 'posix' } + ) + + expect(gitExecFileSyncMock).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/setup-runner.sh'], + { cwd: 'C:\\repo-worktree' } + ) + expect(writeFileSyncMock).toHaveBeenCalledWith( + 'C:\\repo\\.git\\orca\\setup-runner.sh', + '#!/usr/bin/env bash\nset -e\npnpm install\nnpm run build\n', + 'utf-8' + ) + expect(chmodSyncMock).not.toHaveBeenCalled() + expect(result).toMatchObject({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix' } + }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('preserves cmd.exe setup runner semantics for configured cmd users', async () => { + gitExecFileSyncMock.mockReset() + gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\setup-runner.cmd\n') + const fs = await import('node:fs') + const writeFileSyncMock = vi.mocked(fs.writeFileSync) + writeFileSyncMock.mockClear() + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const result = createSetupRunnerScript( + makeRepo(), + 'C:\\repo-worktree', + 'pnpm install\nnpm run build', + undefined, + { family: 'cmd' } + ) + + expect(gitExecFileSyncMock).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/setup-runner.cmd'], + { cwd: 'C:\\repo-worktree' } + ) + expect(writeFileSyncMock).toHaveBeenCalledWith( + 'C:\\repo\\.git\\orca\\setup-runner.cmd', + expect.stringContaining('call pnpm install\r\nif errorlevel 1 exit /b %errorlevel%'), + 'utf-8' + ) + expect(writeFileSyncMock).toHaveBeenCalledWith( + 'C:\\repo\\.git\\orca\\setup-runner.cmd', + expect.stringContaining('call npm run build\r\nif errorlevel 1 exit /b %errorlevel%'), + 'utf-8' + ) + expect(result.shell).toEqual({ family: 'cmd' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('keeps POSIX runner behavior on POSIX platforms', async () => { + gitExecFileSyncMock.mockReset() + gitExecFileSyncMock.mockReturnValue('/test/repo/.git/orca/setup-runner.sh\n') + const fs = await import('node:fs') + const writeFileSyncMock = vi.mocked(fs.writeFileSync) + const chmodSyncMock = vi.mocked(fs.chmodSync) + writeFileSyncMock.mockClear() + chmodSyncMock.mockClear() + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'linux' }) + + try { + const { createSetupRunnerScript } = await import('./hooks') + const result = createSetupRunnerScript(makeRepo(), '/test/worktree', 'pnpm install') + + expect(gitExecFileSyncMock).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/setup-runner.sh'], + { cwd: '/test/worktree' } + ) + expect(writeFileSyncMock).toHaveBeenCalledWith( + '/test/repo/.git/orca/setup-runner.sh', + '#!/usr/bin/env bash\nset -e\npnpm install\n', + 'utf-8' + ) + expect(chmodSyncMock).toHaveBeenCalledWith('/test/repo/.git/orca/setup-runner.sh', 0o755) + expect(result.shell).toBeUndefined() + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + it('omits waitForAgentStartup unless the repo explicitly waits for setup', async () => { gitExecFileSyncMock.mockReset() gitExecFileSyncMock.mockReturnValue('/test/repo/.git/orca/setup-runner.sh\n') @@ -1285,6 +1398,199 @@ describe('createSetupRunnerScript', () => { }) }) +describe('createIssueCommandRunnerScript', () => { + const makeRepo = () => + ({ + id: 'test-id', + path: '/test/repo', + displayName: 'Test Repo', + badgeColor: '#000', + addedAt: Date.now(), + hookSettings: { mode: 'auto', scripts: { setup: '', archive: '' } } + }) as unknown as Repo + + it('writes a POSIX issue-command runner when setup resolves to Git Bash', async () => { + gitExecFileSyncMock.mockReset() + gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.sh\n') + const fs = await import('node:fs') + const writeFileSyncMock = vi.mocked(fs.writeFileSync) + writeFileSyncMock.mockClear() + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createIssueCommandRunnerScript } = await import('./hooks') + const result = createIssueCommandRunnerScript( + makeRepo(), + 'C:\\repo-worktree', + 'gh issue view 42', + undefined, + { family: 'posix' } + ) + + expect(gitExecFileSyncMock).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/issue-command-runner.sh'], + { cwd: 'C:\\repo-worktree' } + ) + expect(writeFileSyncMock).toHaveBeenCalledWith( + 'C:\\repo\\.git\\orca\\issue-command-runner.sh', + '#!/usr/bin/env bash\nset -e\ngh issue view 42\n', + 'utf-8' + ) + expect(result.shell).toEqual({ family: 'posix' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('keeps the cmd issue-command runner when no setup shell is resolved', async () => { + gitExecFileSyncMock.mockReset() + gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.cmd\n') + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + const { createIssueCommandRunnerScript } = await import('./hooks') + const result = createIssueCommandRunnerScript( + makeRepo(), + 'C:\\repo-worktree', + 'gh issue view 42' + ) + + expect(gitExecFileSyncMock).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/issue-command-runner.cmd'], + { cwd: 'C:\\repo-worktree' } + ) + expect(result.shell).toEqual({ family: 'cmd' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) +}) + +describe('resolveSetupRunnerShell', () => { + const installedGitBash = { + resolveGitBashShellPath: () => 'C:\\Program Files\\Git\\bin\\bash.exe' + } + + it('maps git-bash to POSIX setup launch metadata on Windows', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'git-bash' }, 'win32', installedGitBash) + ).toEqual({ + family: 'posix' + }) + }) + + it('falls back to the cmd runner when the git-bash setting has no installed Git Bash', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'git-bash' }, 'win32', { + resolveGitBashShellPath: () => null + }) + ).toEqual({ family: 'cmd' }) + }) + + it('keeps the cmd runner for a non-Git bash such as Cygwin', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'C:\\cygwin64\\bin\\bash.exe' }, 'win32', { + resolveGitBashShellPath: () => null + }) + ).toEqual({ family: 'cmd' }) + }) + + it('keeps the cmd runner for a bare bash whose flavor cannot be resolved', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'bash' }, 'win32', { + resolveGitBashShellPath: () => null + }) + ).toEqual({ family: 'cmd' }) + }) + + it('uses the POSIX runner for a bare bash that resolves to Git Bash', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'bash' }, 'win32', installedGitBash) + ).toEqual({ family: 'posix' }) + }) + + it('uses the POSIX runner for an extension-less Git Bash path', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell( + { terminalWindowsShell: 'C:\\Program Files\\Git\\bin\\bash' }, + 'win32', + installedGitBash + ) + ).toEqual({ family: 'posix' }) + }) + + it('preserves the existing cmd runner for PowerShell terminals', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell( + { + terminalWindowsShell: 'powershell.exe', + terminalWindowsPowerShellImplementation: 'pwsh.exe' + }, + 'win32', + installedGitBash + ) + ).toEqual({ family: 'cmd' }) + }) + + it('preserves cmd setup compatibility when a Windows-host project has a WSL shell setting', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + + expect( + resolveSetupRunnerShell({ terminalWindowsShell: 'wsl.exe' }, 'win32', installedGitBash) + ).toEqual({ family: 'cmd' }) + }) + + it('classifies an installed explicit Git Bash executable as a POSIX runner', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + const { resolveWindowsGitBashShellPath } = await import('./git-bash') + + expect( + resolveSetupRunnerShell( + { terminalWindowsShell: 'C:\\Program Files\\Git\\bin\\bash.exe' }, + 'win32', + { + resolveGitBashShellPath: (shell) => + resolveWindowsGitBashShellPath(shell, { platform: 'win32', exists: () => true }) + } + ) + ).toEqual({ family: 'posix' }) + }) + + it('falls back to the cmd runner when the explicit Git Bash path no longer exists', async () => { + const { resolveSetupRunnerShell } = await import('./hooks') + const { resolveWindowsGitBashShellPath } = await import('./git-bash') + + // Regression: a stale configured path used to commit setup to a .sh runner the + // PTY could never spawn, hanging wait-for-setup until the 2h timeout. + expect( + resolveSetupRunnerShell( + { terminalWindowsShell: 'C:\\Program Files\\Git\\bin\\bash.exe' }, + 'win32', + { + resolveGitBashShellPath: (shell) => + resolveWindowsGitBashShellPath(shell, { platform: 'win32', exists: () => false }) + } + ) + ).toEqual({ family: 'cmd' }) + }) +}) + describe('shouldRunSetupForCreate', () => { const makeRepo = (setupRunPolicy?: 'ask' | 'run-by-default' | 'skip-by-default') => ({ diff --git a/src/main/hooks.ts b/src/main/hooks.ts index 3f8a210ccf9..ad73003778f 100644 --- a/src/main/hooks.ts +++ b/src/main/hooks.ts @@ -8,6 +8,9 @@ import { resolveHookCommandSourcePolicy } from '../shared/hook-command-source-po import { shouldWaitForSetupBeforeAgentStartup } from '../shared/setup-agent-startup-policy' import { TERMINAL_GIT_CREDENTIAL_GUARD_POLICY_ENV } from '../shared/terminal-git-credential-guard' import { parseOrcaYaml } from '../shared/orca-yaml' +import { nativeWindowsPathToPosixShellPath } from '../shared/setup-runner-command' +import { resolveWindowsShellStartupFamily } from '../shared/windows-terminal-shell' +import { resolveWindowsGitBashShellPath } from './git-bash' import { gitExecFileSync, promptGuardShellEnv } from './git/runner' import { isWslPath, parseWslPath, toWindowsWslPath, toLinuxPath } from './wsl' import { addWorktreeSetupWslInteropEnv } from './pty/wsl-orca-env' @@ -21,6 +24,7 @@ import type { WorktreeSetupLaunch } from '../shared/types' import type { ProjectExecutionRuntimeResolution } from '../shared/project-execution-runtime' +import type { SetupRunnerShell } from '../shared/setup-runner-command' const HOOK_TIMEOUT = 120_000 // 2 minutes @@ -28,6 +32,8 @@ export type HookRuntimeTarget = { wslDistro?: string | null } +type SetupRunnerShellSettings = Record | undefined + function getHookShell(): string | undefined { if (process.platform === 'win32') { return process.env.ComSpec || 'cmd.exe' @@ -322,6 +328,15 @@ export function getSetupCommandSource( return null } +// Why: kept in sync with pty/wsl-orca-env.ts, which path-translates the same keys for WSL. +// ORCA_WORKSPACE_NAME is a display name and the credential-guard policy is an enum — never paths. +const SETUP_RUNNER_PATH_ENV_KEYS = [ + 'ORCA_ROOT_PATH', + 'ORCA_WORKTREE_PATH', + 'CONDUCTOR_ROOT_PATH', + 'GHOSTX_ROOT_PATH' +] as const + function getSetupEnvVars(repo: Repo, worktreePath: string): Record { return { ORCA_ROOT_PATH: repo.path, @@ -383,7 +398,9 @@ function getHookWslContext( } export function buildWindowsRunnerScript(script: string): string { - let runnerScript = '@echo off\r\nsetlocal EnableExtensions\r\n' + // Why: launchers invoke this runner under `cmd /v:on`, and EnableExtensions does not reset an + // inherited delayed-expansion state — without this, every `!` in a user setup line is eaten. + let runnerScript = '@echo off\r\nsetlocal EnableExtensions DisableDelayedExpansion\r\n' for (const rawLine of iterateLfScriptLines(script)) { const command = rawLine.trim() @@ -420,16 +437,20 @@ export function createSetupRunnerScript( repo: Repo, worktreePath: string, script: string, - projectRuntime?: ProjectExecutionRuntimeResolution | HookRuntimeTarget + projectRuntime?: ProjectExecutionRuntimeResolution | HookRuntimeTarget, + setupShell?: SetupRunnerShell ): WorktreeSetupLaunch { - return createWorktreeRunnerScript( + return createWorktreeRunnerScript({ repo, worktreePath, script, - 'setup-runner', - getHookRuntimeTarget(projectRuntime), - shouldWaitForSetupBeforeAgentStartup(repo.hookSettings?.setupAgentStartupPolicy) - ) + runnerBaseName: 'setup-runner', + runtimeTarget: getHookRuntimeTarget(projectRuntime), + waitForAgentStartup: shouldWaitForSetupBeforeAgentStartup( + repo.hookSettings?.setupAgentStartupPolicy + ), + setupShell + }) } export function getSetupRunnerEnvVars(repo: Repo, worktreePath: string): Record { @@ -469,32 +490,55 @@ export function createIssueCommandRunnerScript( repo: Repo, worktreePath: string, command: string, - projectRuntime?: ProjectExecutionRuntimeResolution | HookRuntimeTarget + projectRuntime?: ProjectExecutionRuntimeResolution | HookRuntimeTarget, + setupShell?: SetupRunnerShell ): WorktreeSetupLaunch { // Why: writing long commands into a runner script avoids the PTY line editor wrapping/truncating them. - return createWorktreeRunnerScript( + return createWorktreeRunnerScript({ repo, worktreePath, - command, - 'issue-command-runner', - getHookRuntimeTarget(projectRuntime) - ) + script: command, + runnerBaseName: 'issue-command-runner', + runtimeTarget: getHookRuntimeTarget(projectRuntime), + // Why: issue commands run in the same terminal as setup, so a Git Bash setup + // runner must not be paired with a cmd issue runner in one session. + setupShell + }) } -function createWorktreeRunnerScript( - repo: Repo, - worktreePath: string, - script: string, - runnerBaseName: 'setup-runner' | 'issue-command-runner', - runtimeTarget?: HookRuntimeTarget, +function createWorktreeRunnerScript(args: { + repo: Repo + worktreePath: string + script: string + runnerBaseName: 'setup-runner' | 'issue-command-runner' + runtimeTarget?: HookRuntimeTarget waitForAgentStartup?: boolean -): WorktreeSetupLaunch { + setupShell?: SetupRunnerShell +}): WorktreeSetupLaunch { + const { + repo, + worktreePath, + script, + runnerBaseName, + runtimeTarget, + waitForAgentStartup, + setupShell + } = args const envVars = getSetupRunnerEnvVars(repo, worktreePath) // Why: WSL worktrees are Linux fs even though process.platform is 'win32'; use bash for WSL, .cmd for native Windows. const wslWorktree = isWslPath(worktreePath) || Boolean(runtimeTarget?.wslDistro) - const useWindowsFormat = process.platform === 'win32' && !wslWorktree + const nativeWindowsWorktree = process.platform === 'win32' && !wslWorktree + const runnerShell: SetupRunnerShell = nativeWindowsWorktree + ? (setupShell ?? { family: 'cmd' }) + : { family: 'posix' } + const launchShell: SetupRunnerShell | undefined = nativeWindowsWorktree + ? runnerShell + : process.platform === 'win32' && runtimeTarget?.wslDistro + ? { family: 'posix', executable: 'wsl.exe' } + : undefined // Why: linked worktrees use a `.git` file, so resolve the real per-worktree gitdir via git rev-parse --git-path. - const gitRelPath = useWindowsFormat ? `orca/${runnerBaseName}.cmd` : `orca/${runnerBaseName}.sh` + const runnerExtension = runnerShell.family === 'cmd' ? 'cmd' : 'sh' + const gitRelPath = `orca/${runnerBaseName}.${runnerExtension}` let runnerScriptPath = getGitPath(worktreePath, gitRelPath, runtimeTarget) // Why: git runs inside WSL and returns a Linux path; convert to a UNC path so the Windows fs calls can reach it. @@ -507,12 +551,14 @@ function createWorktreeRunnerScript( mkdirSync(dirname(runnerScriptPath), { recursive: true }) - if (useWindowsFormat) { + if (runnerShell.family === 'cmd') { writeFileSync(runnerScriptPath, buildWindowsRunnerScript(script), 'utf-8') } else { writeFileSync(runnerScriptPath, buildPosixRunnerScript(script), 'utf-8') - // Why: chmod over a UNC path to the WSL filesystem sets the execute bit correctly inside WSL. - chmodSync(runnerScriptPath, 0o755) + if (!nativeWindowsWorktree) { + // Why: chmod over a UNC path to the WSL filesystem sets the execute bit correctly inside WSL. + chmodSync(runnerScriptPath, 0o755) + } } // Why: setup script runs inside WSL bash, so translate the Windows UNC env-var paths to Linux paths. @@ -520,15 +566,68 @@ function createWorktreeRunnerScript( for (const key of Object.keys(envVars)) { envVars[key] = toLinuxPath(envVars[key]) } + } else if (nativeWindowsWorktree && runnerShell.family === 'posix') { + // Why: a Git Bash runner already receives its own path as /c/..., and the shell exports HOME + // and PWD the same way, so leaving ORCA_* in C:\ form would make them the lone exception. + // Only path-valued keys convert; the workspace name and policy values are not paths. + for (const key of SETUP_RUNNER_PATH_ENV_KEYS) { + const value = envVars[key] + if (value) { + envVars[key] = nativeWindowsPathToPosixShellPath(value) + } + } } return { runnerScriptPath, envVars, + // Why: WSL git returns /mnt paths that Node converts back to C:\ for file + // writes; retain the runtime signal so launch converts them to /mnt again. + // Issue-command runners take the same resolved shell, so one session never + // mixes a bash setup runner with a cmd issue runner. + ...(launchShell ? { shell: launchShell } : {}), ...(waitForAgentStartup === true ? { waitForAgentStartup: true } : {}) } } +export function resolveSetupRunnerShell( + settings: SetupRunnerShellSettings, + platform: NodeJS.Platform = process.platform, + options: { resolveGitBashShellPath?: (shell: string) => string | null } = {} +): SetupRunnerShell | undefined { + if (platform !== 'win32') { + return undefined + } + + const terminalWindowsShell = settings?.terminalWindowsShell + const configuredShell = + typeof terminalWindowsShell === 'string' && terminalWindowsShell.trim() + ? terminalWindowsShell.trim() + : 'powershell.exe' + const shellBasename = configuredShell.replaceAll('\\', '/').split('/').pop()?.toLowerCase() + const family = resolveWindowsShellStartupFamily(configuredShell) + if (family === 'posix' && shellBasename !== 'wsl.exe' && shellBasename !== 'wsl') { + // Why: the PTY resolves Git Bash independently and falls back to PowerShell when it + // is missing, so gate the .sh runner on the same resolution. This also keeps + // non-Git bash flavors (Cygwin's /cygdrive, the System32 WSL shim's /mnt) off the + // MSYS-only /c/... form the posix runner emits. + const resolveGitBashShellPath = + options.resolveGitBashShellPath ?? + ((shell: string) => resolveWindowsGitBashShellPath(shell, { platform })) + if (resolveGitBashShellPath(configuredShell)) { + // Note: Git Bash users with batch-syntax orca.yaml setup content get a bash + // interpreter from here on. The flip is intentional and documented in + // docs/reference/windows-setup-shell.md. + return { family: 'posix' } + } + } + + // Why: existing Windows setup scripts were authored for Orca's cmd runner; + // PowerShell, wsl.exe-as-terminal, and Windows-host projects can invoke it + // without changing syntax, so they intentionally stay on the cmd runner. + return { family: 'cmd' } +} + /** * Run a named hook script in the given working directory. */ diff --git a/src/main/index.ts b/src/main/index.ts index 2c94c61488c..3521070b55c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1406,6 +1406,7 @@ function openMainWindow(): BrowserWindow { providerSession, providerSessionOnly, promptInteractionKey, + restoredUnconfirmed, isReplay }) => { if (mainWindow?.isDestroyed()) { @@ -1442,6 +1443,7 @@ function openMainWindow(): BrowserWindow { stateStartedAt, ...(providerSession ? { providerSession } : {}), ...(promptInteractionKey ? { promptInteractionKey } : {}), + ...(restoredUnconfirmed ? { restoredUnconfirmed: true } : {}), ...(orchestration ? { orchestration } : {}) }) recordAgentStateCrashBreadcrumb(payload.agentType ?? 'unknown', payload.state) @@ -2741,6 +2743,9 @@ void app.whenReady().then(async () => { // Why: mobile pairing needs the stable pre-setName() path (getCanonicalUserDataPath), not a late app.getPath('userData') that drops paired devices across restarts. userDataPath: getCanonicalUserDataPath(), enableWebSocket: true, + // Why: STA-2370 — the desktop app binds the WS listener to loopback until the user pairs a device; + // `orca serve` is an explicit remote opt-in, and E2E keeps the wide bind its harness connects over. + exposeNetworkByDefault: Boolean(serveOptions) || isE2E, ...(isE2E ? { wsPort: e2eWsPort } : {}), ...(devWsPort !== undefined ? { wsPort: devWsPort } : {}), ...(serveOptions?.wsPort !== undefined diff --git a/src/main/ipc/ai-vault-host-discovery.ts b/src/main/ipc/ai-vault-host-discovery.ts new file mode 100644 index 00000000000..e8f1f51fb23 --- /dev/null +++ b/src/main/ipc/ai-vault-host-discovery.ts @@ -0,0 +1,29 @@ +import type { AiVaultListResult } from '../../shared/ai-vault-types' +import { aiVaultScanIssueResult } from '../ai-vault/session-list-results' + +export type AiVaultHostDiscoveryResult = { + hostInfos: readonly T[] + issue?: AiVaultListResult +} + +/** + * Why: enumerating runtime/SSH hosts reads live session state and can throw. In + * 'all' scope that rejection would take down the whole Promise.all and drop the + * local sessions too, so a broken enumerator degrades to one issue row instead. + */ +export function discoverAiVaultHosts( + enumerate: () => readonly T[], + args: { path: string; fallbackMessage: string } +): AiVaultHostDiscoveryResult { + try { + return { hostInfos: enumerate() } + } catch (error) { + return { + hostInfos: [], + issue: aiVaultScanIssueResult({ + path: args.path, + message: error instanceof Error ? error.message : args.fallbackMessage + }) + } + } +} diff --git a/src/main/ipc/ai-vault-host-leg-cache.ts b/src/main/ipc/ai-vault-host-leg-cache.ts new file mode 100644 index 00000000000..9911e81e98b --- /dev/null +++ b/src/main/ipc/ai-vault-host-leg-cache.ts @@ -0,0 +1,78 @@ +import type { AiVaultListResult } from '../../shared/ai-vault-types' +import { + aiVaultSessionDepthCovers, + truncateAiVaultListResult, + type AiVaultSessionDepth +} from '../../shared/ai-vault-session-depth' + +export const AI_VAULT_CACHE_TTL_MS = 15_000 + +type CachedHostLeg = { + depth: AiVaultSessionDepth + result: AiVaultListResult + expiresAt: number +} + +// Why: the merged result is only cacheable when every host answered, so one +// flaky host used to force a full rescan of every healthy host on each panel +// open. Legs are cached individually and the failing host is the only one +// rescanned. +const cachedHostLegs = new Map() + +/** Serves one host's leg from the per-host TTL cache, and stores it only when + * that host answered without a host issue — a failing host is retried on the + * next open while its healthy neighbours stay cached. */ +export async function scanHostLegWithCache(args: { + cacheKey: string + depth: AiVaultSessionDepth + scopePaths?: readonly string[] + force: boolean + scan: () => Promise +}): Promise { + const now = Date.now() + const cached = cachedHostLegs.get(args.cacheKey) + if ( + !args.force && + cached && + cached.expiresAt > now && + aiVaultSessionDepthCovers(cached.depth, args.depth) + ) { + return truncateAiVaultListResult(cached.result, args.depth, args.scopePaths) + } + const result = await args.scan() + if (result.issues.some((issue) => issue.kind === 'host')) { + const current = cachedHostLegs.get(args.cacheKey) + if (!current || current.expiresAt <= Date.now()) { + cachedHostLegs.delete(args.cacheKey) + } + return result + } + pruneExpiredHostLegs(now) + const current = cachedHostLegs.get(args.cacheKey) + if ( + !args.force && + current && + current.expiresAt > Date.now() && + aiVaultSessionDepthCovers(current.depth, args.depth) + ) { + return result + } + cachedHostLegs.set(args.cacheKey, { + depth: args.depth, + result, + expiresAt: Date.now() + AI_VAULT_CACHE_TTL_MS + }) + return result +} + +function pruneExpiredHostLegs(now: number): void { + for (const [cacheKey, entry] of cachedHostLegs) { + if (entry.expiresAt <= now) { + cachedHostLegs.delete(cacheKey) + } + } +} + +export function resetAiVaultHostLegCacheForTests(): void { + cachedHostLegs.clear() +} diff --git a/src/main/ipc/ai-vault-runtime-scan.ts b/src/main/ipc/ai-vault-runtime-scan.ts new file mode 100644 index 00000000000..f9432f143a8 --- /dev/null +++ b/src/main/ipc/ai-vault-runtime-scan.ts @@ -0,0 +1,95 @@ +import { + isAiVaultScanCancelledError, + type AiVaultListArgs, + type AiVaultListResult +} from '../../shared/ai-vault-types' +import { + abandonRemoteSessionScanOnCancel, + throwIfAiVaultScanCancelled +} from '../ai-vault/ai-vault-scan-cancellation' +import { aiVaultScanIssueResult } from '../ai-vault/session-list-results' + +export type RuntimeAiVaultHostInfo = { + environmentId: string + executionHostId: `runtime:${string}` +} + +export type RuntimeAiVaultScanOptions = { + timeoutMs?: number +} + +export type RuntimeAiVaultScanner = ( + environmentId: string, + args: AiVaultListArgs, + options?: RuntimeAiVaultScanOptions +) => Promise + +/** + * Why: an unreachable Orca server must cost this host's row, not the whole + * multi-host list, so every failure except cancellation degrades to an issue. + */ +export async function scanRuntimeAiVaultSessions(args: { + hostInfo: RuntimeAiVaultHostInfo + scanner: RuntimeAiVaultScanner | undefined + listArgs?: AiVaultListArgs + options?: RuntimeAiVaultScanOptions & { signal?: AbortSignal } +}): Promise { + const { signal, ...scannerOptions } = args.options ?? {} + throwIfAiVaultScanCancelled(signal) + if (!args.scanner) { + return runtimeScanIssueResult( + args.hostInfo, + 'Agent Session History is not available for this execution host.' + ) + } + try { + return await abandonRemoteSessionScanOnCancel( + args.scanner(args.hostInfo.environmentId, runtimeScanArgs(args.hostInfo, args.listArgs), { + ...scannerOptions + }), + signal + ) + } catch (error) { + // RPC rejections keep the message but lose Error.name, so classify on both. + if (isAiVaultScanCancelledError(error)) { + throw error + } + return runtimeScanIssueResult( + args.hostInfo, + error instanceof Error ? error.message : 'Remote Orca server is unavailable.' + ) + } +} + +// Optional keys are copied only when present so the RPC schema never sees an +// explicit undefined for limit/force/scopePaths. +function runtimeScanArgs( + hostInfo: RuntimeAiVaultHostInfo, + listArgs: AiVaultListArgs | undefined +): AiVaultListArgs { + const scanArgs: AiVaultListArgs = { executionHostScope: hostInfo.executionHostId } + if (listArgs?.limit !== undefined) { + scanArgs.limit = listArgs.limit + } + if (listArgs?.unlimited !== undefined) { + scanArgs.unlimited = listArgs.unlimited + } + if (listArgs?.force !== undefined) { + scanArgs.force = listArgs.force + } + if (listArgs?.scopePaths !== undefined) { + scanArgs.scopePaths = listArgs.scopePaths + } + return scanArgs +} + +function runtimeScanIssueResult( + hostInfo: RuntimeAiVaultHostInfo, + message: string +): AiVaultListResult { + return aiVaultScanIssueResult({ + executionHostId: hostInfo.executionHostId, + path: hostInfo.environmentId, + message + }) +} diff --git a/src/main/ipc/ai-vault-scan-coalescing.test.ts b/src/main/ipc/ai-vault-scan-coalescing.test.ts new file mode 100644 index 00000000000..3a8cd3bd149 --- /dev/null +++ b/src/main/ipc/ai-vault-scan-coalescing.test.ts @@ -0,0 +1,230 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import type { AiVaultListResult } from '../../shared/ai-vault-types' +import type { IFilesystemProvider } from '../providers/types' +import { getRemoteHostPlatform } from '../ssh/ssh-remote-platform' + +const mocks = vi.hoisted(() => ({ + scanAiVaultSessions: vi.fn(), + scanRemoteAiVaultSessions: vi.fn(), + scanRuntimeAiVaultSessions: vi.fn(), + getSshFilesystemProvider: vi.fn(), + getActiveSshAiVaultHostInfo: vi.fn(), + getActiveSshAiVaultHostInfos: vi.fn(), + requestActiveSshAiVaultSessionList: vi.fn(), + ipcHandle: vi.fn() +})) + +vi.mock('electron', () => ({ app: { on: vi.fn() }, ipcMain: { handle: mocks.ipcHandle } })) +vi.mock('../ai-vault/session-scanner', () => ({ + scanAiVaultSessions: mocks.scanAiVaultSessions +})) +vi.mock('../ai-vault/remote-session-scanner', () => ({ + scanRemoteAiVaultSessions: mocks.scanRemoteAiVaultSessions +})) +vi.mock('../wsl', () => ({ + getWslHomeAsync: vi.fn(), + listWslDistrosAsync: vi.fn().mockResolvedValue([]) +})) +vi.mock('../providers/ssh-filesystem-dispatch', () => ({ + SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE: 'SSH unavailable', + getSshFilesystemProvider: mocks.getSshFilesystemProvider +})) +vi.mock('./ssh', () => ({ + getActiveSshAiVaultHostInfo: mocks.getActiveSshAiVaultHostInfo, + getActiveSshAiVaultHostInfos: mocks.getActiveSshAiVaultHostInfos, + requestActiveSshAiVaultSessionList: mocks.requestActiveSshAiVaultSessionList +})) + +const { _internals, registerAiVaultHandlers } = await import('./ai-vault') +const EMPTY_RESULT: AiVaultListResult = { + sessions: [], + issues: [], + scannedAt: '2026-07-27T00:00:00.000Z' +} + +beforeEach(() => { + vi.clearAllMocks() + _internals.resetAiVaultCacheForTests() + mocks.scanAiVaultSessions.mockResolvedValue(EMPTY_RESULT) + mocks.scanRemoteAiVaultSessions.mockResolvedValue(EMPTY_RESULT) + mocks.scanRuntimeAiVaultSessions.mockResolvedValue(EMPTY_RESULT) + mocks.getSshFilesystemProvider.mockReturnValue({} as IFilesystemProvider) + mocks.getActiveSshAiVaultHostInfo.mockReturnValue(hostInfo()) + mocks.getActiveSshAiVaultHostInfos.mockReturnValue([hostInfo()]) + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue(null) +}) + +describe('Agent Session History scan coalescing', () => { + it.each([ + ['local', mocks.scanAiVaultSessions], + ['runtime:remote-server', mocks.scanRuntimeAiVaultSessions] + ] as const)('coalesces %s scans while isolating caller cancellation', async (scope, scan) => { + let resolveScan: ((result: AiVaultListResult) => void) | undefined + scan.mockImplementation( + () => + new Promise((resolve) => { + resolveScan = resolve + }) + ) + registerRuntimeHost() + const firstController = new AbortController() + const first = _internals.listAiVaultSessions( + { executionHostScope: scope }, + { signal: firstController.signal } + ) + const second = _internals.listAiVaultSessions({ executionHostScope: scope }) + await vi.waitFor(() => expect(resolveScan).toBeDefined()) + + firstController.abort() + + await expect(first).rejects.toMatchObject({ name: 'AbortError' }) + expect(scan).toHaveBeenCalledTimes(1) + resolveScan?.(EMPTY_RESULT) + await expect(second).resolves.toEqual(EMPTY_RESULT) + }) + + it('coalesces every all-host leg while isolating caller cancellation', async () => { + let resolveRuntime: ((result: AiVaultListResult) => void) | undefined + mocks.scanRuntimeAiVaultSessions.mockImplementation( + () => + new Promise((resolve) => { + resolveRuntime = resolve + }) + ) + registerRuntimeHost() + const controller = new AbortController() + + const first = _internals.listAiVaultSessions( + { executionHostScope: 'all' }, + { signal: controller.signal } + ) + const firstRejection = expect(first).rejects.toMatchObject({ name: 'AbortError' }) + const second = _internals.listAiVaultSessions({ executionHostScope: 'all' }) + await vi.waitFor(() => expect(resolveRuntime).toBeDefined()) + + expect(mocks.scanAiVaultSessions).toHaveBeenCalledTimes(1) + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(mocks.scanRuntimeAiVaultSessions).toHaveBeenCalledTimes(1) + controller.abort() + await firstRejection + resolveRuntime?.(EMPTY_RESULT) + await expect(second).resolves.toMatchObject({ sessions: [], issues: [] }) + }) + + it('keeps a shared multi-window scan alive when one window cancels', async () => { + let resolveRelay: ((result: AiVaultListResult) => void) | undefined + mocks.requestActiveSshAiVaultSessionList.mockImplementation( + () => + new Promise((resolve) => { + resolveRelay = resolve + }) + ) + registerAiVaultHandlers() + const list = ipcHandler('aiVault:listSessions') + const cancel = ipcHandler('aiVault:cancelListSessions') + const firstEvent = { sender: { id: 1 } } + const secondEvent = { sender: { id: 2 } } + const first = list(firstEvent, { + executionHostScope: 'ssh:dev-box', + requestToken: 'scan' + }) as Promise + const second = list(secondEvent, { + executionHostScope: 'ssh:dev-box', + requestToken: 'scan' + }) as Promise + await vi.waitFor(() => expect(resolveRelay).toBeDefined()) + + cancel(firstEvent, { requestToken: 'scan' }) + + // Electron logs every rejected handler, so a cancelled scan resolves instead. + await expect(first).resolves.toMatchObject({ cancelled: true, sessions: [], issues: [] }) + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledTimes(1) + resolveRelay?.(EMPTY_RESULT) + await expect(second).resolves.toEqual(EMPTY_RESULT) + }) + + it('reports a real scan failure as a host issue rather than cancellation', async () => { + mocks.requestActiveSshAiVaultSessionList.mockRejectedValue(new Error('relay socket closed')) + mocks.scanRemoteAiVaultSessions.mockRejectedValue(new Error('relay socket closed')) + registerAiVaultHandlers() + const list = ipcHandler('aiVault:listSessions') + + // SSH host legs convert unexpected throws into scan issues so an `all` + // multi-host list still returns the other hosts' sessions. + const result = await list( + { sender: { id: 1 } }, + { executionHostScope: 'ssh:dev-box', requestToken: 'scan' } + ) + expect(result).toMatchObject({ + sessions: [], + issues: [expect.objectContaining({ message: 'relay socket closed', kind: 'host' })] + }) + expect(result).not.toHaveProperty('cancelled') + }) + + it('still rejects the handler when a scan fails for a non-cancellation reason', async () => { + mocks.scanAiVaultSessions.mockRejectedValue(new Error('transcript root is unreadable')) + registerAiVaultHandlers() + const list = ipcHandler('aiVault:listSessions') + + await expect( + list({ sender: { id: 1 } }, { executionHostScope: 'local', requestToken: 'scan' }) + ).rejects.toThrow('transcript root is unreadable') + }) + + it('re-joins a preempted same-scope caller onto the forced refresh', async () => { + const signals: AbortSignal[] = [] + let resolveForced: ((result: AiVaultListResult) => void) | undefined + mocks.requestActiveSshAiVaultSessionList.mockImplementation( + (_targetId, _params, options: { signal: AbortSignal }) => { + signals.push(options.signal) + return new Promise((resolve) => { + if (signals.length === 1) { + options.signal.addEventListener('abort', () => resolve(EMPTY_RESULT), { once: true }) + } else { + resolveForced = resolve + } + }) + } + ) + const first = _internals.listAiVaultSessions({ executionHostScope: 'ssh:dev-box' }) + await vi.waitFor(() => expect(signals).toHaveLength(1)) + + const forced = _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + force: true + }) + await vi.waitFor(() => expect(signals).toHaveLength(2)) + + expect(signals[0]?.aborted).toBe(true) + resolveForced?.(EMPTY_RESULT) + // Another window's Refresh must not surface as this caller's cancellation. + await expect(Promise.all([first, forced])).resolves.toEqual([EMPTY_RESULT, EMPTY_RESULT]) + }) +}) + +function registerRuntimeHost(): void { + registerAiVaultHandlers({ + getActiveRuntimeAiVaultHostInfos: () => [ + { environmentId: 'remote-server', executionHostId: 'runtime:remote-server' } + ], + scanRuntimeAiVaultSessions: mocks.scanRuntimeAiVaultSessions + }) +} + +function hostInfo() { + return { + targetId: 'dev-box', + executionHostId: 'ssh:dev-box' as const, + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64') + } +} + +function ipcHandler(channel: string): (...args: unknown[]) => unknown { + const registration = mocks.ipcHandle.mock.calls.find(([registered]) => registered === channel) + if (!registration) { + throw new Error(`${channel} was not registered`) + } + return registration[1] +} diff --git a/src/main/ipc/ai-vault.test.ts b/src/main/ipc/ai-vault.test.ts index 5f4153106fd..1ecc3bb0a89 100644 --- a/src/main/ipc/ai-vault.test.ts +++ b/src/main/ipc/ai-vault.test.ts @@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import type { AiVaultListResult, AiVaultSession } from '../../shared/ai-vault-types' import type { IFilesystemProvider } from '../providers/types' import { getRemoteHostPlatform } from '../ssh/ssh-remote-platform' +import { SSH_MUX_REQUEST_TIMEOUT_CODE } from '../ssh/ssh-channel-multiplexer' const mocks = vi.hoisted(() => ({ scanAiVaultSessions: vi.fn(), @@ -14,6 +15,7 @@ const mocks = vi.hoisted(() => ({ getSshFilesystemProvider: vi.fn(), getActiveSshAiVaultHostInfo: vi.fn(), getActiveSshAiVaultHostInfos: vi.fn(), + requestActiveSshAiVaultSessionList: vi.fn(), ipcHandle: vi.fn() })) @@ -47,7 +49,8 @@ vi.mock('../providers/ssh-filesystem-dispatch', () => ({ vi.mock('./ssh', () => ({ getActiveSshAiVaultHostInfo: mocks.getActiveSshAiVaultHostInfo, - getActiveSshAiVaultHostInfos: mocks.getActiveSshAiVaultHostInfos + getActiveSshAiVaultHostInfos: mocks.getActiveSshAiVaultHostInfos, + requestActiveSshAiVaultSessionList: mocks.requestActiveSshAiVaultSessionList })) const { _internals, registerAiVaultHandlers } = await import('./ai-vault') @@ -66,6 +69,7 @@ beforeEach(() => { result([session('runtime:remote-server', 'runtime-session')]) ) mocks.getSshFilesystemProvider.mockReturnValue(provider) + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue(null) mocks.getActiveSshAiVaultHostInfo.mockReturnValue(hostInfo('dev-box')) mocks.getActiveSshAiVaultHostInfos.mockReturnValue([hostInfo('dev-box')]) }) @@ -101,11 +105,160 @@ describe('listAiVaultSessions host routing', () => { ) }) + it('uses one target-side relay scan when the SSH relay supports it', async () => { + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue( + result([session('local', 'remote-session')]) + ) + + const scanned = await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + scopePaths: ['/home/ada/repo'] + }) + + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledWith( + 'dev-box', + { + limit: undefined, + scopePaths: ['/home/ada/repo'] + }, + expect.objectContaining({ signal: expect.any(AbortSignal) }) + ) + expect(mocks.scanRemoteAiVaultSessions).not.toHaveBeenCalled() + expect(scanned.sessions[0]).toMatchObject({ + executionHostId: 'ssh:dev-box', + id: expect.stringContaining('ssh:dev-box:') + }) + }) + + it('marks oversized project scopes when sending their bounded relay form', async () => { + const scopePaths = Array.from({ length: 80 }, (_, index) => `/repo/${index}`) + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue(result([])) + + await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + scopePaths + }) + + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledWith( + 'dev-box', + { + limit: undefined, + scopePaths: scopePaths.slice(0, 64), + scopePathsTruncated: true + }, + expect.objectContaining({ signal: expect.any(AbortSignal) }) + ) + }) + + it('caps and reports oversized project scopes on the SSH filesystem fallback', async () => { + const scopePaths = Array.from({ length: 80 }, (_, index) => `/repo/${index}`) + + const scanned = await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + scopePaths + }) + + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledWith( + expect.objectContaining({ scopePaths: scopePaths.slice(0, 64) }) + ) + expect(scanned.issues).toContainEqual( + expect.objectContaining({ + kind: 'scope', + message: expect.stringContaining('first 64 project paths') + }) + ) + }) + + it('coalesces concurrent cancellable requests into one scan', async () => { + let resolveRelay: (() => void) | undefined + mocks.requestActiveSshAiVaultSessionList.mockImplementation( + () => + new Promise((resolve) => { + resolveRelay = () => resolve(result([])) + }) + ) + const args = { executionHostScope: 'ssh:dev-box' as const } + + const first = _internals.listAiVaultSessions(args, { signal: new AbortController().signal }) + const second = _internals.listAiVaultSessions(args, { signal: new AbortController().signal }) + await vi.waitFor(() => expect(resolveRelay).toBeDefined()) + + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledTimes(1) + resolveRelay?.() + await expect(Promise.all([first, second])).resolves.toHaveLength(2) + }) + + it('does not start a second remote crawl after the relay scan budget expires', async () => { + mocks.requestActiveSshAiVaultSessionList.mockRejectedValue(relayTimeoutError()) + + const scanned = await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box' + }) + + expect(mocks.scanRemoteAiVaultSessions).not.toHaveBeenCalled() + expect(scanned.sessions).toEqual([]) + expect(scanned.issues[0]?.message).toContain('timed out') + }) + + it('does not cache a host-level relay failure', async () => { + mocks.requestActiveSshAiVaultSessionList.mockRejectedValue(relayTimeoutError()) + + await _internals.listAiVaultSessions({ executionHostScope: 'ssh:dev-box' }) + await _internals.listAiVaultSessions({ executionHostScope: 'ssh:dev-box' }) + + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledTimes(2) + }) + + it('falls back to the filesystem crawl after a non-timeout relay failure', async () => { + mocks.requestActiveSshAiVaultSessionList.mockRejectedValue( + new Error('Invalid aiVault.listSessions response') + ) + + const scanned = await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box' + }) + + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(scanned.sessions).toEqual([expect.objectContaining({ sessionId: 'remote-session' })]) + }) + + it('falls back when a nonempty relay sessions array contains no valid rows', async () => { + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue({ + sessions: [{ id: 42 }], + issues: [], + scannedAt: '2026-07-27T00:00:00.000Z' + }) + + const scanned = await _internals.listAiVaultSessions({ executionHostScope: 'ssh:dev-box' }) + + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(scanned.sessions).toEqual([expect.objectContaining({ sessionId: 'remote-session' })]) + }) + + it('uses the relay scan without requiring the fallback filesystem provider', async () => { + mocks.getSshFilesystemProvider.mockReturnValue(undefined) + mocks.requestActiveSshAiVaultSessionList.mockResolvedValue( + result([session('local', 'remote-session')]) + ) + + const scanned = await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box' + }) + + expect(scanned.sessions).toHaveLength(1) + expect(mocks.scanRemoteAiVaultSessions).not.toHaveBeenCalled() + }) + it('merges local plus connected SSH targets for all hosts', async () => { const result = await _internals.listAiVaultSessions({ executionHostScope: 'all' }) expect(mocks.scanAiVaultSessions).toHaveBeenCalledTimes(1) expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + expect(mocks.requestActiveSshAiVaultSessionList).toHaveBeenCalledWith( + 'dev-box', + expect.any(Object), + expect.objectContaining({ timeoutMs: 15_000 }) + ) expect(result.sessions.map((entry) => entry.executionHostId)).toEqual(['ssh:dev-box', 'local']) }) @@ -159,6 +312,50 @@ describe('listAiVaultSessions host routing', () => { ]) }) + it('keeps SSH results when the local scan itself throws', async () => { + // Why: `all` awaits every leg together, so an unguarded local throw (parse + // cache load, WSL home resolution) would discard every host's sessions. + mocks.scanAiVaultSessions.mockRejectedValue(new Error('session parse cache is corrupt')) + registerAiVaultHandlers({ + getActiveRuntimeAiVaultHostInfos: () => [], + scanRuntimeAiVaultSessions: mocks.scanRuntimeAiVaultSessions + }) + + const result = await _internals.listAiVaultSessions({ executionHostScope: 'all' }) + + expect(result.sessions.map((entry) => entry.executionHostId)).toEqual(['ssh:dev-box']) + expect(result.issues).toEqual([ + expect.objectContaining({ + executionHostId: 'local', + kind: 'host', + path: 'this computer', + message: 'session parse cache is corrupt' + }) + ]) + }) + + it('keeps local results when SSH host discovery fails', async () => { + mocks.getActiveSshAiVaultHostInfos.mockImplementation(() => { + throw new Error('relay session map is unavailable') + }) + registerAiVaultHandlers({ + getActiveRuntimeAiVaultHostInfos: () => [], + scanRuntimeAiVaultSessions: mocks.scanRuntimeAiVaultSessions + }) + + const result = await _internals.listAiVaultSessions({ executionHostScope: 'all' }) + + expect(mocks.scanAiVaultSessions).toHaveBeenCalledTimes(1) + expect(result.sessions.map((entry) => entry.executionHostId)).toEqual(['local']) + expect(result.issues).toEqual([ + expect.objectContaining({ + agent: 'codex', + path: 'SSH hosts', + message: 'relay session map is unavailable' + }) + ]) + }) + it('keeps direct runtime host scans on the normal runtime timeout', async () => { registerAiVaultHandlers({ getActiveRuntimeAiVaultHostInfos: () => [], @@ -205,6 +402,63 @@ describe('listAiVaultSessions host routing', () => { expect(mocks.scanAiVaultSessions).toHaveBeenCalledTimes(1) expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) }) + + it('caches completed SSH scans by host and workspace scope', async () => { + await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + scopePaths: ['/home/ada/repo-a', '/home/ada/repo-b'] + }) + await _internals.listAiVaultSessions({ + executionHostScope: 'ssh:dev-box', + scopePaths: ['/home/ada/repo-b', '/home/ada/repo-a'] + }) + + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + }) + + it('serves lower SSH depths from a larger completed scan', async () => { + const base = { executionHostScope: 'ssh:dev-box' as const, scopePaths: ['/home/ada/repo'] } + await _internals.listAiVaultSessions({ ...base, limit: 1000 }) + await _internals.listAiVaultSessions({ ...base, limit: 250 }) + await _internals.listAiVaultSessions({ ...base, limit: 500 }) + + expect(mocks.scanRemoteAiVaultSessions).toHaveBeenCalledTimes(1) + }) + + it('threads renderer cancellation into the SSH relay request', async () => { + let relaySignal: AbortSignal | undefined + mocks.requestActiveSshAiVaultSessionList.mockImplementation( + (_targetId, _params, options: { signal?: AbortSignal }) => + new Promise((_resolve, reject) => { + relaySignal = options.signal + options.signal?.addEventListener( + 'abort', + () => { + const error = new Error('cancelled') + error.name = 'AbortError' + reject(error) + }, + { once: true } + ) + }) + ) + registerAiVaultHandlers() + const event = { sender: { id: 7 } } + const pending = getIpcHandler('aiVault:listSessions')(event, { + executionHostScope: 'ssh:dev-box', + requestToken: 'scan-1' + }) + await vi.waitFor(() => expect(relaySignal).toBeDefined()) + + await getIpcHandler('aiVault:cancelListSessions')(event, { + requestToken: 'scan-1' + }) + + expect(relaySignal?.aborted).toBe(true) + // Resolved, not rejected: Electron logs every rejected handler, and a + // superseded scan is normal control flow rather than a failure. + await expect(pending).resolves.toMatchObject({ cancelled: true, sessions: [] }) + }) }) describe('prepareSessionResume IPC', () => { @@ -280,6 +534,14 @@ function getPrepareSessionResumeHandler(): ( return registration[1] } +function getIpcHandler(channel: string): (...args: unknown[]) => unknown { + const registration = mocks.ipcHandle.mock.calls.find(([registered]) => registered === channel) + if (!registration) { + throw new Error(`${channel} was not registered`) + } + return registration[1] +} + describe('listAiVaultSubagentSessions gating', () => { const claudeRoot = join(homedir(), '.claude', 'projects') @@ -365,6 +627,14 @@ function hostInfo(targetId: string) { } } +/** Mirrors the multiplexer's typed timeout: callers branch on the code, not on + * the message text. */ +function relayTimeoutError(): Error { + return Object.assign(new Error('Request "aiVault.listSessions" timed out after 130000ms'), { + code: SSH_MUX_REQUEST_TIMEOUT_CODE + }) +} + function result(sessions: AiVaultSession[]): AiVaultListResult { return { sessions, issues: [], scannedAt: new Date().toISOString() } } diff --git a/src/main/ipc/ai-vault.ts b/src/main/ipc/ai-vault.ts index e103b7b5cd4..5d3b0bd2e79 100644 --- a/src/main/ipc/ai-vault.ts +++ b/src/main/ipc/ai-vault.ts @@ -7,17 +7,24 @@ import { resetAiVaultSessionListCacheForTests, type AiVaultSessionSources } from '../ai-vault/cached-session-list' -import { scanRemoteAiVaultSessions } from '../ai-vault/remote-session-scanner' import { listClaudeSubagentSessions } from '../ai-vault/session-scanner-claude-subagents' import { claudeProjectsRootDirs } from '../ai-vault/session-scanner-source-discovery' import { isPathInsideOrEqual } from '../../shared/cross-platform-path' -import { aiVaultScanIssueResult, mergeAiVaultListResults } from '../ai-vault/session-list-results' -import type { - AiVaultFirstUserPromptArgs, - AiVaultListArgs, - AiVaultListResult, - AiVaultSubagentListArgs, - AiVaultSubagentListResult +import { + aiVaultScanIssueResult, + cancelledAiVaultListResult, + mergeAiVaultListResults +} from '../ai-vault/session-list-results' +import { scanSshAiVaultSessions } from '../ai-vault/ssh-session-list' +import { AiVaultScanCoordinator } from '../ai-vault/ai-vault-scan-coordinator' +import { + AI_VAULT_SCOPE_PATHS_MAX_COUNT, + isAiVaultScanCancelledError, + type AiVaultFirstUserPromptArgs, + type AiVaultListArgs, + type AiVaultListResult, + type AiVaultSubagentListArgs, + type AiVaultSubagentListResult } from '../../shared/ai-vault-types' import { handleAiVaultGetFirstUserPrompt } from '../ai-vault/session-first-user-prompt-read' import { registerAiVaultResumeHandler, type AiVaultResumeHandlerOptions } from './ai-vault-resume' @@ -29,126 +36,150 @@ import { toSshExecutionHostId, type ExecutionHostScope } from '../../shared/execution-host' +import { getActiveSshAiVaultHostInfos } from './ssh' +import { createSenderScopedRequestCancellations } from './sender-scoped-request-cancellation' +import { discoverAiVaultHosts, type AiVaultHostDiscoveryResult } from './ai-vault-host-discovery' import { - getSshFilesystemProvider, - SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE -} from '../providers/ssh-filesystem-dispatch' -import { getActiveSshAiVaultHostInfo, getActiveSshAiVaultHostInfos } from './ssh' + scanRuntimeAiVaultSessions, + type RuntimeAiVaultHostInfo, + type RuntimeAiVaultScanner +} from './ai-vault-runtime-scan' +import { resetAiVaultHostLegCacheForTests, scanHostLegWithCache } from './ai-vault-host-leg-cache' +import { requestedAiVaultSessionDepth } from '../../shared/ai-vault-session-depth' -const AI_VAULT_CACHE_TTL_MS = 15_000 const AI_VAULT_ALL_HOST_RUNTIME_TIMEOUT_MS = 3_000 +// Why: a remote home with many agent roots routinely needs seconds to walk, +// stat and parse. The old shared 3s bound emptied healthy SSH hosts in the +// all-hosts view; the relay gets a real scan budget and the whole leg (relay +// attempt plus any legacy crawl) stays bounded so one host can't hold the +// merge open. +const AI_VAULT_ALL_HOST_SSH_RELAY_TIMEOUT_MS = 15_000 +const AI_VAULT_ALL_HOST_SSH_TIMEOUT_MS = 20_000 type AiVaultHandlerOptions = AiVaultSessionSources & AiVaultResumeHandlerOptions & { getActiveRuntimeAiVaultHostInfos?: () => readonly RuntimeAiVaultHostInfo[] - scanRuntimeAiVaultSessions?: ( - environmentId: string, - args: AiVaultListArgs, - options?: RuntimeAiVaultScanOptions - ) => Promise + scanRuntimeAiVaultSessions?: RuntimeAiVaultScanner } -type RuntimeAiVaultScanOptions = { - timeoutMs?: number -} - -type CachedAiVaultList = { - key: string - result: AiVaultListResult - expiresAt: number -} - -type RuntimeAiVaultHostInfo = { - environmentId: string - executionHostId: `runtime:${string}` -} - -let cachedList: CachedAiVaultList | null = null -let inflightList: Promise | null = null -let inflightKey: string | null = null +let scanCoordinator = new AiVaultScanCoordinator() let handlerOptions: AiVaultHandlerOptions = {} +const listCancellations = createSenderScopedRequestCancellations() -async function listAiVaultSessions(args?: AiVaultListArgs): Promise { +async function listAiVaultSessions( + args?: AiVaultListArgs, + options: { signal?: AbortSignal } = {} +): Promise { const executionHostScope = normalizeExecutionHostScope( args?.executionHostScope ?? LOCAL_EXECUTION_HOST_ID ) - // Why: local-scope scans go straight to the shared cache module (also used by - // the runtime RPC method), so the desktop panel and a paired mobile client - // never double-scan the same transcripts; the cache below only has to dedupe - // the multi-host (ssh/runtime/all) merges that exist on the desktop side. - if (executionHostScope === LOCAL_EXECUTION_HOST_ID) { - return scanLocalAiVaultSessions(args) - } // Scope paths change the result set, so they must be part of the cache key. + // A scanner consumes at most 64 paths, so smaller equivalent workspace sets + // can share a snapshot regardless of which worktree was selected first. + const scopePaths = args?.scopePaths ?? [] const key = JSON.stringify({ - limit: args?.limit ?? 'default', - scopePaths: args?.scopePaths ?? [], + scopePaths: + scopePaths.length <= AI_VAULT_SCOPE_PATHS_MAX_COUNT + ? [...new Set(scopePaths)].sort() + : scopePaths, executionHostScope }) - const now = Date.now() - // Why: opening this panel repeatedly should not re-parse hundreds of JSONL - // transcripts; explicit refreshes bypass the cache but not an active scan. - if (args?.force !== true && cachedList?.key === key && cachedList.expiresAt > now) { - return cachedList.result - } - if (inflightList && inflightKey === key) { - return inflightList - } - - inflightKey = key - inflightList = scanAiVaultSessionsByHostScope(args, executionHostScope) - .then((result) => { - cachedList = { - key, - result, - expiresAt: Date.now() + AI_VAULT_CACHE_TTL_MS + const depth = requestedAiVaultSessionDepth(args) + const scanKey = JSON.stringify({ key, depth }) + // Why: every renderer request carries its own cancellation signal, so + // coalescing has to survive them — the coordinator hands all same-key callers + // one scan and only aborts it once every one of them has cancelled. + return scanCoordinator.run({ + key: scanKey, + force: args?.force, + signal: options.signal, + start: (scanSignal) => { + const scan = () => scanAiVaultSessionsByHostScope(args, executionHostScope, scanSignal, key) + if (executionHostScope === LOCAL_EXECUTION_HOST_ID) { + return scan() } - return result - }) - .finally(() => { - // Only clear tracking if it still refers to this request: a concurrent - // different-scope scan may have replaced it and must stay dedupable. - if (inflightKey === key) { - inflightKey = null - inflightList = null - } - }) - return inflightList + return scanHostLegWithCache({ + cacheKey: key, + depth, + scopePaths, + force: args?.force === true, + scan + }) + } + }) } async function scanAiVaultSessionsByHostScope( args: AiVaultListArgs | undefined, - executionHostScope: ExecutionHostScope + executionHostScope: ExecutionHostScope, + signal?: AbortSignal, + cacheKey = '' ): Promise { + const depth = requestedAiVaultSessionDepth(args) + const scopePaths = args?.scopePaths ?? [] + if (executionHostScope === LOCAL_EXECUTION_HOST_ID) { + return scanLocalAiVaultSessions(args, signal) + } if (executionHostScope === 'all') { const runtimeHosts = getActiveRuntimeAiVaultHostInfosResult() - const runtimeResults = runtimeHosts.issue ? [runtimeHosts.issue] : [] + const sshHosts = getActiveSshAiVaultHostInfosResult() + const runtimeResults = [ + ...(runtimeHosts.issue ? [runtimeHosts.issue] : []), + ...(sshHosts.issue ? [sshHosts.issue] : []) + ] const scannedResults = await Promise.all([ - scanLocalAiVaultSessions(args), - ...getActiveSshAiVaultHostInfos().map((hostInfo) => - scanSshAiVaultSessions(hostInfo.targetId, args) + scanLocalAiVaultSessionsForAllScope(args, signal), + ...sshHosts.hostInfos.map((hostInfo) => + scanHostLegWithCache({ + cacheKey: `${cacheKey}|${toSshExecutionHostId(hostInfo.targetId)}`, + depth, + scopePaths, + force: args?.force === true, + scan: () => + scanSshAiVaultSessions(hostInfo.targetId, args, { + signal, + timeoutMs: AI_VAULT_ALL_HOST_SSH_TIMEOUT_MS, + relayTimeoutMs: AI_VAULT_ALL_HOST_SSH_RELAY_TIMEOUT_MS + }) + }) ), ...runtimeHosts.hostInfos.map((hostInfo) => - scanRuntimeAiVaultSessions(hostInfo, args, { - timeoutMs: AI_VAULT_ALL_HOST_RUNTIME_TIMEOUT_MS + scanHostLegWithCache({ + cacheKey: `${cacheKey}|${hostInfo.executionHostId}`, + depth, + scopePaths, + force: args?.force === true, + scan: () => + scanRuntimeAiVaultSessions({ + hostInfo, + scanner: handlerOptions.scanRuntimeAiVaultSessions, + listArgs: args, + options: { signal, timeoutMs: AI_VAULT_ALL_HOST_RUNTIME_TIMEOUT_MS } + }) }) ) ]) - return mergeAiVaultListResults([...scannedResults, ...runtimeResults], args?.limit) + return mergeAiVaultListResults( + [...scannedResults, ...runtimeResults], + args?.limit, + args?.unlimited + ) } const parsed = parseExecutionHostId(executionHostScope) if (parsed?.kind === 'ssh') { - return scanSshAiVaultSessions(parsed.targetId, args) + return scanSshAiVaultSessions(parsed.targetId, args, { signal }) } if (parsed?.kind === 'runtime') { - return scanRuntimeAiVaultSessions( - { + return scanRuntimeAiVaultSessions({ + hostInfo: { environmentId: parsed.environmentId, executionHostId: toRuntimeExecutionHostId(parsed.environmentId) }, - args - ) + scanner: handlerOptions.scanRuntimeAiVaultSessions, + listArgs: args, + options: { signal } + }) } return aiVaultScanIssueResult({ @@ -158,118 +189,57 @@ async function scanAiVaultSessionsByHostScope( }) } -function getActiveRuntimeAiVaultHostInfos(): readonly RuntimeAiVaultHostInfo[] { - return handlerOptions.getActiveRuntimeAiVaultHostInfos?.() ?? [] -} - -function getActiveRuntimeAiVaultHostInfosResult(): { - hostInfos: readonly RuntimeAiVaultHostInfo[] - issue?: AiVaultListResult -} { - try { - return { hostInfos: getActiveRuntimeAiVaultHostInfos() } - } catch (error) { - return { - hostInfos: [], - issue: runtimeHostDiscoveryIssueResult( - error instanceof Error ? error.message : 'Runtime hosts are unavailable.' - ) - } - } -} - -async function scanRuntimeAiVaultSessions( - hostInfo: RuntimeAiVaultHostInfo, - args?: AiVaultListArgs, - options: RuntimeAiVaultScanOptions = {} -): Promise { - const scanner = handlerOptions.scanRuntimeAiVaultSessions - if (!scanner) { - return runtimeScanIssueResult( - hostInfo, - 'Agent Session History is not available for this execution host.' - ) - } - const scanArgs: AiVaultListArgs = { executionHostScope: hostInfo.executionHostId } - if (args?.limit !== undefined) { - scanArgs.limit = args.limit - } - if (args?.force !== undefined) { - scanArgs.force = args.force - } - if (args?.scopePaths !== undefined) { - scanArgs.scopePaths = args.scopePaths - } - try { - return await scanner(hostInfo.environmentId, scanArgs, options) - } catch (error) { - return runtimeScanIssueResult( - hostInfo, - error instanceof Error ? error.message : 'Remote Orca server is unavailable.' - ) - } -} - -function runtimeScanIssueResult( - hostInfo: RuntimeAiVaultHostInfo, - message: string -): AiVaultListResult { - return aiVaultScanIssueResult({ - executionHostId: hostInfo.executionHostId, - path: hostInfo.environmentId, - message +function getActiveRuntimeAiVaultHostInfosResult(): AiVaultHostDiscoveryResult { + return discoverAiVaultHosts(() => handlerOptions.getActiveRuntimeAiVaultHostInfos?.() ?? [], { + path: 'runtime environments', + fallbackMessage: 'Runtime hosts are unavailable.' }) } -function runtimeHostDiscoveryIssueResult(message: string): AiVaultListResult { - return aiVaultScanIssueResult({ path: 'runtime environments', message }) +function getActiveSshAiVaultHostInfosResult(): AiVaultHostDiscoveryResult<{ targetId: string }> { + return discoverAiVaultHosts(getActiveSshAiVaultHostInfos, { + path: 'SSH hosts', + fallbackMessage: 'SSH hosts are unavailable.' + }) } -async function scanLocalAiVaultSessions(args?: AiVaultListArgs): Promise { +// Why: the SSH legs already degrade to an issue row so one bad host can't take +// the shared Promise.all down; the local leg can throw too (parse-cache load, +// WSL home resolution) and would otherwise discard every host's sessions. +async function scanLocalAiVaultSessionsForAllScope( + args: AiVaultListArgs | undefined, + signal: AbortSignal | undefined +): Promise { + try { + return await scanLocalAiVaultSessions(args, signal) + } catch (error) { + if (isAiVaultScanCancelledError(error)) { + throw error + } + return aiVaultScanIssueResult({ + executionHostId: LOCAL_EXECUTION_HOST_ID, + path: 'this computer', + message: error instanceof Error ? error.message : 'Local session scan failed.' + }) + } +} + +async function scanLocalAiVaultSessions( + args?: AiVaultListArgs, + signal?: AbortSignal +): Promise { // Why: the shared cache module owns codex-home/WSL sourcing and the local // scan cache, so the desktop IPC path and the runtime RPC method (mobile) // share one cache instance and one source of managed-Codex homes. - return listCachedLocalAiVaultSessions({ - limit: args?.limit, - force: args?.force, - scopePaths: args?.scopePaths - }) -} - -async function scanSshAiVaultSessions( - targetId: string, - args?: AiVaultListArgs -): Promise { - const executionHostId = toSshExecutionHostId(targetId) - const hostInfo = getActiveSshAiVaultHostInfo(targetId) - const provider = getSshFilesystemProvider(targetId) - if (!hostInfo || !provider) { - return sshScanIssueResult({ - executionHostId, - targetId, - message: SSH_FILESYSTEM_PROVIDER_UNAVAILABLE_MESSAGE - }) - } - return scanRemoteAiVaultSessions({ - provider, - executionHostId: hostInfo.executionHostId, - remoteHome: hostInfo.remoteHome, - hostPlatform: hostInfo.hostPlatform, - limit: args?.limit, - scopePaths: args?.scopePaths - }) -} - -function sshScanIssueResult(args: { - executionHostId: `ssh:${string}` - targetId: string - message: string -}): AiVaultListResult { - return aiVaultScanIssueResult({ - executionHostId: args.executionHostId, - path: args.targetId, - message: args.message - }) + return listCachedLocalAiVaultSessions( + { + limit: args?.limit, + unlimited: args?.unlimited, + force: args?.force, + scopePaths: args?.scopePaths + }, + { signal } + ) } export function registerAiVaultHandlers(options: AiVaultHandlerOptions = {}): void { @@ -279,8 +249,32 @@ export function registerAiVaultHandlers(options: AiVaultHandlerOptions = {}): vo // WSL injection. The runtime also configures these sources from its deps // (serve-mode reachable); this desktop path supplies the same source. configureAiVaultSessionSources(options) - ipcMain.handle('aiVault:listSessions', (_event, args?: AiVaultListArgs) => - listAiVaultSessions(args) + ipcMain.handle('aiVault:listSessions', async (event, args?: AiVaultListArgs) => { + const requestToken = + typeof args?.requestToken === 'string' && args.requestToken.length <= 128 + ? args.requestToken + : undefined + const controller = listCancellations.begin(event, requestToken) + try { + return await listAiVaultSessions(args, { signal: controller?.signal }) + } catch (error) { + // Why: superseding a scan is normal control flow, but Electron logs every + // rejected handler — report it as a result so the log stays truthful. + if (!isAiVaultScanCancelledError(error)) { + throw error + } + return cancelledAiVaultListResult() + } finally { + listCancellations.finish(event, requestToken, controller) + } + }) + ipcMain.handle( + 'aiVault:cancelListSessions', + (event, args: { requestToken?: string } | undefined): void => { + if (typeof args?.requestToken === 'string' && args.requestToken.length <= 128) { + listCancellations.cancel(event, args.requestToken) + } + } ) registerAiVaultResumeHandler(options) ipcMain.handle( @@ -335,9 +329,8 @@ async function listAiVaultSubagentSessions( } function resetAiVaultCacheForTests(): void { - cachedList = null - inflightList = null - inflightKey = null + resetAiVaultHostLegCacheForTests() + scanCoordinator = new AiVaultScanCoordinator() handlerOptions = {} // The local leg delegates to the shared cache module; reset it too so tests // never see a scan cached by an earlier case. diff --git a/src/main/ipc/browser.test.ts b/src/main/ipc/browser.test.ts index c09fb2d7f80..4b233c17108 100644 --- a/src/main/ipc/browser.test.ts +++ b/src/main/ipc/browser.test.ts @@ -4,6 +4,7 @@ const { removeHandlerMock, handleMock, registerGuestMock, + attachGuestPoliciesMock, unregisterGuestMock, getGuestWebContentsIdMock, getWebContentsIdByTabIdMock, @@ -20,6 +21,7 @@ const { removeHandlerMock: vi.fn(), handleMock: vi.fn(), registerGuestMock: vi.fn(), + attachGuestPoliciesMock: vi.fn(), unregisterGuestMock: vi.fn(), getGuestWebContentsIdMock: vi.fn(), getWebContentsIdByTabIdMock: vi.fn(() => new Map()), @@ -53,6 +55,7 @@ vi.mock('../browser/browser-manager', () => ({ }, browserManager: { registerGuest: registerGuestMock, + attachGuestPolicies: attachGuestPoliciesMock, unregisterGuest: unregisterGuestMock, getGuestWebContentsId: getGuestWebContentsIdMock, getWebContentsIdByTabId: getWebContentsIdByTabIdMock, @@ -80,6 +83,7 @@ describe('registerBrowserHandlers', () => { handleMock.mockReset() registerGuestMock.mockReset() registerGuestMock.mockReturnValue(true) + attachGuestPoliciesMock.mockReset() unregisterGuestMock.mockReset() getGuestWebContentsIdMock.mockReset() getWebContentsIdByTabIdMock.mockReset() @@ -162,6 +166,93 @@ describe('registerBrowserHandlers', () => { } }) + it('validates exact live guest registration only for the trusted renderer', () => { + getGuestWebContentsIdMock.mockReturnValue(123) + registerBrowserHandlers() + const validateHandler = handleMock.mock.calls.find( + ([channel]) => channel === 'browser:isGuestRegistered' + )?.[1] as (event: { sender: Electron.WebContents }, args: unknown) => boolean + const trustedSender = { + id: 91, + isDestroyed: () => false, + getType: () => 'window', + getURL: () => 'file:///renderer/index.html' + } as Electron.WebContents + + expect( + validateHandler({ sender: trustedSender }, { browserPageId: 'page-1', webContentsId: 123 }) + ).toBe(true) + expect( + validateHandler({ sender: trustedSender }, { browserPageId: 'page-1', webContentsId: 124 }) + ).toBe(false) + + webContentsFromIdMock.mockReturnValue({ isDestroyed: () => true }) + expect( + validateHandler({ sender: trustedSender }, { browserPageId: 'page-1', webContentsId: 123 }) + ).toBe(false) + expect( + validateHandler( + { + sender: { + id: 92, + isDestroyed: () => false, + getType: () => 'webview', + getURL: () => 'https://example.com' + } as Electron.WebContents + }, + { browserPageId: 'page-1', webContentsId: 123 } + ) + ).toBe(false) + }) + + it('repairs only a live webview owned by the trusted renderer', () => { + registerBrowserHandlers() + const repairHandler = handleMock.mock.calls.find( + ([channel]) => channel === 'browser:repairGuestRegistration' + )?.[1] as ( + event: { sender: Electron.WebContents }, + args: { + browserPageId: string + workspaceId: string + worktreeId: string + webContentsId: number + } + ) => boolean + const trustedSender = { + id: 91, + isDestroyed: () => false, + getType: () => 'window', + getURL: () => 'file:///renderer/index.html' + } as Electron.WebContents + const guest = { + id: 123, + hostWebContents: trustedSender, + isDestroyed: () => false, + getType: () => 'webview' + } as Electron.WebContents + webContentsFromIdMock.mockReturnValue(guest) + const args = { + browserPageId: 'page-1', + workspaceId: 'workspace-1', + worktreeId: 'worktree-1', + webContentsId: 123 + } + + expect(repairHandler({ sender: trustedSender }, args)).toBe(true) + expect(attachGuestPoliciesMock).toHaveBeenCalledWith(guest) + expect(registerGuestMock).toHaveBeenCalledWith({ + ...args, + rendererWebContentsId: trustedSender.id + }) + + webContentsFromIdMock.mockReturnValue({ + ...guest, + hostWebContents: { id: 92 } + }) + expect(repairHandler({ sender: trustedSender }, args)).toBe(false) + expect(registerGuestMock).toHaveBeenCalledTimes(1) + }) + it('authorizes browser download cancellation through the owning renderer', () => { cancelDownloadMock.mockReturnValue(true) registerBrowserHandlers() diff --git a/src/main/ipc/browser.ts b/src/main/ipc/browser.ts index fb67b002234..504b4108948 100644 --- a/src/main/ipc/browser.ts +++ b/src/main/ipc/browser.ts @@ -87,6 +87,14 @@ function isLiveBrowserWebContentsId(webContentsId: number | null | undefined): b return Boolean(guest && !guest.isDestroyed()) } +type BrowserGuestRegistrationArgs = { + browserPageId: string + workspaceId: string + worktreeId: string + sessionProfileId?: string | null + webContentsId: number +} + function hasRegisteredTabForWorktree(worktreeId: string): boolean { for (const [browserPageId, webContentsId] of browserManager.getWebContentsIdByTabId()) { if ( @@ -197,6 +205,8 @@ export function registerBrowserHandlers(): void { // Why: a stale in-flight chain from a prior registration would block new operations forever. grabModeOperationByPageId.clear() ipcMain.removeHandler('browser:registerGuest') + ipcMain.removeHandler('browser:isGuestRegistered') + ipcMain.removeHandler('browser:repairGuestRegistration') ipcMain.removeHandler('browser:unregisterGuest') ipcMain.removeHandler('browser:openDevTools') ipcMain.removeHandler('browser:setViewportOverride') @@ -211,46 +221,84 @@ export function registerBrowserHandlers(): void { ipcMain.removeHandler('browser:activeTabChanged') ipcMain.removeHandler('browser:proceedCertificate') + const registerGuest = ( + event: Electron.IpcMainInvokeEvent, + args: BrowserGuestRegistrationArgs, + repairPolicies: boolean + ): boolean => { + if (!isTrustedBrowserRenderer(event.sender)) { + return false + } + if ( + !args || + typeof args.browserPageId !== 'string' || + typeof args.workspaceId !== 'string' || + typeof args.worktreeId !== 'string' || + typeof args.webContentsId !== 'number' + ) { + return false + } + if (repairPolicies) { + const guest = webContents.fromId(args.webContentsId) + if ( + !guest || + guest.isDestroyed() || + guest.getType() !== 'webview' || + guest.hostWebContents?.id !== event.sender.id + ) { + return false + } + browserManager.attachGuestPolicies(guest) + } + // Why: when Chromium swaps a guest's renderer process (navigation, + // crash recovery), the renderer re-registers the same browserPageId + // with a new webContentsId. The bridge must destroy the old session's + // proxy (its webContents is gone) and let the next command recreate it. + const previousWcId = browserManager.getGuestWebContentsId(args.browserPageId) + const registered = browserManager.registerGuest({ + ...args, + rendererWebContentsId: event.sender.id + }) + if (!registered) { + return false + } + if (agentBrowserBridgeRef && previousWcId !== null && previousWcId !== args.webContentsId) { + agentBrowserBridgeRef.onProcessSwap(args.browserPageId, args.webContentsId, previousWcId) + } + const pendingResolves = pendingTabRegistrations.get(args.browserPageId) + pendingTabRegistrations.delete(args.browserPageId) + resolvePendingRegistrations(pendingResolves) + const pendingWorktreeResolves = pendingWorktreeTabRegistrations.get(args.worktreeId) + pendingWorktreeTabRegistrations.delete(args.worktreeId) + resolvePendingRegistrations(pendingWorktreeResolves) + const pendingAnyResolves = new Set(pendingAnyTabRegistrations) + pendingAnyTabRegistrations.clear() + resolvePendingRegistrations(pendingAnyResolves) + return true + } + + ipcMain.handle('browser:registerGuest', (event, args: BrowserGuestRegistrationArgs) => + registerGuest(event, args, false) + ) + + ipcMain.handle('browser:repairGuestRegistration', (event, args: BrowserGuestRegistrationArgs) => + registerGuest(event, args, true) + ) + ipcMain.handle( - 'browser:registerGuest', - ( - event, - args: { - browserPageId: string - workspaceId: string - worktreeId: string - sessionProfileId?: string | null - webContentsId: number - } - ) => { - if (!isTrustedBrowserRenderer(event.sender)) { + 'browser:isGuestRegistered', + (event, args: { browserPageId?: unknown; webContentsId?: unknown }): boolean => { + if ( + !isTrustedBrowserRenderer(event.sender) || + typeof args?.browserPageId !== 'string' || + typeof args.webContentsId !== 'number' + ) { return false } - // Why: when Chromium swaps a guest's renderer process (navigation, - // crash recovery), the renderer re-registers the same browserPageId - // with a new webContentsId. The bridge must destroy the old session's - // proxy (its webContents is gone) and let the next command recreate it. - const previousWcId = browserManager.getGuestWebContentsId(args.browserPageId) - const registered = browserManager.registerGuest({ - ...args, - rendererWebContentsId: event.sender.id - }) - if (!registered) { - return false - } - if (agentBrowserBridgeRef && previousWcId !== null && previousWcId !== args.webContentsId) { - agentBrowserBridgeRef.onProcessSwap(args.browserPageId, args.webContentsId, previousWcId) - } - const pendingResolves = pendingTabRegistrations.get(args.browserPageId) - pendingTabRegistrations.delete(args.browserPageId) - resolvePendingRegistrations(pendingResolves) - const pendingWorktreeResolves = pendingWorktreeTabRegistrations.get(args.worktreeId) - pendingWorktreeTabRegistrations.delete(args.worktreeId) - resolvePendingRegistrations(pendingWorktreeResolves) - const pendingAnyResolves = new Set(pendingAnyTabRegistrations) - pendingAnyTabRegistrations.clear() - resolvePendingRegistrations(pendingAnyResolves) - return true + return ( + browserManager.getGuestWebContentsId(args.browserPageId) === args.webContentsId && + isLiveBrowserWebContentsId(args.webContentsId) + ) } ) diff --git a/src/main/ipc/mobile.test.ts b/src/main/ipc/mobile.test.ts index be6f07ff2c4..54458541f92 100644 --- a/src/main/ipc/mobile.test.ts +++ b/src/main/ipc/mobile.test.ts @@ -22,6 +22,7 @@ vi.mock('os', () => ({ })) import { registerMobileHandlers } from './mobile' +import { NETWORK_EXPOSURE_FAILED_GUIDANCE } from '../runtime/network-exposure-guidance' describe('registerMobileHandlers', () => { const handlers = new Map unknown>() @@ -285,7 +286,8 @@ describe('registerMobileHandlers', () => { endpoint: 'ws://100.64.1.20:6768', deviceId: 'runtime-1' }) - const rpcServer = { createPairingOffer } + const ensureNetworkExposure = vi.fn().mockResolvedValue(undefined) + const rpcServer = { createPairingOffer, ensureNetworkExposure } registerMobileHandlers(rpcServer as never) @@ -308,6 +310,35 @@ describe('registerMobileHandlers', () => { name: expect.stringMatching(/^Runtime /), scope: 'runtime' }) + // Why: STA-2370 — generating a runtime offer must widen the listener BEFORE advertising its endpoint, + // or a client could read the URL and connect before the LAN bind exists. Assert call ORDER, not just + // that the widen ran, so a regression that widens after minting the offer is caught. + expect(ensureNetworkExposure).toHaveBeenCalled() + expect(ensureNetworkExposure.mock.invocationCallOrder[0]).toBeLessThan( + createPairingOffer.mock.invocationCallOrder[0] + ) + }) + + it('reports the runtime pairing url unavailable and mints no offer when the widen fails', async () => { + const createPairingOffer = vi.fn() + // Why: STA-2370 — a failed widen leaves the listener on loopback, so the handler must NOT advertise a + // LAN endpoint. A regression that swallows the rejection and mints an offer against a loopback-only + // listener is caught here: createPairingOffer must never run. + const ensureNetworkExposure = vi.fn().mockRejectedValue(new Error('bind refused')) + const rpcServer = { createPairingOffer, ensureNetworkExposure } + + registerMobileHandlers(rpcServer as never) + + await expect( + handlers.get('mobile:getRuntimePairingUrl')?.(null, { address: '100.64.1.20' }) + ).resolves.toEqual({ + available: false, + reason: 'network_exposure_failed', + guidance: NETWORK_EXPOSURE_FAILED_GUIDANCE + }) + + expect(ensureNetworkExposure).toHaveBeenCalled() + expect(createPairingOffer).not.toHaveBeenCalled() }) it('lists runtime access grants including unused generated links', () => { diff --git a/src/main/ipc/mobile.ts b/src/main/ipc/mobile.ts index 1e9e4d99a6d..ff4c5c6d3ec 100644 --- a/src/main/ipc/mobile.ts +++ b/src/main/ipc/mobile.ts @@ -4,6 +4,7 @@ import type { RuntimeAccessGrant } from '../../shared/runtime-access-grants' import type { MobilePairingConnectionMode } from '../../shared/mobile-pairing-connection-mode' import { isTailnetIPv4Address } from '../../shared/tailnet-address' import type { DeviceEntry } from '../runtime/device-registry' +import { NETWORK_EXPOSURE_FAILED_GUIDANCE } from '../runtime/network-exposure-guidance' import type { OrcaRuntimeRpcServer } from '../runtime/runtime-rpc' import type { RelayBrokerStatus } from '../runtime/relay/relay-session-broker' import { encodeMobilePairingQr, type MobilePairingQrResult } from '../runtime/mobile-pairing-qr' @@ -180,6 +181,25 @@ export function registerMobileHandlers( return { available: false as const } } + // Why: STA-2370 — generating a runtime pairing offer is the user's explicit opt-in to remote + // reach, so widen the loopback listener before advertising its LAN endpoint. If the widen fails the + // listener stays on loopback, so report unavailable rather than advertise a dead LAN endpoint. + try { + await rpcServer.ensureNetworkExposure() + } catch (error) { + console.error( + '[mobile] Network exposure failed while creating a runtime pairing offer:', + error + ) + // Why: STA-2370 — carry the specific reason/guidance to the renderer (mirrors the mobile-QR path) so + // a widen failure is distinguishable from a missing address, not collapsed into a bare unavailable. + return { + available: false as const, + reason: 'network_exposure_failed' as const, + guidance: NETWORK_EXPOSURE_FAILED_GUIDANCE + } + } + // Why: web/desktop runtime clients need full runtime access, not the // mobile allowlist used by phone QR pairing. const offer = rpcServer.createPairingOffer({ diff --git a/src/main/ipc/pty-management.test.ts b/src/main/ipc/pty-management.test.ts index 4e30669fb9e..1586c566ffb 100644 --- a/src/main/ipc/pty-management.test.ts +++ b/src/main/ipc/pty-management.test.ts @@ -44,11 +44,18 @@ vi.mock('../daemon/daemon-pty-router', () => { // subscribes to adapter events, so keep only the accessors pty-management uses. vi.mock('../daemon/degraded-daemon-pty-provider', () => { class DegradedDaemonPtyProvider { - readonly isDegraded = true private allAdapters: unknown[] + private routesFreshToFallback = true constructor(opts: { current: unknown; legacy: unknown[] }) { this.allAdapters = [opts.current, ...opts.legacy] } + get routesFreshSpawnsToLocalProvider(): true | undefined { + return this.routesFreshToFallback ? true : undefined + } + async recoverFreshSpawnRouting(): Promise { + this.routesFreshToFallback = false + return true + } getAllAdapters() { return this.allAdapters } @@ -177,6 +184,19 @@ describe('pty:management IPC handlers', () => { expect(result.sessions.map((s) => s.sessionId)).toEqual(['preserved-1']) }) + it('clears degraded mode after durable fresh-spawn routing recovers', async () => { + const current = makeAdapter(5, [makeSession('preserved-1')]) + const provider = await makeDegradedProvider(current) + const { registerDaemonManagementHandlers } = await importFresh() + getDaemonProviderMock.mockReturnValue(provider) + registerDaemonManagementHandlers() + const handler = buildHandlerMap()['pty:management:listSessions'] + + await expect(handler({})).resolves.toMatchObject({ degraded: true }) + await provider.recoverFreshSpawnRouting() + await expect(handler({})).resolves.toMatchObject({ degraded: false }) + }) + it('returns empty list when no daemon provider is installed', async () => { getDaemonProviderMock.mockReturnValue(null) diff --git a/src/main/ipc/pty-management.ts b/src/main/ipc/pty-management.ts index f188fb3aad5..6a3f455aeea 100644 --- a/src/main/ipc/pty-management.ts +++ b/src/main/ipc/pty-management.ts @@ -26,7 +26,11 @@ function getDaemonAdapters(): DaemonPtyAdapter[] { // Why: surface degraded mode (daemon alive but cannot spawn fresh PTYs) so the UI can warn new terminals lack persistence. function isDaemonDegraded(): boolean { - return getDaemonProvider() instanceof DegradedDaemonPtyProvider + const provider = getDaemonProvider() + return ( + provider instanceof DegradedDaemonPtyProvider && + provider.routesFreshSpawnsToLocalProvider === true + ) } async function collectSessions(adapters: DaemonPtyAdapter[]): Promise { diff --git a/src/main/ipc/pty.test.ts b/src/main/ipc/pty.test.ts index 0d6d50cd050..257250a9858 100644 --- a/src/main/ipc/pty.test.ts +++ b/src/main/ipc/pty.test.ts @@ -303,9 +303,7 @@ describe('registerPtyHandlers', () => { webContents: { on: vi.fn(), send: vi.fn(), - removeListener: vi.fn(), - // Why: the did-start-loading reset handler filters to main-frame loads; default true so lifecycle-reset tests reset (a subframe case overrides false). - isLoadingMainFrame: vi.fn(() => true) + removeListener: vi.fn() } } const mainWindowIpcEvent = { sender: mainWindow.webContents } @@ -764,6 +762,7 @@ describe('registerPtyHandlers', () => { setPtyController: vi.fn((next) => { controller = next }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term_recovered'), registerPreAllocatedHandleForPty: vi.fn(), registerPty: vi.fn() } @@ -1033,6 +1032,85 @@ describe('registerPtyHandlers', () => { clearProviderPtyState('pty-local-claim') }) + it.each(['runtime controller', 'renderer IPC'] as const)( + 'recovers degraded fresh-spawn routing before %s chooses daemon host semantics', + async (entryPoint) => { + let degraded = true + const daemonSpawn = vi.fn(async (options: { sessionId?: string }) => ({ + id: options.sessionId ?? 'unexpected-fallback-id' + })) + const provider = createAgentClaimProvider({ spawn: daemonSpawn }) + const recoverFreshSpawnRouting = vi.fn(async () => { + degraded = false + return true + }) + Object.defineProperties(provider, { + routesFreshSpawnsToLocalProvider: { + configurable: true, + get: () => (degraded ? true : undefined) + }, + recoverFreshSpawnRouting: { value: recoverFreshSpawnRouting } + }) + setLocalPtyProvider(provider as never) + const controller = registerAgentClaimController() + const worktreeId = 'repo::/tmp/recovered-daemon-routing' + const spawnArgs = { + cols: 80, + rows: 24, + cwd: '/tmp/recovered-daemon-routing', + worktreeId + } + + await (entryPoint === 'runtime controller' + ? controller.spawn(spawnArgs) + : handlers.get('pty:spawn')!(null, spawnArgs)) + + expect(recoverFreshSpawnRouting).toHaveBeenCalledOnce() + expect(daemonSpawn).toHaveBeenCalledOnce() + expect(daemonSpawn.mock.calls[0]?.[0].sessionId).toMatch( + new RegExp(`^${worktreeId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}@@`) + ) + expect(recoverFreshSpawnRouting.mock.invocationCallOrder[0]).toBeLessThan( + daemonSpawn.mock.invocationCallOrder[0] ?? Number.POSITIVE_INFINITY + ) + } + ) + + it('recovers degraded routing for a fresh runtime session with a stable id', async () => { + let degraded = true + const daemonSpawn = vi.fn(async (options: { sessionId?: string; isNewSession?: boolean }) => ({ + id: options.sessionId ?? 'unexpected-fallback-id' + })) + const provider = createAgentClaimProvider({ spawn: daemonSpawn }) + const recoverFreshSpawnRouting = vi.fn(async () => { + degraded = false + return true + }) + Object.defineProperties(provider, { + routesFreshSpawnsToLocalProvider: { + configurable: true, + get: () => (degraded ? true : undefined) + }, + recoverFreshSpawnRouting: { value: recoverFreshSpawnRouting } + }) + setLocalPtyProvider(provider as never) + const controller = registerAgentClaimController() + + await controller.spawn({ + cols: 80, + rows: 24, + cwd: '/tmp/recovered-stable-session', + worktreeId: 'repo::/tmp/recovered-stable-session', + sessionId: 'serve-stable-session', + isNewSession: true + }) + + expect(recoverFreshSpawnRouting).toHaveBeenCalledOnce() + expect(daemonSpawn).toHaveBeenCalledWith( + expect.objectContaining({ sessionId: 'serve-stable-session', isNewSession: true }) + ) + }) + it('adopts a daemon owner recovered from provider listing before claimed ensure', async () => { const owner: AgentSessionOwnerBinding = { claim: recoveredAgentClaim, @@ -1543,6 +1621,11 @@ describe('registerPtyHandlers', () => { return listenerCall[1] as (...args: unknown[]) => void } + function getMainFrameNavigationListener(): () => void { + const listener = getMainWindowWebContentsListener('did-start-navigation') + return () => listener({ isMainFrame: true, isSameDocument: false }) + } + function getPtyResizeListener(): ( event: unknown, args: { id: string; cols: number; rows: number } @@ -6671,6 +6754,64 @@ describe('registerPtyHandlers', () => { ]) }) + it('waits for local provider startup before resolving snapshot capability', async () => { + const barrier = makeDeferred() + const awaitLocalPtyProviderStartup = vi.fn(() => barrier.promise) + registerPtyHandlers( + mainWindow as never, + undefined, + undefined, + undefined, + undefined, + undefined, + { awaitLocalPtyProviderStartup } + ) + const pending = Promise.resolve( + handlers.get('pty:getAuthoritativeBufferSnapshotCapabilities')?.(null, { + ids: ['restored-local-pty'] + }) + ) + let settled = false + void pending.then(() => { + settled = true + }) + + await Promise.resolve() + expect(awaitLocalPtyProviderStartup).toHaveBeenCalledTimes(1) + expect(settled).toBe(false) + + installDaemonTestProvider({ canProvideAuthoritativeBufferSnapshot: () => true }) + barrier.resolve() + + await expect(pending).resolves.toEqual([{ id: 'restored-local-pty', authoritative: true }]) + }) + + it('does not gate remote snapshot capability on local provider startup', async () => { + const awaitLocalPtyProviderStartup = vi.fn(() => new Promise(() => {})) + registerSshPtyProvider('ssh-1', { + canProvideAuthoritativeBufferSnapshot: () => false + } as never) + registerPtyHandlers( + mainWindow as never, + undefined, + undefined, + undefined, + undefined, + undefined, + { awaitLocalPtyProviderStartup } + ) + + const result = await handlers.get('pty:getAuthoritativeBufferSnapshotCapabilities')?.(null, { + ids: ['remote:environment@@pty-1', 'ssh:ssh-1@@pty-2'] + }) + + expect(awaitLocalPtyProviderStartup).not.toHaveBeenCalled() + expect(result).toEqual([ + { id: 'remote:environment@@pty-1', authoritative: false }, + { id: 'ssh:ssh-1@@pty-2', authoritative: false } + ]) + }) + it('answers false, not null, for a resolved provider with no snapshot capability', async () => { // Null is never cached, so missing optional methods must resolve false. registerPtyHandlers(mainWindow as never) @@ -8177,7 +8318,7 @@ describe('registerPtyHandlers', () => { resolveSpawn({ id: 'pty-shared' }) await expect(Promise.all([runtimeSpawn, rendererSpawn])).resolves.toEqual([ { id: 'pty-shared' }, - { id: 'pty-shared' } + { id: 'pty-shared', isReattach: true } ]) expect(providerSpawn).toHaveBeenCalledTimes(1) expect(store.persistPtyBinding).toHaveBeenCalledWith({ @@ -8189,6 +8330,83 @@ describe('registerPtyHandlers', () => { }) }) + it('waits for an early runtime pane claim before renderer creation', async () => { + type RuntimeSpawnController = { + claimStablePaneCreate(args: { + worktreeId: string + connectionId: string | null + tabId: string + leafId: string + }): () => void + } + const providerSpawn = vi.fn(async () => ({ id: 'pty-after-runtime-claim' })) + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + let controller: RuntimeSpawnController | null = null + const runtime = { + setPtyController: vi.fn((value) => { + controller = value + }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term_claimed'), + registerPreAllocatedHandleForPty: vi.fn(), + registerPty: vi.fn(), + onPtySpawned: vi.fn(), + onPtyExit: vi.fn(), + onPtyData: vi.fn() + } + registerPtyHandlers(mainWindow as never, runtime as never) + const tabId = 'tab-early-runtime-claim' + const leafId = '44444444-4444-4444-8444-444444444444' + const worktreeId = 'repo-1::/tmp/early-runtime-claim' + const releaseClaim = (controller as unknown as RuntimeSpawnController).claimStablePaneCreate({ + worktreeId, + connectionId: null, + tabId, + leafId + }) + + const mounted = handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd: '/tmp/early-runtime-claim', + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: makePaneKey(tabId, leafId), + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + } + }) + await new Promise((resolve) => setImmediate(resolve)) + expect(providerSpawn).not.toHaveBeenCalled() + + releaseClaim() + await expect(mounted).resolves.toMatchObject({ id: 'pty-after-runtime-claim' }) + expect(providerSpawn).toHaveBeenCalledOnce() + }) + it('reuses renderer spawn when runtime materialization starts for the same pane', async () => { type RuntimeSpawnController = { spawn(args: { @@ -8235,6 +8453,7 @@ describe('registerPtyHandlers', () => { const store = { persistPtyBinding: vi.fn() } + let registeredPane: { ptyId: string; tabId: string; leafId: string } | null = null let controller: RuntimeSpawnController | null = null const runtime = { setPtyController: vi.fn((value) => { @@ -8243,7 +8462,30 @@ describe('registerPtyHandlers', () => { createPreAllocatedTerminalHandle: vi.fn(() => 'term_trusted'), preAllocateHandleForPty: vi.fn(() => 'term_trusted'), registerPreAllocatedHandleForPty: vi.fn(), - registerPty: vi.fn(), + registerPty: vi.fn( + ( + ptyId: string, + _worktreeId: string, + _connectionId: string | null, + binding?: { tabId: string; leafId: string } + ) => { + if (binding) { + registeredPane = { ptyId, ...binding } + } + } + ), + resolveTerminalPane: vi.fn(() => { + if (!registeredPane) { + throw new Error('terminal_not_found') + } + return { + handle: 'term_trusted', + tabId: registeredPane.tabId, + leafId: registeredPane.leafId, + ptyId: registeredPane.ptyId, + worktreeId: 'repo-1::/tmp' + } + }), onPtySpawned: vi.fn(), onPtyExit: vi.fn(), onPtyData: vi.fn() @@ -8285,14 +8527,18 @@ describe('registerPtyHandlers', () => { env: { ORCA_PANE_KEY: paneKey }, persistHostSessionBinding: true }) - await Promise.resolve() - - expect(providerSpawn).toHaveBeenCalledTimes(1) + await vi.waitFor(() => expect(providerSpawn).toHaveBeenCalledTimes(1)) resolveSpawn({ id: 'pty-renderer' }) - await expect(Promise.all([rendererSpawn, runtimeSpawn])).resolves.toEqual([ - { id: 'pty-renderer' }, - { id: 'pty-renderer' } - ]) + const [rendererResult, runtimeResult] = await Promise.all([rendererSpawn, runtimeSpawn]) + expect(rendererResult).toEqual({ id: 'pty-renderer' }) + expect(runtimeResult).toEqual({ + id: 'pty-renderer', + stablePaneOwner: { + handle: 'term_trusted', + tabId: 'tab-race', + leafId + } + }) expect(providerSpawn).toHaveBeenCalledTimes(1) expect(store.persistPtyBinding).toHaveBeenCalledWith({ worktreeId: 'repo-1::/tmp', @@ -8303,6 +8549,825 @@ describe('registerPtyHandlers', () => { }) }) + it.each([ + { + label: 'git worktree', + worktreeId: 'repo-1::/tmp/live-owner', + cwd: '/tmp/live-owner' + }, + { + label: 'folder workspace', + worktreeId: 'folder:live-owner', + cwd: '/tmp' + } + ])( + 'adopts a completed runtime-owned pane before replacement launch preflight ($label)', + async ({ worktreeId, cwd }) => { + type StableAdoption = { + result: { id: string; incarnationId?: string; isReattach?: boolean } + owner: { handle?: string; tabId: string; leafId: string; ptyId: string } + materialized?: true + } | null + type RuntimeSpawnController = { + adoptStablePane(args: { + cols: number + rows: number + worktreeId: string + tabId: string + leafId: string + cwd: string + }): Promise + spawn(args: Record): Promise<{ + id: string + incarnationId?: string + stablePaneOwner?: { handle: string; tabId: string; leafId: string } + }> + } + const tabId = 'tab-live-owner' + const leafId = '66666666-6666-4666-8666-666666666666' + const paneKey = makePaneKey(tabId, leafId) + let ownerPublished = false + let releaseAttach!: () => void + let attachBarrier: Promise + const resetAttachBarrier = (): void => { + attachBarrier = new Promise((resolve) => { + releaseAttach = resolve + }) + } + resetAttachBarrier() + const supportsAgentSessionClaims = vi.fn(async () => false) + const supportsAgentSessionCreateOperations = vi.fn(async () => false) + const providerSpawn = vi.fn( + async (options: { attachOnly?: boolean; command?: string; sessionId?: string }) => { + if (options.attachOnly) { + await attachBarrier + return { + id: 'pty-live-owner', + incarnationId: 'inc-live-owner', + isReattach: true, + snapshot: 'original-live-output', + providerSequence: { value: 20, generation: 'continued' as const } + } + } + return { id: 'pty-live-owner', incarnationId: 'inc-live-owner' } + } + ) + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + supportsAgentSessionClaims, + supportsAgentSessionCreateOperations, + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + const folderWorkspace = { + id: 'live-owner', + folderPath: cwd, + projectGroupId: 'folder-group' + } + const store = { + persistPtyBinding: vi.fn(), + getFolderWorkspace: vi.fn(() => folderWorkspace), + getFolderWorkspaces: vi.fn(() => [folderWorkspace]), + getProjectGroups: vi.fn(() => []), + getRepos: vi.fn(() => []) + } + const prepareClaudeAuth = vi.fn(() => { + throw new Error('replacement auth preflight must not run') + }) + let controller: RuntimeSpawnController | null = null + const runtime = { + setPtyController: vi.fn((value) => { + controller = value + }), + resolveTerminalPane: vi.fn(() => { + if (!ownerPublished) { + throw new Error('terminal_not_found') + } + return { + handle: 'term-live-owner', + tabId, + leafId, + ptyId: 'pty-live-owner', + worktreeId + } + }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term-provisional-renderer'), + preAllocateHandleForPty: vi.fn(() => 'term-live-owner'), + registerPreAllocatedHandleForPty: vi.fn(), + beginPtyRegistration: vi.fn(), + cancelPendingPtyRegistration: vi.fn(), + assertPtyRegistrationAllowed: vi.fn(), + registerPty: vi.fn(), + noteTerminalSpawnCommand: vi.fn(), + seedHeadlessTerminal: vi.fn(), + onPtySpawned: vi.fn(), + onPtyExit: vi.fn(), + onPtyData: vi.fn() + } + + registerPtyHandlers( + mainWindow as never, + runtime as never, + undefined, + undefined, + prepareClaudeAuth, + store as never + ) + const spawnController = controller as unknown as RuntimeSpawnController + await spawnController.spawn({ + cols: 80, + rows: 24, + cwd, + command: 'node original-agent-fixture.mjs', + worktreeId, + preAllocatedHandle: 'term-live-owner', + tabId, + leafId, + env: { ORCA_PANE_KEY: paneKey }, + persistHostSessionBinding: true + }) + ownerPublished = true + runtime.createPreAllocatedTerminalHandle.mockClear() + runtime.registerPreAllocatedHandleForPty.mockClear() + runtime.noteTerminalSpawnCommand.mockClear() + trackMock.mockClear() + store.persistPtyBinding.mockClear() + mainWindow.webContents.send.mockClear() + + const mountArgs = { + cols: 120, + rows: 40, + cwd, + command: 'claude --resume provider-session', + launchAgent: 'claude', + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + }, + telemetry: { + agent_kind: 'codex', + launch_source: 'new_workspace_composer', + request_kind: 'new' + } + } + const firstMount = handlers.get('pty:spawn')!(null, mountArgs) + await vi.waitFor(() => expect(providerSpawn).toHaveBeenCalledTimes(2)) + const secondMount = handlers.get('pty:spawn')!(null, mountArgs) + releaseAttach() + const [mounted, concurrentMounted] = await Promise.all([firstMount, secondMount]) + + expect(mounted).toMatchObject({ + id: 'pty-live-owner', + incarnationId: 'inc-live-owner', + isReattach: true, + snapshot: 'original-live-output' + }) + expect(concurrentMounted).toEqual(mounted) + expect(providerSpawn).toHaveBeenCalledTimes(2) + expect(providerSpawn.mock.calls[1]?.[0]).toMatchObject({ + attachOnly: true, + sessionId: 'pty-live-owner' + }) + expect(providerSpawn.mock.calls[1]?.[0].command).toBeUndefined() + expect(runtime.createPreAllocatedTerminalHandle).not.toHaveBeenCalled() + expect(prepareClaudeAuth).not.toHaveBeenCalled() + expect(runtime.registerPreAllocatedHandleForPty).not.toHaveBeenCalled() + expect(runtime.noteTerminalSpawnCommand).not.toHaveBeenCalled() + expect(trackMock).not.toHaveBeenCalledWith('agent_started', expect.anything()) + expect(runtime.onPtyExit).not.toHaveBeenCalled() + expect(getPtyIdForPaneKey(paneKey)).toBe('pty-live-owner') + + resetAttachBarrier() + store.persistPtyBinding.mockClear() + mainWindow.webContents.send.mockClear() + const adoptionArgs = { cols: 120, rows: 40, cwd, worktreeId, tabId, leafId } + let runtimeSecondAdoption: Promise | null = null + runtime.beginPtyRegistration.mockImplementation(() => { + runtimeSecondAdoption ??= spawnController.adoptStablePane(adoptionArgs) + }) + const rendererFirstMount = handlers.get('pty:spawn')!(null, mountArgs) + await vi.waitFor(() => expect(providerSpawn).toHaveBeenCalledTimes(3)) + releaseAttach() + await vi.waitFor(() => expect(runtimeSecondAdoption).not.toBeNull()) + const pendingRuntimeAdoption = runtimeSecondAdoption + if (!pendingRuntimeAdoption) { + throw new Error('runtime adoption did not enter during renderer publication') + } + const adoptedOwner = await pendingRuntimeAdoption + expect(adoptedOwner).toMatchObject({ materialized: true }) + + const claimedResultPromise = spawnController.spawn({ + cols: 120, + rows: 40, + cwd, + command: 'codex resume should-not-run', + worktreeId, + preAllocatedHandle: 'term-live-owner', + tabId, + leafId, + env: { ORCA_PANE_KEY: paneKey }, + persistHostSessionBinding: true, + adoptedStablePane: adoptedOwner, + agentSessionEnsure: { + claim: { + ...recoveredAgentClaim, + identityDigest: 'ccccccccccccccccccccccccccccccccccccccccccc' + }, + surface: { worktreeId, tabId, leafId, terminalHandle: 'term-live-owner' } + }, + agentSessionCreateOperationId: 'create-op-must-not-run' + }) + const [rendererFirstResult, claimedResult] = await Promise.all([ + rendererFirstMount, + claimedResultPromise + ]) + expect(rendererFirstResult).toMatchObject({ + id: 'pty-live-owner', + incarnationId: 'inc-live-owner', + isReattach: true + }) + expect(claimedResult).toMatchObject({ + id: 'pty-live-owner', + stablePaneOwner: { handle: 'term-live-owner', tabId, leafId } + }) + expect(providerSpawn).toHaveBeenCalledTimes(3) + expect(supportsAgentSessionClaims).not.toHaveBeenCalled() + expect(supportsAgentSessionCreateOperations).not.toHaveBeenCalled() + expect(store.persistPtyBinding).toHaveBeenCalledOnce() + expect( + mainWindow.webContents.send.mock.calls.filter(([channel]) => channel === 'pty:spawned') + ).toHaveLength(1) + } + ) + + it('adopts an exact persisted owner when the runtime projection is missing', async () => { + const tabId = 'tab-persisted-owner' + const leafId = '88888888-8888-4888-8888-888888888888' + const paneKey = makePaneKey(tabId, leafId) + const worktreeId = 'repo-1::/tmp/persisted-owner' + const providerSpawn = vi.fn(async (options: { attachOnly?: boolean; sessionId?: string }) => ({ + id: options.sessionId ?? 'unexpected-fresh-id', + incarnationId: 'inc-persisted-owner', + isReattach: options.attachOnly === true, + snapshot: 'persisted-owner-output' + })) + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + const runtime = { + setPtyController: vi.fn(), + resolveTerminalPane: vi.fn(() => { + throw new Error('terminal_not_found') + }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term-rebuilt-owner'), + registerPreAllocatedHandleForPty: vi.fn(), + beginPtyRegistration: vi.fn(), + cancelPendingPtyRegistration: vi.fn(), + assertPtyRegistrationAllowed: vi.fn(), + registerPty: vi.fn(), + noteTerminalSpawnCommand: vi.fn(), + seedHeadlessTerminal: vi.fn(), + onPtyExit: vi.fn() + } + const store = { + getWorkspaceSession: vi.fn(() => ({ + tabsByWorktree: { + [worktreeId]: [{ id: tabId, worktreeId, ptyId: 'pty-persisted-owner' }] + }, + terminalLayoutsByTabId: { + [tabId]: { ptyIdsByLeafId: { [leafId]: 'pty-persisted-owner' } } + }, + terminalPtyIncarnationsByPaneKey: { + [paneKey]: 'inc-persisted-owner' + } + })), + persistPtyBinding: vi.fn() + } + + registerPtyHandlers( + mainWindow as never, + runtime as never, + undefined, + undefined, + undefined, + store as never + ) + const mounted = await handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd: '/tmp/persisted-owner', + command: 'codex resume provider-session', + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + } + }) + + expect(mounted).toMatchObject({ + id: 'pty-persisted-owner', + incarnationId: 'inc-persisted-owner', + isReattach: true + }) + expect(providerSpawn).toHaveBeenCalledOnce() + expect(providerSpawn).toHaveBeenCalledWith( + expect.objectContaining({ + attachOnly: true, + sessionId: 'pty-persisted-owner', + command: undefined + }) + ) + expect(runtime.registerPreAllocatedHandleForPty).toHaveBeenCalledWith( + 'pty-persisted-owner', + 'term-rebuilt-owner' + ) + expect(runtime.noteTerminalSpawnCommand).not.toHaveBeenCalled() + expect(store.persistPtyBinding).toHaveBeenCalledOnce() + expect( + mainWindow.webContents.send.mock.calls.filter(([channel]) => channel === 'pty:spawned') + ).toHaveLength(1) + expect(runtime.onPtyExit).not.toHaveBeenCalled() + }) + + it.each([ + { + label: 'git worktree', + worktreeId: 'repo-1::/tmp/dead-persisted-owner', + cwd: '/tmp/dead-persisted-owner', + folderMissing: false + }, + { + label: 'missing folder workspace', + worktreeId: 'folder:dead-persisted-owner', + cwd: '/tmp/missing-dead-persisted-owner', + folderMissing: true + } + ])( + 'retires a persistence-only dead owner before fresh recovery ($label)', + async ({ worktreeId, cwd, folderMissing }) => { + const tabId = 'tab-dead-persisted-owner' + const leafId = '12121212-1212-4212-8212-121212121212' + const paneKey = makePaneKey(tabId, leafId) + const providerSpawn = vi.fn( + async (options: { attachOnly?: boolean; command?: string; sessionId?: string }) => { + if (options.attachOnly) { + throw new Error('Session not found: pty-dead-persisted-owner') + } + return { id: 'pty-fresh-recovery', incarnationId: 'inc-fresh-recovery' } + } + ) + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + let session = { + tabsByWorktree: { + [worktreeId]: [{ id: tabId, worktreeId, ptyId: 'pty-dead-persisted-owner' }] + }, + terminalLayoutsByTabId: { + [tabId]: { + root: { type: 'leaf' as const, leafId }, + activeLeafId: leafId, + expandedLeafId: null, + ptyIdsByLeafId: { [leafId]: 'pty-dead-persisted-owner' } + } + }, + terminalPtyIncarnationsByPaneKey: { [paneKey]: 'inc-dead-persisted-owner' } + } + const store = { + getWorkspaceSession: vi.fn(() => session), + setWorkspaceSession: vi.fn((next) => { + session = next + }), + flushOrThrow: vi.fn(), + persistPtyBinding: vi.fn(), + getFolderWorkspace: vi.fn(() => ({ + id: 'dead-persisted-owner', + folderPath: cwd, + projectGroupId: 'folder-group' + })), + getFolderWorkspaces: vi.fn(() => [ + { + id: 'dead-persisted-owner', + folderPath: cwd, + projectGroupId: 'folder-group' + } + ]), + getProjectGroups: vi.fn(() => []), + getRepos: vi.fn(() => []) + } + const runtime = { + setPtyController: vi.fn(), + resolveTerminalPane: vi.fn(() => { + throw new Error('terminal_not_found') + }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term-fresh-recovery'), + preAllocateHandleForPty: vi.fn(() => 'term-fresh-recovery'), + registerPreAllocatedHandleForPty: vi.fn(), + beginPtyRegistration: vi.fn(), + cancelPendingPtyRegistration: vi.fn(), + assertPtyRegistrationAllowed: vi.fn(), + registerPty: vi.fn(), + noteTerminalSpawnCommand: vi.fn(), + seedHeadlessTerminal: vi.fn(), + onPtySpawned: vi.fn(), + onPtyExit: vi.fn(), + onPtyData: vi.fn() + } + + registerPtyHandlers( + mainWindow as never, + runtime as never, + undefined, + undefined, + undefined, + store as never + ) + if (folderMissing) { + statSyncMock.mockImplementation(() => { + throw Object.assign(new Error('missing folder'), { code: 'ENOENT' }) + }) + } + const mountedPromise = handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd, + command: 'codex resume exact-dead-provider-session', + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + } + }) + + if (folderMissing) { + await expect(mountedPromise).rejects.toThrow(`folder_workspace_path_missing:${cwd}`) + expect(providerSpawn).toHaveBeenCalledOnce() + expect(providerSpawn.mock.calls[0]?.[0]).toMatchObject({ + attachOnly: true, + sessionId: 'pty-dead-persisted-owner', + command: undefined + }) + expect(store.setWorkspaceSession).toHaveBeenCalledOnce() + expect(runtime.onPtyExit).toHaveBeenCalledWith( + 'pty-dead-persisted-owner', + 0, + 'inc-dead-persisted-owner' + ) + return + } + const mounted = await mountedPromise + + expect(mounted).toMatchObject({ + id: 'pty-fresh-recovery', + incarnationId: 'inc-fresh-recovery' + }) + expect(providerSpawn).toHaveBeenCalledTimes(2) + expect(providerSpawn.mock.calls[0]?.[0]).toMatchObject({ + attachOnly: true, + sessionId: 'pty-dead-persisted-owner', + command: undefined + }) + expect(providerSpawn.mock.calls[1]?.[0]).toMatchObject({ + command: 'codex resume exact-dead-provider-session' + }) + expect(store.setWorkspaceSession).toHaveBeenCalledOnce() + expect(store.flushOrThrow).toHaveBeenCalledOnce() + expect(runtime.onPtyExit).toHaveBeenCalledWith( + 'pty-dead-persisted-owner', + 0, + 'inc-dead-persisted-owner' + ) + } + ) + + it('retires a dead owner from the exact SSH host session before fresh recovery', async () => { + const connectionId = 'ssh-dead-stable-pane' + const hostId = `ssh:${connectionId}` + const tabId = 'tab-dead-ssh-owner' + const leafId = '34343434-3434-4434-8434-343434343434' + const paneKey = makePaneKey(tabId, leafId) + const worktreeId = 'repo-ssh::/remote/dead-stable-pane' + const deadPtyId = `ssh:${connectionId}@@dead-relay-pty` + const freshPtyId = `ssh:${connectionId}@@fresh-relay-pty` + const remoteSpawn = vi.fn(async (options: { attachOnly?: boolean; command?: string }) => { + if (options.attachOnly) { + throw new Error('PTY "dead-relay-pty" not found') + } + return { id: freshPtyId, incarnationId: 'inc-fresh-ssh-owner' } + }) + registerSshPtyProvider(connectionId, { + spawn: remoteSpawn, + write: vi.fn(), + resize: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + let session = { + tabsByWorktree: { + [worktreeId]: [{ id: tabId, worktreeId, ptyId: deadPtyId }] + }, + terminalLayoutsByTabId: { + [tabId]: { + root: { type: 'leaf' as const, leafId }, + activeLeafId: leafId, + expandedLeafId: null, + ptyIdsByLeafId: { [leafId]: deadPtyId } + } + }, + terminalPtyIncarnationsByPaneKey: { [paneKey]: 'inc-dead-ssh-owner' } + } + const store = { + getWorkspaceSession: vi.fn((requestedHostId?: string) => { + expect(requestedHostId).toBe(hostId) + return session + }), + setWorkspaceSession: vi.fn((next, requestedHostId?: string) => { + expect(requestedHostId).toBe(hostId) + session = next + }), + flushOrThrow: vi.fn(), + persistPtyBinding: vi.fn(), + upsertSshRemotePtyLease: vi.fn(), + removeSshRemotePtyLease: vi.fn(), + markSshRemotePtyLease: vi.fn() + } + const runtime = { + setPtyController: vi.fn(), + resolveTerminalPane: vi.fn(() => { + throw new Error('terminal_not_found') + }), + createPreAllocatedTerminalHandle: vi.fn(() => 'term-fresh-ssh-owner'), + registerPreAllocatedHandleForPty: vi.fn(), + beginPtyRegistration: vi.fn(), + cancelPendingPtyRegistration: vi.fn(), + assertPtyRegistrationAllowed: vi.fn(), + registerPty: vi.fn(), + noteTerminalSpawnCommand: vi.fn(), + seedHeadlessTerminal: vi.fn(), + getDriver: vi.fn(() => ({ kind: 'host' })), + onPtySpawned: vi.fn(), + onPtyExit: vi.fn(), + onPtyData: vi.fn() + } + + try { + registerPtyHandlers( + mainWindow as never, + runtime as never, + undefined, + undefined, + undefined, + store as never + ) + const mounted = await handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd: '/remote/dead-stable-pane', + command: 'codex resume exact-dead-ssh-provider-session', + connectionId, + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + } + }) + + expect(mounted).toMatchObject({ id: freshPtyId, incarnationId: 'inc-fresh-ssh-owner' }) + expect(remoteSpawn).toHaveBeenCalledTimes(2) + expect(remoteSpawn.mock.calls[0]?.[0]).toMatchObject({ + attachOnly: true, + sessionId: deadPtyId, + command: undefined + }) + expect(remoteSpawn.mock.calls[1]?.[0]).toMatchObject({ + command: 'codex resume exact-dead-ssh-provider-session' + }) + expect(store.setWorkspaceSession).toHaveBeenCalledWith(expect.anything(), hostId) + expect(store.persistPtyBinding).toHaveBeenCalledWith( + expect.objectContaining({ + worktreeId, + tabId, + leafId, + ptyId: freshPtyId + }), + hostId + ) + } finally { + unregisterSshPtyProvider(connectionId) + } + }) + + it('fails closed when runtime and persisted stable-pane owners conflict', async () => { + const tabId = 'tab-conflicting-owner' + const leafId = '99999999-9999-4999-8999-999999999999' + const paneKey = makePaneKey(tabId, leafId) + const worktreeId = 'repo-1::/tmp/conflicting-owner' + const providerSpawn = vi.fn() + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + const runtime = { + setPtyController: vi.fn(), + resolveTerminalPane: vi.fn(() => ({ + handle: 'term-runtime-owner', + tabId, + leafId, + ptyId: 'pty-runtime-owner', + worktreeId + })), + createPreAllocatedTerminalHandle: vi.fn(() => 'term-provisional') + } + const store = { + getWorkspaceSession: vi.fn(() => ({ + tabsByWorktree: { + [worktreeId]: [{ id: tabId, worktreeId, ptyId: 'pty-persisted-owner' }] + }, + terminalLayoutsByTabId: { + [tabId]: { ptyIdsByLeafId: { [leafId]: 'pty-persisted-owner' } } + } + })) + } + + registerPtyHandlers( + mainWindow as never, + runtime as never, + undefined, + undefined, + undefined, + store as never + ) + + await expect( + handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd: '/tmp/conflicting-owner', + worktreeId, + tabId, + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: tabId, + ORCA_WORKTREE_ID: worktreeId + } + }) + ).rejects.toThrow('terminal_pane_owner_conflict') + expect(providerSpawn).not.toHaveBeenCalled() + }) + + it('does not coalesce identical pane coordinates across worktrees', async () => { + const providerSpawn = vi.fn(async () => ({ id: `pty-${providerSpawn.mock.calls.length}` })) + setLocalPtyProvider({ + spawn: providerSpawn, + write: vi.fn(), + resize: vi.fn(), + kill: vi.fn(), + shutdown: vi.fn(), + sendSignal: vi.fn(), + getCwd: vi.fn(), + getInitialCwd: vi.fn(), + clearBuffer: vi.fn(), + acknowledgeDataEvent: vi.fn(), + hasChildProcesses: vi.fn(), + getForegroundProcess: vi.fn(), + serialize: vi.fn(), + revive: vi.fn(), + onData: vi.fn(() => () => {}), + onReplay: vi.fn(() => () => {}), + onExit: vi.fn(() => () => {}), + listProcesses: vi.fn(async () => []), + attach: vi.fn(), + getDefaultShell: vi.fn(), + getProfiles: vi.fn() + } as never) + registerPtyHandlers(mainWindow as never) + const leafId = '77777777-7777-4777-8777-777777777777' + const paneKey = makePaneKey('tab-host-scope', leafId) + const spawn = (worktreeId: string) => + handlers.get('pty:spawn')!(null, { + cols: 80, + rows: 24, + cwd: '/tmp', + worktreeId, + tabId: 'tab-host-scope', + leafId, + env: { + ORCA_PANE_KEY: paneKey, + ORCA_TAB_ID: 'tab-host-scope', + ORCA_WORKTREE_ID: worktreeId + } + }) + + await Promise.all([spawn('repo-1::/tmp/a'), spawn('repo-1::/tmp/b')]) + + expect(providerSpawn).toHaveBeenCalledTimes(2) + }) + it('settles the pane reservation when a post-spawn step throws so later spawns do not hang', async () => { // Why: reservation-leak regression — a post-spawn throw after provider.spawn resolves must reject/clear the reservation, else later spawns for the same pane key hang forever. registerPtyHandlers(mainWindow as never) @@ -8807,7 +9872,7 @@ describe('registerPtyHandlers', () => { } }) - it('does not leave SSH leases when runtime-owned binding persistence fails after reattach', async () => { + it('preserves adopted SSH ownership when runtime binding persistence fails', async () => { type RuntimeSpawnController = { spawn(args: { cols: number @@ -8895,9 +9960,12 @@ describe('registerPtyHandlers', () => { expect(remoteShutdown).not.toHaveBeenCalled() getPtyWriteListener()(mainWindowIpcEvent, { id: 'ssh:ssh-reattach-fail@@relay-pty', - data: 'echo should-not-route' + data: 'echo remains-routable' }) - expect(remoteWrite).not.toHaveBeenCalled() + expect(remoteWrite).toHaveBeenCalledWith( + 'ssh:ssh-reattach-fail@@relay-pty', + 'echo remains-routable' + ) unregisterSshPtyProvider('ssh-reattach-fail') }) @@ -10595,7 +11663,7 @@ describe('registerPtyHandlers', () => { cwd: '/tmp' })) as { id: string } const setRendererPtyVisible = getPtySetRendererPtyVisibleListener() - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() const handleRendererDispatcherReady = getPtyRendererDispatcherReadyListener() mainWindow.webContents.send.mockClear() @@ -10638,7 +11706,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() const handleRendererDispatcherReady = getPtyRendererDispatcherReadyListener() // Drain the initial dispatcher-ready flush (beforeEach fires the handshake to model a live page) so flood timing starts clean. vi.advanceTimersByTime(1) @@ -10703,7 +11771,7 @@ describe('registerPtyHandlers', () => { } }) - it('ignores a subframe did-start-loading (isLoadingMainFrame false) so an in-page iframe load cannot freeze delivery', async () => { + it('ignores overlapping subframe navigation so an in-page iframe cannot reclose delivery', async () => { vi.useFakeTimers() const mockProc = createMockProc() spawnMock.mockReturnValue(mockProc.proc) @@ -10715,8 +11783,8 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') - const ackData = getPtyAckDataListener() + const handleRendererNavigation = getMainWindowWebContentsListener('did-start-navigation') + const handleRendererDispatcherReady = getPtyRendererDispatcherReadyListener() // Drain the initial dispatcher-ready flush (beforeEach fires the handshake). vi.advanceTimersByTime(1) mainWindow.webContents.send.mockClear() @@ -10729,23 +11797,31 @@ describe('registerPtyHandlers', () => { } expect(mainWindow.webContents.send).toHaveBeenCalledTimes(32) - // A subframe load (isLoadingMainFrame() === false, e.g. notebook srcDoc iframe) is NOT a lifecycle reset — resetting here would freeze every pane for the watchdog window. - mainWindow.webContents.isLoadingMainFrame.mockReturnValueOnce(false) - handleRendererLoading() + // Main navigation closes the gate; the fresh dispatcher reopens it before an overlapping iframe navigates. + handleRendererNavigation({ isMainFrame: true, isSameDocument: false }) + handleRendererDispatcherReady() + handleRendererNavigation({ isMainFrame: false, isSameDocument: false }) expect(getPtyRendererDeliveryDebugSnapshot()).toMatchObject({ - rendererInFlightChars: 512 * 1024, - pendingChars: 88 * 1024, - pendingPtyCount: 1, - rendererLifecycleResetCount: 0, - lastLifecycleResetClearedChars: 0, + rendererInFlightChars: 0, + pendingChars: 0, + pendingPtyCount: 0, + rendererLifecycleResetCount: 1, + lastLifecycleResetClearedChars: 512 * 1024, rendererPtyDispatcherReady: true }) - // Gate still open: ACKing the in-flight cap drains the held backlog (a spurious reset would have cleared pending/ready, so this send would never fire). + // Gate remains open: output after the iframe navigation reaches the fresh page without waiting for the watchdog. mainWindow.webContents.send.mockClear() - ackData(null, { id: spawnResult.id, charCount: 512 * 1024 }) + mockProc.emitData('post-subframe output') vi.advanceTimersByTime(8) - expect(mainWindow.webContents.send).toHaveBeenCalled() + expect(mainWindow.webContents.send).toHaveBeenCalledWith('pty:data', { + id: spawnResult.id, + data: 'post-subframe output' + }) + expect(getPtyRendererDeliveryDebugSnapshot()).toMatchObject({ + rendererPtyDispatcherReady: true, + rendererDispatcherReadyForcedCount: 0 + }) } finally { vi.useRealTimers() } @@ -10782,7 +11858,7 @@ describe('registerPtyHandlers', () => { rendererPtyDispatcherReady: true }) - // Handshake arriving while the gate is already open proves a missed lifecycle reset (subframe-overlapped reload emits no did-start-loading); it must reconcile stale accounting or survivors stay pinned at the cap forever. + // Handshake while the gate is open proves a missed lifecycle reset; reconcile or survivors stay pinned at the cap. mainWindow.webContents.send.mockClear() handleRendererDispatcherReady() const reconciled = getPtyRendererDeliveryDebugSnapshot() @@ -10823,7 +11899,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() const handleRendererDispatcherReady = getPtyRendererDispatcherReadyListener() const writeListener = getPtyWriteListener() // Drain the initial ready-flush the beforeEach handshake schedules. @@ -10868,7 +11944,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() vi.advanceTimersByTime(1) // Reload closes the gate and arms the ~10s watchdog; the reloaded page never sends the handshake (dropped IPC), so output stays held. @@ -10910,7 +11986,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() const readyCall = onMock.mock.calls.find( (call: unknown[]) => call[0] === 'pty:rendererDispatcherReady' )! @@ -10951,7 +12027,7 @@ describe('registerPtyHandlers', () => { try { registerPtyHandlers(mainWindow as never) await handlers.get('pty:spawn')!(null, { cols: 80, rows: 24, cwd: '/tmp' }) - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() const handleRendererDispatcherReady = getPtyRendererDispatcherReadyListener() vi.advanceTimersByTime(1) @@ -10984,7 +12060,7 @@ describe('registerPtyHandlers', () => { try { registerPtyHandlers(mainWindow as never) await handlers.get('pty:spawn')!(null, { cols: 80, rows: 24, cwd: '/tmp' }) - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() // Drain the initial dispatcher-ready flush; the baseline is timer-free. vi.advanceTimersByTime(1) expect(vi.getTimerCount()).toBe(0) @@ -11103,9 +12179,12 @@ describe('registerPtyHandlers', () => { const sourceData = '\x1b]10;?\x1b\\\x1b]11;?\x1b\\ready' mockProc.emitData(sourceData) + // Why: the reply leaves the query's own turn so a still-cooked tty cannot + // echo it back as text instead of delivering it to the agent (#12112). + expect(mockProc.proc.write).not.toHaveBeenCalled() + vi.advanceTimersByTime(2) expect(mockProc.proc.write).toHaveBeenCalledWith('\x1b]10;rgb:eeee/eeee/eeee\x1b\\') expect(mockProc.proc.write).toHaveBeenCalledWith('\x1b]11;rgb:1111/1111/1111\x1b\\') - vi.advanceTimersByTime(2) expect(mainWindow.webContents.send).toHaveBeenCalledWith('pty:data', { id: spawnResult.id, data: 'ready', @@ -11140,9 +12219,11 @@ describe('registerPtyHandlers', () => { const sourceData = '\x1b]10;?;?\x1b\\ready' mockProc.emitData(sourceData) + // Why: both slots of a duplicate-slot query leave the query's own turn too (#12112). + expect(mockProc.proc.write).not.toHaveBeenCalled() + vi.advanceTimersByTime(2) expect(mockProc.proc.write).toHaveBeenCalledWith('\x1b]10;rgb:eeee/eeee/eeee\x1b\\') expect(mockProc.proc.write).toHaveBeenCalledWith('\x1b]11;rgb:1111/1111/1111\x1b\\') - vi.advanceTimersByTime(2) expect(mainWindow.webContents.send).toHaveBeenCalledWith('pty:data', { id: spawnResult.id, data: 'ready', @@ -11794,7 +12875,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' }) - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() let cleared = false mainWindow.webContents.send.mockImplementation( (channel: string, payload: { id?: string }) => { @@ -12506,7 +13587,7 @@ describe('registerPtyHandlers', () => { try { const provider = installObservableDaemonTestProvider() registerPtyHandlers(mainWindow as never) - const resetRenderer = getMainWindowWebContentsListener('did-start-loading') + const resetRenderer = getMainFrameNavigationListener() const readyRenderer = getPtyRendererDispatcherReadyListener() let failed = false mainWindow.webContents.send.mockImplementation((channel: string) => { @@ -13256,7 +14337,7 @@ describe('registerPtyHandlers', () => { try { await spawnAndSaturateRendererDeliveryGate(mockProc) - const handleRendererLoading = getMainWindowWebContentsListener('did-start-loading') + const handleRendererLoading = getMainFrameNavigationListener() expect(getPtyRendererDeliveryDebugSnapshot()).toMatchObject({ rendererInFlightPtyCount: 1, rendererInFlightChars: 512 * 1024 @@ -14031,7 +15112,7 @@ describe('registerPtyHandlers', () => { const setHidden = getPtySetHiddenRendererPtyListener() const setInterest = getPtySetDeliveryInterestListener() const setActive = getPtySetActiveRendererPtyListener() - getMainWindowWebContentsListener('did-start-loading')() + getMainFrameNavigationListener()() mainWindow.webContents.send.mockClear() setHidden(null, { id: spawnResult.id, hidden: true }) @@ -14119,7 +15200,7 @@ describe('registerPtyHandlers', () => { rows: 24, cwd: '/tmp' })) as { id: string } - getMainWindowWebContentsListener('did-start-loading')() + getMainFrameNavigationListener()() getPtySetHiddenRendererPtyListener()(null, { id: spawnResult.id, hidden: true }) mainWindow.webContents.send.mockClear() mockProc.emitData('blocked while gate disabled') diff --git a/src/main/ipc/pty.ts b/src/main/ipc/pty.ts index d7786a30d0e..cd01a985243 100644 --- a/src/main/ipc/pty.ts +++ b/src/main/ipc/pty.ts @@ -14,6 +14,7 @@ import { export { getBashShellReadyRcfileContent } from '../providers/local-pty-shell-ready' import type { OrcaRuntimeService } from '../runtime/orca-runtime' import type { Store } from '../persistence' +import { retireTerminalSurfaceFromPersistence } from '../runtime/mobile-session-terminal-persistence-retirement' import type { GlobalSettings, TuiAgent } from '../../shared/types' import { toSshExecutionHostId } from '../../shared/execution-host' import { normalizeRuntimePathForComparison } from '../../shared/cross-platform-path' @@ -146,7 +147,7 @@ import { clearMigrationUnsupportedPtysForPaneKey } from '../agent-hooks/migration-unsupported-pty-state' import { parseWslPath } from '../wsl' -import { mergePersistedWindowsPath } from '../pty/windows-environment-path' +import { mergePersistedWindowsPath, resolvePathEnvKey } from '../pty/windows-environment-path' import { addOrcaWslInteropEnv, stampWslOrchestrationCompatibilityHost } from '../pty/wsl-orca-env' import { PtyProducerFlowController } from './pty-producer-flow-control' import { beginTerminalInstall } from './watcher-removal-gate' @@ -227,9 +228,6 @@ import type { PtyListedSession } from '../../shared/pty-listed-session' // Routes PTY operations by connectionId (null = local provider). let localProvider: IPtyProvider = new LocalPtyProvider() -type FreshLocalFallbackProvider = IPtyProvider & { - routesFreshSpawnsToLocalProvider?: true -} const sshProviders = new Map() const sshProvidersByGeneration = new Map() @@ -317,9 +315,20 @@ type PaneSpawnReservation = { type PaneSpawnReservationResult = { id: string launchConfig?: SleepingAgentLaunchConfig + stablePaneOwner?: { + handle: string + tabId: string + leafId: string + } } & Partial -// Why: mobile materialization and a newly-focused pane can race to spawn the same leaf; key by paneKey so the loser adopts the winner's PTY. -const paneSpawnReservationsByPaneKey = new Map() +// Why: identical pane coordinates on different worktrees or hosts are independent owners. +const paneSpawnReservationsByOwnerKey = new Map() +type PendingRuntimePaneCreate = { + count: number + promise: Promise + resolve: () => void +} +const pendingRuntimePaneCreatesByOwnerKey = new Map() // Why: one main process can route the same remote provider namespace through // multiple SSH relays; coordinate claims above every provider boundary too. const agentSessionOwners = new ClaimedAgentPtyOwnerRegistry() @@ -475,16 +484,54 @@ function reservePaneSpawn(paneKey: string): PaneSpawnReservation { }) promise.catch(() => {}) const reservation = { promise, resolve, reject } - paneSpawnReservationsByPaneKey.set(paneKey, reservation) + paneSpawnReservationsByOwnerKey.set(paneKey, reservation) return reservation } function clearPaneSpawnReservation(paneKey: string, reservation: PaneSpawnReservation): void { - if (paneSpawnReservationsByPaneKey.get(paneKey) === reservation) { - paneSpawnReservationsByPaneKey.delete(paneKey) + if (paneSpawnReservationsByOwnerKey.get(paneKey) === reservation) { + paneSpawnReservationsByOwnerKey.delete(paneKey) } } +function makePaneSpawnReservationKey( + worktreeId: string | undefined, + connectionId: string | null | undefined, + paneKey: string | null | undefined +): string | null { + return paneKey ? JSON.stringify([connectionId ?? null, worktreeId ?? null, paneKey]) : null +} + +function claimRuntimePaneCreate(ownerKey: string): () => void { + const existing = pendingRuntimePaneCreatesByOwnerKey.get(ownerKey) + if (existing) { + existing.count += 1 + return () => releaseRuntimePaneCreate(ownerKey, existing) + } + let resolve!: () => void + const claim = { + count: 1, + promise: new Promise((done) => { + resolve = done + }), + resolve: () => resolve() + } + pendingRuntimePaneCreatesByOwnerKey.set(ownerKey, claim) + return () => releaseRuntimePaneCreate(ownerKey, claim) +} + +function releaseRuntimePaneCreate(ownerKey: string, claim: PendingRuntimePaneCreate): void { + if (pendingRuntimePaneCreatesByOwnerKey.get(ownerKey) !== claim) { + return + } + claim.count -= 1 + if (claim.count > 0) { + return + } + pendingRuntimePaneCreatesByOwnerKey.delete(ownerKey) + claim.resolve() +} + function rejectPaneSpawnReservation( paneKey: string | null | undefined, reservation: PaneSpawnReservation | null | undefined, @@ -514,6 +561,227 @@ function resolvePaneSpawnReservation( return response } +type StablePaneOwner = { + handle?: string + tabId: string + leafId: string + ptyId: string + incarnationId?: string +} +type StablePaneAdoption = { + result: PtySpawnResult + owner: StablePaneOwner + materialized?: true +} | null +const stablePaneAdoptionsByOwnerKey = new Map>() + +function resolvePersistedStablePaneOwner( + store: Store | undefined, + paneKey: string, + worktreeId: string, + connectionId: string | null | undefined +): Pick | null { + if (!store || typeof store.getWorkspaceSession !== 'function') { + return null + } + const parsed = parsePaneKey(paneKey) + if (!parsed) { + return null + } + const session = store.getWorkspaceSession( + connectionId ? toSshExecutionHostId(connectionId) : undefined + ) + const tab = session.tabsByWorktree?.[worktreeId]?.find( + (candidate) => candidate.id === parsed.tabId && candidate.worktreeId === worktreeId + ) + const ptyId = session.terminalLayoutsByTabId?.[parsed.tabId]?.ptyIdsByLeafId?.[parsed.leafId] + if (!tab || typeof ptyId !== 'string' || ptyId.length === 0) { + return null + } + const incarnationId = session.terminalPtyIncarnationsByPaneKey?.[paneKey] + return { + tabId: parsed.tabId, + leafId: parsed.leafId, + ptyId, + ...(incarnationId ? { incarnationId } : {}) + } +} + +function resolveStablePaneOwner( + runtime: OrcaRuntimeService | undefined, + store: Store | undefined, + paneKey: string | null | undefined, + worktreeId: string | undefined, + connectionId: string | null | undefined +): StablePaneOwner | null { + if (!paneKey || !worktreeId) { + return null + } + let resolved: ReturnType | null = null + let resolvedHandleCandidate: ReturnType | null = null + if (runtime && typeof runtime.resolveTerminalPane === 'function') { + try { + const candidate = runtime.resolveTerminalPane(paneKey, worktreeId) + resolvedHandleCandidate = candidate + resolved = candidate.connected === false ? null : candidate + } catch (error) { + if (!(error instanceof Error && error.message === 'terminal_not_found')) { + throw error + } + } + } + const persisted = resolvePersistedStablePaneOwner(store, paneKey, worktreeId, connectionId) + if (resolved?.ptyId && persisted && resolved.ptyId !== persisted.ptyId) { + throw new Error('terminal_pane_owner_conflict') + } + const ptyId = resolved?.ptyId ?? persisted?.ptyId + if (!ptyId) { + return null + } + const registeredConnectionId = ptyOwnership.get(ptyId) + const parsedSshId = registeredConnectionId === undefined ? parseAppSshPtyId(ptyId) : null + const ownerConnectionId = registeredConnectionId ?? parsedSshId?.connectionId ?? null + if (ownerConnectionId !== (connectionId ?? null)) { + throw new Error('terminal_pane_owner_host_mismatch') + } + const runtimeIncarnationId = ptyIncarnationById.get(ptyId) + if ( + runtimeIncarnationId && + persisted?.incarnationId && + runtimeIncarnationId !== persisted.incarnationId + ) { + throw new Error('terminal_pane_owner_conflict') + } + const parsed = parsePaneKey(paneKey) + if (!parsed) { + return null + } + return { + ...(resolvedHandleCandidate?.ptyId === ptyId ? { handle: resolvedHandleCandidate.handle } : {}), + tabId: resolved?.tabId || persisted?.tabId || parsed.tabId, + leafId: resolved?.leafId || persisted?.leafId || parsed.leafId, + ptyId, + ...(runtimeIncarnationId || persisted?.incarnationId + ? { incarnationId: runtimeIncarnationId ?? persisted?.incarnationId } + : {}) + } +} + +function retirePersistedStablePaneOwner( + store: Store | undefined, + owner: StablePaneOwner, + worktreeId: string, + connectionId: string | null | undefined +): boolean { + if (!store) { + return false + } + const paneKey = makePaneKey(owner.tabId, owner.leafId) + const hostId = connectionId ? toSshExecutionHostId(connectionId) : undefined + const current = resolvePersistedStablePaneOwner(store, paneKey, worktreeId, connectionId) + if (current?.ptyId !== owner.ptyId || current.incarnationId !== owner.incarnationId) { + return false + } + const session = store.getWorkspaceSession(hostId) + const retired = retireTerminalSurfaceFromPersistence(session, { + worktreeId, + parentTabId: owner.tabId, + leafId: owner.leafId, + ptyId: owner.ptyId, + ...(owner.incarnationId ? { incarnationId: owner.incarnationId } : {}) + }) + if (retired === session) { + return false + } + store.setWorkspaceSession(retired, hostId) + store.flushOrThrow() + return true +} + +type StablePaneSpawnContext = { + runtime: OrcaRuntimeService | undefined + store?: Store + provider: IPtyProvider + spawnOptions: PtySpawnOptions + owner: StablePaneOwner | null + worktreeId?: string + connectionId?: string | null + resolveOwner?: () => StablePaneOwner | null + onFreshSpawn?: (result: PtySpawnResult) => void +} + +async function attachStablePaneOwner( + args: StablePaneSpawnContext & { owner: StablePaneOwner } +): Promise<{ result: PtySpawnResult; owner: StablePaneOwner } | null> { + const { owner, provider, runtime, spawnOptions } = args + let result: PtySpawnResult + try { + result = await provider.spawn({ + ...spawnOptions, + sessionId: owner.ptyId, + attachOnly: true, + isNewSession: undefined, + command: undefined, + commandDelivery: undefined, + startupCommandDelivery: undefined, + launchAgent: undefined, + startupIngress: undefined, + agentSessionEnsure: undefined, + agentSessionCreateOperationId: undefined, + onPtySpawnCommitted: undefined + }) + } catch (error) { + if (!isPtyAlreadyGoneError(error)) { + throw error + } + const ownerBeforeRetire = args.resolveOwner?.() + if ( + ownerBeforeRetire && + (ownerBeforeRetire.ptyId !== owner.ptyId || + (ownerBeforeRetire.incarnationId !== undefined && + owner.incarnationId !== undefined && + ownerBeforeRetire.incarnationId !== owner.incarnationId)) + ) { + throw new Error('terminal_pane_owner_changed') + } + runtime?.onPtyExit(owner.ptyId, 0, owner.incarnationId) + clearProviderPtyState(owner.ptyId) + ptyOwnership.delete(owner.ptyId) + if ( + args.worktreeId && + !retirePersistedStablePaneOwner(args.store, owner, args.worktreeId, args.connectionId) + ) { + throw new Error('terminal_pane_owner_changed') + } + if (args.resolveOwner?.()) { + throw new Error('terminal_pane_owner_changed') + } + return null + } + if ( + result.id !== owner.ptyId || + result.isReattach !== true || + (owner.incarnationId !== undefined && result.incarnationId !== owner.incarnationId) + ) { + throw new Error('terminal_pane_owner_changed') + } + return { result, owner } +} + +async function spawnForStablePane( + args: StablePaneSpawnContext +): Promise<{ result: PtySpawnResult; owner: StablePaneOwner | null }> { + if (args.owner) { + const attached = await attachStablePaneOwner({ ...args, owner: args.owner }) + if (attached) { + return attached + } + } + const result = await args.provider.spawn(args.spawnOptions) + args.onFreshSpawn?.(result) + return { result, owner: null } +} + function settlePendingPaneSerializer(paneKey: string, gen: number): boolean { if (pendingByPaneKey.get(paneKey)?.gen !== gen) { return false @@ -743,7 +1011,8 @@ export type BuildPtyHostEnvOptions = { } function readInheritedPath(baseEnv: Record): string { - return baseEnv.PATH ?? baseEnv.Path ?? process.env.PATH ?? process.env.Path ?? '' + const pathKey = resolvePathEnvKey(baseEnv, process.platform) + return baseEnv[pathKey] ?? process.env[pathKey] ?? '' } function firstPathEntry(pathValue: string | undefined): string | null { @@ -1407,7 +1676,9 @@ export function buildPtyHostEnv( const devCliBin = join(opts.userDataPath, 'cli', 'bin') const inheritedPath = readInheritedPath(baseEnv) // Why: an empty PATH segment resolves as `.` in some shells (commands run from cwd); avoid a trailing delimiter. - baseEnv.PATH = inheritedPath ? `${devCliBin}${delimiter}${inheritedPath}` : devCliBin + baseEnv[resolvePathEnvKey(baseEnv, process.platform)] = inheritedPath + ? `${devCliBin}${delimiter}${inheritedPath}` + : devCliBin } else if (process.platform === 'linux') { // Why: bare-`orca` shim scoped to Orca PTYs — Linux CLI installs as `orca-ide` to avoid shadowing GNOME's /usr/bin/orca screen reader (stablyai/orca#7904). const shimDir = ensureLinuxTerminalOrcaCliShimDir({ userDataPath: opts.userDataPath }) @@ -1448,10 +1719,20 @@ function isClaudeLaunchCommand(command: string | undefined): boolean { ) } -function routesFreshSpawnsToLocalProvider( - provider: IPtyProvider -): provider is FreshLocalFallbackProvider { - return (provider as FreshLocalFallbackProvider).routesFreshSpawnsToLocalProvider === true +function routesFreshSpawnsToLocalProvider(provider: IPtyProvider): boolean { + return provider.routesFreshSpawnsToLocalProvider === true +} + +function recoverFreshSpawnProviderRouting( + provider: IPtyProvider, + connectionId: string | null | undefined, + sessionId: string | undefined, + isNewSession = sessionId === undefined +): Promise | undefined { + if (connectionId || (!isNewSession && sessionId) || !routesFreshSpawnsToLocalProvider(provider)) { + return + } + return provider.recoverFreshSpawnRouting?.() } function beginPtySpawnForWorktree( @@ -1659,8 +1940,13 @@ let rendererGateResetWebContents: WebContents | null = null let clearBackgroundedDeliverySyncForPty: (id: string) => void = () => {} // Why: after daemon keep-tail thinning main's mirror holds only the kept tail, so recovery must keep consulting the daemon's complete model until exit. const providerSnapshotRequiredPtys = new Set() -// Why: did-start-loading also fires for in-page subframe loads (notebook srcDoc iframes); a dedicated handler filters those via isLoadingMainFrame. -let rendererDidStartLoadingHandler: (() => void) | null = null +type RendererNavigationDetails = { + isMainFrame: boolean + isSameDocument: boolean +} + +// Why: navigation details identify the triggering frame; querying aggregate load state can misclassify an overlapping subframe load. +let rendererDidStartNavigationHandler: ((details: RendererNavigationDetails) => void) | null = null // Why: Restart daemon must re-bind provider→renderer listeners after replaceDaemonProvider swaps localProvider, else subscribers stay bound to the disposed adapter and new PTY data silently drops. let rebindProviderListeners: (() => void) | null = null @@ -1795,10 +2081,10 @@ function clearRendererLifecycleResetHandlers(): void { if (!rendererLifecycleResetWebContents) { return } - if (rendererDidStartLoadingHandler) { + if (rendererDidStartNavigationHandler) { rendererLifecycleResetWebContents.removeListener( - 'did-start-loading', - rendererDidStartLoadingHandler + 'did-start-navigation', + rendererDidStartNavigationHandler ) } if (rendererLifecycleResetHandler) { @@ -1810,7 +2096,7 @@ function clearRendererLifecycleResetHandlers(): void { } rendererLifecycleResetWebContents = null rendererLifecycleResetHandler = null - rendererDidStartLoadingHandler = null + rendererDidStartNavigationHandler = null } function registerRendererLifecycleResetHandlers(webContents: WebContents): void { @@ -1818,14 +2104,13 @@ function registerRendererLifecycleResetHandlers(webContents: WebContents): void markRendererPtysHiddenForRendererLifecycleReset() rendererLifecycleResetWebContents = webContents rendererLifecycleResetHandler = markRendererPtysHiddenForRendererLifecycleReset - // Why: did-start-loading also fires for in-page subframe loads (notebook srcDoc iframes); filter via isLoadingMainFrame so a subframe load can't clear pendingData and freeze the alive page. - rendererDidStartLoadingHandler = () => { - if (!webContents.isLoadingMainFrame()) { + rendererDidStartNavigationHandler = (details) => { + if (!details.isMainFrame || details.isSameDocument) { return } markRendererPtysHiddenForRendererLifecycleReset() } - webContents.on('did-start-loading', rendererDidStartLoadingHandler) + webContents.on('did-start-navigation', rendererDidStartNavigationHandler) webContents.on('render-process-gone', rendererLifecycleResetHandler) webContents.on('destroyed', rendererLifecycleResetHandler) } @@ -3811,17 +4096,145 @@ export function registerPtyHandlers( : env } + const adoptStablePane = async (args: { + cols: number + rows: number + cwd?: string + connectionId?: string | null + worktreeId: string + preAllocatedHandle?: string + tabId: string + leafId: string + ownsPaneSpawnReservation?: true + }) => { + const paneKey = makePaneKey(args.tabId, args.leafId) + const ownerKey = makePaneSpawnReservationKey(args.worktreeId, args.connectionId, paneKey) + const pendingAdoption = ownerKey ? stablePaneAdoptionsByOwnerKey.get(ownerKey) : undefined + if (pendingAdoption) { + return await pendingAdoption + } + const activePaneSpawn = + ownerKey && !args.ownsPaneSpawnReservation + ? paneSpawnReservationsByOwnerKey.get(ownerKey) + : undefined + if (activePaneSpawn) { + const result = await activePaneSpawn.promise + const owner = resolveStablePaneOwner( + runtime, + store, + paneKey, + args.worktreeId, + args.connectionId + ) + if ( + !owner || + owner.ptyId !== result.id || + (owner.incarnationId !== undefined && + result.incarnationId !== undefined && + owner.incarnationId !== result.incarnationId) + ) { + throw new Error('terminal_pane_owner_changed') + } + return { + result: { + ...result, + isReattach: true, + ...(owner.incarnationId ? { incarnationId: owner.incarnationId } : {}) + }, + owner, + materialized: true as const + } + } + const owner = resolveStablePaneOwner( + runtime, + store, + paneKey, + args.worktreeId, + args.connectionId + ) + if (!owner) { + return null + } + const adoption = attachStablePaneOwner({ + runtime, + store, + provider: getProvider(args.connectionId), + spawnOptions: { + cols: args.cols, + rows: args.rows, + cwd: args.cwd + }, + owner, + worktreeId: args.worktreeId, + connectionId: args.connectionId, + resolveOwner: () => + resolveStablePaneOwner(runtime, store, paneKey, args.worktreeId, args.connectionId) + }) + if (!ownerKey) { + return await adoption + } + stablePaneAdoptionsByOwnerKey.set(ownerKey, adoption) + try { + return await adoption + } finally { + if (stablePaneAdoptionsByOwnerKey.get(ownerKey) === adoption) { + stablePaneAdoptionsByOwnerKey.delete(ownerKey) + } + } + } + // Why: route through getProviderForPty() so CLI commands work for remote PTYs too; localProvider would silently fail for them. runtime?.setPtyController({ + claimStablePaneCreate: (args) => { + const paneKey = makePaneKey(args.tabId, args.leafId) + const ownerKey = makePaneSpawnReservationKey(args.worktreeId, args.connectionId, paneKey) + return ownerKey ? claimRuntimePaneCreate(ownerKey) : () => {} + }, + adoptStablePane, spawn: async (args) => { + const preAdoptedStablePane = args.adoptedStablePane ?? null const startupPromise = getLocalPtyStartupPromise(args.connectionId) if (startupPromise) { await startupPromise } - await assertFolderWorkspacePtyPathUsable(args.worktreeId) + if (preAdoptedStablePane?.materialized) { + const handle = preAdoptedStablePane.owner.handle ?? args.preAllocatedHandle + if (!handle) { + throw new Error('terminal_pane_owner_unknown') + } + return { + id: preAdoptedStablePane.result.id, + ...(preAdoptedStablePane.result.incarnationId + ? { incarnationId: preAdoptedStablePane.result.incarnationId } + : {}), + ...(typeof preAdoptedStablePane.result.wslDistro === 'string' + ? { wslDistro: preAdoptedStablePane.result.wslDistro } + : {}), + stablePaneOwner: { + handle, + tabId: preAdoptedStablePane.owner.tabId, + leafId: preAdoptedStablePane.owner.leafId + } + } + } + if (!preAdoptedStablePane) { + await assertFolderWorkspacePtyPathUsable(args.worktreeId) + } const cwd = resolvePtySpawnStartupCwd(args.worktreeId, args.cwd) const provider = getProvider(args.connectionId) - const isClaudeLaunch = !args.connectionId && isClaudeLaunchCommand(args.command) + const freshSpawnRecovery = preAdoptedStablePane + ? undefined + : recoverFreshSpawnProviderRouting( + provider, + args.connectionId, + args.sessionId, + args.isNewSession + ) + if (freshSpawnRecovery) { + await freshSpawnRecovery + } + const isClaudeLaunch = + !preAdoptedStablePane && !args.connectionId && isClaudeLaunchCommand(args.command) if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) { throw new Error('A Claude account switch is in progress. Try again after it finishes.') } @@ -3852,7 +4265,10 @@ export function registerPtyHandlers( sessionId !== undefined ? getRelayPtyId(args.connectionId, sessionId) : undefined const effectiveSessionAppId = sessionId !== undefined ? getAppPtyId(args.connectionId, sessionId) : undefined - const isMintedSessionId = callerRequestedSessionId === undefined && isDaemonHostSpawn + const isNewDaemonSession = + !preAdoptedStablePane && + isDaemonHostSpawn && + (callerRequestedSessionId === undefined || args.isNewSession === true) const expectedWslDistro = !args.connectionId ? (resolveWslSessionContext({ cwd, @@ -3866,17 +4282,19 @@ export function registerPtyHandlers( cwd, expectedWslDistro ) - const codexResumePreparation = prepareCodexResumeHome({ - connectionId: args.connectionId, - launchAgent: args.launchAgent, - providerSession: args.resumeProviderSession, - target: codexSelectionTarget, - launchEnv: args.env, - workspacePath: cwd - }) + const codexResumePreparation = preAdoptedStablePane + ? null + : prepareCodexResumeHome({ + connectionId: args.connectionId, + launchAgent: args.launchAgent, + providerSession: args.resumeProviderSession, + target: codexSelectionTarget, + launchEnv: args.env, + workspacePath: cwd + }) const codexResumeLaunch = codexResumePreparation ? await resolveCodexResumeLaunch(args.command, codexResumePreparation) - : noCodexResumeLaunch(args.command) + : noCodexResumeLaunch(preAdoptedStablePane ? undefined : args.command) const codexResumeHome = codexResumeLaunch.codexResumeHome // Why: the drop still applies here, but this controller's result has no field for // notifyResumeUnavailable — runtime/relay panes start fresh without the notice. @@ -3923,23 +4341,30 @@ export function registerPtyHandlers( let env: Record | undefined = claudeAuth ? { ...sshScopedEnv, ...claudeAuth.envPatch } : sshScopedEnv - const requestedAgentTeamsPath = env?.ORCA_AGENT_TEAMS_TEAM_ID ? env.PATH : undefined + const requestedAgentTeamsPath = env?.ORCA_AGENT_TEAMS_TEAM_ID + ? env[resolvePathEnvKey(env, process.platform)] + : undefined env = stripSequencedStartupResumeArgv(env, codexResumeLaunch) if (args.preAllocatedHandle) { env = { ...env, ORCA_TERMINAL_HANDLE: args.preAllocatedHandle } } - let selectedCodexHomePath = !args.connectionId - ? getCompatibleSelectedCodexHomePath( - codexSelectionTarget, - codexResumeHome - ? codexResumeHome.codexHomePath - : (getSelectedCodexHomePath?.(codexSelectionTarget, env, { - workspacePath: cwd, - launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined - }) ?? null) - ) - : null - if (args.launchAgent === 'codex' && callerRequestedSessionId === undefined) { + let selectedCodexHomePath = + !preAdoptedStablePane && !args.connectionId + ? getCompatibleSelectedCodexHomePath( + codexSelectionTarget, + codexResumeHome + ? codexResumeHome.codexHomePath + : (getSelectedCodexHomePath?.(codexSelectionTarget, env, { + workspacePath: cwd, + launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined + }) ?? null) + ) + : null + if ( + !preAdoptedStablePane && + args.launchAgent === 'codex' && + callerRequestedSessionId === undefined + ) { const resolution = resolveCodexHomeAfterManagedAuthReadiness({ selectedCodexHomePath, getSettings: () => getSettings?.(), @@ -3980,7 +4405,7 @@ export function registerPtyHandlers( skipCodexHomeEnv, settings: getSettings?.() }) - if (isDaemonHostSpawn && sessionId) { + if (isDaemonHostSpawn && sessionId && !preAdoptedStablePane) { if (!isSafePtySessionId(sessionId, app.getPath('userData'))) { throw new Error('Invalid PTY session id') } @@ -4016,7 +4441,7 @@ export function registerPtyHandlers( rows: args.rows, cwd, env, - ...(isMintedSessionId ? { isNewSession: true } : {}) + ...(isNewDaemonSession ? { isNewSession: true } : {}) } if (!args.connectionId && !isDaemonHostSpawn) { spawnOptions.codexHomePathOverride = { value: selectedCodexHomePath } @@ -4110,6 +4535,7 @@ export function registerPtyHandlers( : undefined } if ( + !preAdoptedStablePane && args.agentSessionEnsure && (await (provider as IPtyProvider).supportsAgentSessionClaims?.()) === false ) { @@ -4117,15 +4543,16 @@ export function registerPtyHandlers( throw new Error('agent_session_claim_unavailable') } if ( + !preAdoptedStablePane && args.agentSessionCreateOperationId && (await (provider as IPtyProvider).supportsAgentSessionCreateOperations?.()) === false ) { throw new Error('execution_owner_unavailable') } - if (args.agentSessionEnsure) { + if (!preAdoptedStablePane && args.agentSessionEnsure) { spawnOptions.agentSessionEnsure = args.agentSessionEnsure } - if (args.agentSessionCreateOperationId) { + if (!preAdoptedStablePane && args.agentSessionCreateOperationId) { spawnOptions.agentSessionCreateOperationId = args.agentSessionCreateOperationId } if (args.signal) { @@ -4139,21 +4566,54 @@ export function registerPtyHandlers( spawnOptions.onPtySpawnCommitted = reportPtySpawnCommitted } - const existingPaneSpawn = materializedPaneKey - ? paneSpawnReservationsByPaneKey.get(materializedPaneKey) + const paneSpawnReservationKey = makePaneSpawnReservationKey( + args.worktreeId, + args.connectionId, + spawnIdentityPaneKey + ) + const existingPaneSpawn = paneSpawnReservationKey + ? paneSpawnReservationsByOwnerKey.get(paneSpawnReservationKey) : undefined if (existingPaneSpawn) { - return await existingPaneSpawn.promise + const concurrentResult = await existingPaneSpawn.promise + const concurrentOwner = resolveStablePaneOwner( + runtime, + store, + spawnIdentityPaneKey, + args.worktreeId, + args.connectionId + ) + if ( + !concurrentOwner?.handle || + concurrentOwner.ptyId !== concurrentResult.id || + (concurrentOwner.incarnationId !== undefined && + concurrentResult.incarnationId !== undefined && + concurrentOwner.incarnationId !== concurrentResult.incarnationId) + ) { + throw new Error('terminal_pane_owner_unknown') + } + return { + id: concurrentOwner.ptyId, + ...(concurrentOwner.incarnationId + ? { incarnationId: concurrentOwner.incarnationId } + : {}), + stablePaneOwner: { + handle: concurrentOwner.handle, + tabId: concurrentOwner.tabId, + leafId: concurrentOwner.leafId + } + } } const finishTerminalInstall = beginPtySpawnForWorktree( args.worktreeId, cwd, args.connectionId ) - const paneSpawnReservation = materializedPaneKey - ? reservePaneSpawn(materializedPaneKey) + const paneSpawnReservation = paneSpawnReservationKey + ? reservePaneSpawn(paneSpawnReservationKey) : null let result: PtySpawnResult + let stablePaneOwner: StablePaneOwner | null = null let rejectedRegistrationCandidate: PtySpawnResult | null = null let pendingRegistrationPtyId: string | null = null let preparedProvisionalExecutionContext = false @@ -4164,7 +4624,19 @@ export function registerPtyHandlers( if (args.preAllocatedHandle) { trustedTerminalHandleEnv.add(args.preAllocatedHandle) } - const expectedPtyId = effectiveSessionAppId ?? sessionId + const stablePaneOwnerCandidate = preAdoptedStablePane + ? preAdoptedStablePane.owner + : args.agentSessionEnsure + ? null + : resolveStablePaneOwner( + runtime, + store, + spawnIdentityPaneKey, + args.worktreeId, + args.connectionId + ) + const expectedPtyId = + stablePaneOwnerCandidate?.ptyId ?? effectiveSessionAppId ?? sessionId if (expectedPtyId) { runtime?.beginPtyRegistration?.(expectedPtyId) pendingRegistrationPtyId = expectedPtyId @@ -4172,8 +4644,8 @@ export function registerPtyHandlers( if (isDaemonHostSpawn && expectedPtyId) { preparedProvisionalExecutionContext = runtime?.preparePtyExecutionContext?.(expectedPtyId, expectedWslDistro, { - resetIncarnation: isMintedSessionId, - preserveExisting: !isMintedSessionId + resetIncarnation: isNewDaemonSession && !stablePaneOwnerCandidate, + preserveExisting: !isNewDaemonSession || Boolean(stablePaneOwnerCandidate) }) ?? false } const sequenceBeforeProviderSpawn = expectedPtyId @@ -4184,7 +4656,7 @@ export function registerPtyHandlers( throw new Error('client_disconnected') } } - if (args.agentSessionEnsure) { + if (args.agentSessionEnsure && !preAdoptedStablePane) { // Why: daemon-backed claims can outlive this controller; import all // proven owners before deciding that an identity is absent. await reconcileAgentSessionOwnerListings() @@ -4250,10 +4722,37 @@ export function registerPtyHandlers( result.agentSessionEnsure = ensured } else { assertClientStillConnected() - result = await provider.spawn(spawnOptions) + const stablePaneSpawn = preAdoptedStablePane + ? preAdoptedStablePane + : await spawnForStablePane({ + runtime, + store, + provider, + spawnOptions, + owner: stablePaneOwnerCandidate, + worktreeId: args.worktreeId, + connectionId: args.connectionId, + resolveOwner: () => + resolveStablePaneOwner( + runtime, + store, + spawnIdentityPaneKey, + args.worktreeId, + args.connectionId + ), + onFreshSpawn: reportPtySpawnCommitted + }) + result = stablePaneSpawn.result + stablePaneOwner = stablePaneSpawn.owner + if ( + stablePaneOwner && + isNewDaemonSession && + effectiveSessionAppId && + effectiveSessionAppId !== result.id + ) { + clearProviderPtyState(effectiveSessionAppId) + } rejectedRegistrationCandidate = result - // Why: daemon/relay returns cross the physical commit boundary before controller admission. - reportPtySpawnCommitted() assertSpawnReplyWasLive(result) } rejectedRegistrationCandidate ??= result @@ -4282,7 +4781,10 @@ export function registerPtyHandlers( : result.wslDistro ) } catch (err) { - if ((isMintedSessionId || preparedProvisionalExecutionContext) && effectiveSessionAppId) { + if ( + (isNewDaemonSession || preparedProvisionalExecutionContext) && + effectiveSessionAppId + ) { runtime?.preparePtyExecutionContext?.(effectiveSessionAppId, null, { resetIncarnation: true }) @@ -4325,7 +4827,7 @@ export function registerPtyHandlers( store?.markSshRemotePtyLease(args.connectionId, effectiveSessionRelayId, 'expired') } } - if (isMintedSessionId && sessionId !== undefined) { + if (isNewDaemonSession && sessionId !== undefined) { clearProviderPtyState(sessionId) } throw spawnError @@ -4421,8 +4923,8 @@ export function registerPtyHandlers( } } catch (err) { console.error('[pty] failed to persist runtime PTY binding after spawn:', err) - deletePtyOwnership(result.id) if (!result.isReattach) { + deletePtyOwnership(result.id) try { await provider.shutdown(result.id, { immediate: true }) } catch (shutdownErr) { @@ -4436,7 +4938,7 @@ export function registerPtyHandlers( } persistSshLease() } - if (args.preAllocatedHandle) { + if (args.preAllocatedHandle && !stablePaneOwner?.handle) { runtime?.registerPreAllocatedHandleForPty(result.id, args.preAllocatedHandle) } if (args.worktreeId) { @@ -4464,11 +4966,13 @@ export function registerPtyHandlers( runtime?.cancelPendingPtyRegistration?.(result.id, result.incarnationId) } // Why: arms main's per-PTY Command Code output detector from the launch command (renderer startupCommand parity). - runtime?.noteTerminalSpawnCommand?.(result.id, launchCommand ?? null) - if (isClaudeLaunch) { + if (!stablePaneOwner) { + runtime?.noteTerminalSpawnCommand?.(result.id, launchCommand ?? null) + } + if (isClaudeLaunch && !stablePaneOwner) { markClaudePtySpawned(result.id) } - if (args.telemetry) { + if (args.telemetry && !stablePaneOwner) { const agentKindParse = agentKindSchema.safeParse(args.telemetry.agent_kind) const launchSourceParse = launchSourceSchema.safeParse(args.telemetry.launch_source) const requestKindParse = requestKindSchema.safeParse(args.telemetry.request_kind) @@ -4509,9 +5013,22 @@ export function registerPtyHandlers( const response = { id: result.id, ...(result.incarnationId ? { incarnationId: result.incarnationId } : {}), + ...(stablePaneOwner && (stablePaneOwner.handle || args.preAllocatedHandle) + ? { + stablePaneOwner: { + handle: stablePaneOwner.handle ?? args.preAllocatedHandle!, + tabId: stablePaneOwner.tabId, + leafId: stablePaneOwner.leafId + } + } + : {}), ...(result.agentSessionEnsure ? { agentSessionEnsure: result.agentSessionEnsure } : {}) } - return resolvePaneSpawnReservation(materializedPaneKey, paneSpawnReservation, response) + resolvePaneSpawnReservation(paneSpawnReservationKey, paneSpawnReservation, { + ...result, + isReattach: true + }) + return response } catch (err) { if (pendingRegistrationPtyId) { runtime?.cancelPendingPtyRegistration?.( @@ -4523,10 +5040,10 @@ export function registerPtyHandlers( // Why: once the reservation is created, any later throw — spawn // failure, persist failure, or a post-spawn helper such as // registerPty/rememberPaneKeyForPty/track — must settle it. Otherwise - // it lingers in paneSpawnReservationsByPaneKey and every future spawn + // it lingers in paneSpawnReservationsByOwnerKey and every future spawn // for this pane awaits a promise that never resolves. reject is a // no-op once the reservation has already resolved. - rejectPaneSpawnReservation(materializedPaneKey, paneSpawnReservation, err) + rejectPaneSpawnReservation(paneSpawnReservationKey, paneSpawnReservation, err) throw err } finally { releaseWorktreeSpawn?.() @@ -4929,7 +5446,6 @@ export function registerPtyHandlers( if (startupPromise) { await startupPromise } - await assertFolderWorkspacePtyPathUsable(args.worktreeId) // Why: honor the fallback only for fresh local spawns — reattach needs exact cwd and SSH can't probe the local filesystem. const allowMissingCwdFallback = !args.connectionId && !args.sessionId && args.cwdFallback === 'worktree' @@ -4949,411 +5465,512 @@ export function registerPtyHandlers( const startupCwdFallback = didFallbackToWorkspaceRootCwd && cwd ? ({ kind: 'worktree', cwd } as const) : undefined spawnTiming.mark('preflight') - const provider = getProvider(args.connectionId) - const isClaudeLaunch = !args.connectionId && isClaudeLaunchCommand(args.command) - if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) { - throw new Error('A Claude account switch is in progress. Try again after it finishes.') - } - const terminalRuntimeOptions = - process.platform === 'win32' && !args.connectionId - ? resolveLocalWindowsTerminalRuntimeOptions({ - requestedShellOverride: args.shellOverride, - settings: getSettings?.(), - projectRuntime: args.projectRuntime, - fallbackHostShell: process.env.COMSPEC || 'powershell.exe' - }) - : { shellOverride: args.shellOverride, terminalWindowsWslDistro: null } - const initialShellOverride = terminalRuntimeOptions.shellOverride - const isDaemonHostSpawn = - !args.connectionId && - !(provider instanceof LocalPtyProvider) && - !routesFreshSpawnsToLocalProvider(provider) - // Why: daemon host-env setup needs a stable id BEFORE provider.spawn so buildPtyHostEnv hooks/Pi cleanup can run; daemon still honors opts.sessionId ?? mint(). - // Note: sessionId is STABLE across daemon restarts by design — do NOT simplify to a fresh UUID per spawn; that orphans reconnectable state. - // Why: only clear ids minted in THIS request on failure — a caller-supplied args.sessionId may name an existing PTY we must not clobber. - const isMintedSessionId = args.sessionId === undefined && isDaemonHostSpawn - const effectiveSessionId = - args.sessionId ?? (isDaemonHostSpawn ? mintPtySessionId(args.worktreeId) : undefined) - const effectiveSessionAppId = - effectiveSessionId !== undefined - ? getAppPtyId(args.connectionId, effectiveSessionId) - : undefined - const effectiveSessionRelayId = - effectiveSessionId !== undefined - ? getRelayPtyId(args.connectionId, effectiveSessionId) - : undefined - const expectedWslDistro = !args.connectionId - ? (resolveWslSessionContext({ - cwd, - sessionId: effectiveSessionId, - shellOverride: terminalRuntimeOptions.shellOverride, - terminalWindowsWslDistro: terminalRuntimeOptions.terminalWindowsWslDistro - })?.distro ?? null) - : null - const initialSelectionTarget = getCodexSelectionTargetForPty( - initialShellOverride, - cwd, - expectedWslDistro - ) - const claudeAuth = - isClaudeLaunch && prepareClaudeAuth ? await prepareClaudeAuth(initialSelectionTarget) : null - spawnTiming.mark('auth') - if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) { - throw new Error('A Claude account switch is in progress. Try again after it finishes.') - } - if (claudeAuth?.stripAuthEnv && hasClaudeAuthEnvConflict(args.env)) { - throw new Error( - 'This Claude launch defines explicit Anthropic auth environment variables. Remove those overrides before using a managed Claude account.' - ) - } - // Why: the daemon-backed provider skips LocalPtyProvider's buildSpawnEnv, so assemble the same host-local env here for parity. - // Safety: skip entirely for SSH — every injection is a loopback secret or a local path that leaks or misleads on the remote host. - const startupTerminalColorQueryReplyColors = getStartupTerminalColorQueryReplyColors(args) - // Why: forward pane env to SSH only when the relay hook path is enabled, or a newer relay could emit statuses this build can't route. - const sshSourceEnv = stripRemotePaneEnvWhenHooksDisabled(args.connectionId, args.env) - const baseEnvWithAuth = claudeAuth - ? { ...sshSourceEnv, ...claudeAuth.envPatch } - : sshSourceEnv - const spawnPaneKey = baseEnvWithAuth?.ORCA_PANE_KEY - const parsedSpawnPaneKey = parseValidPaneKey(spawnPaneKey) - const verifiedPaneKey = - parsedSpawnPaneKey && - typeof args.tabId === 'string' && - args.tabId === parsedSpawnPaneKey.tabId && - args.leafId === parsedSpawnPaneKey.leafId - ? makePaneKey(parsedSpawnPaneKey.tabId, parsedSpawnPaneKey.leafId) - : null - const verifiedLeafId = - verifiedPaneKey && parsedSpawnPaneKey ? parsedSpawnPaneKey.leafId : null - const metadataLeafId = + const earlyLeafId = typeof args.leafId === 'string' && isTerminalLeafId(args.leafId) ? args.leafId : null - const metadataPaneKey = + const earlyPaneKey = + typeof args.worktreeId === 'string' && typeof args.tabId === 'string' && isValidTerminalTabId(args.tabId) && args.tabId.length <= 512 && - metadataLeafId - ? makePaneKey(args.tabId, metadataLeafId) + earlyLeafId + ? makePaneKey(args.tabId, earlyLeafId) : null - const legacySpawnPaneKey = verifiedPaneKey ? null : parseLegacyNumericPaneKey(spawnPaneKey) - const migrationUnsupportedPaneKey = - legacySpawnPaneKey && - typeof args.tabId === 'string' && - args.tabId === legacySpawnPaneKey.tabId && - typeof args.leafId === 'string' && - isTerminalLeafId(args.leafId) - ? makePaneKey(args.tabId, args.leafId) - : null - const stablePaneKey = verifiedPaneKey ?? migrationUnsupportedPaneKey - let baseEnv = baseEnvWithAuth ? { ...baseEnvWithAuth } : undefined - const shouldRefreshAgentTeamsEnv = - !args.connectionId && - runtime !== undefined && - stablePaneKey !== null && - shouldRefreshNativeClaudeAgentTeamsEnv({ - command: args.command, - launchConfig: args.launchConfig - }) - let effectiveLaunchConfig = args.launchConfig - const shouldPreAllocateTerminalHandle = - runtime !== undefined && - ((!(provider instanceof LocalPtyProvider) && !routesFreshSpawnsToLocalProvider(provider)) || - shouldRefreshAgentTeamsEnv) - const preAllocatedHandle = shouldPreAllocateTerminalHandle - ? runtime.createPreAllocatedTerminalHandle() - : null - if (shouldRefreshAgentTeamsEnv && preAllocatedHandle) { - // Why: Agent Teams ids/tokens are process-local, so the team env must be regenerated for the new leader PTY. - const prepared = await runtime.prepareClaudeAgentTeamsLeaderForHandle({ - handle: preAllocatedHandle, - baseEnv: baseEnv ?? {} - }) - baseEnv = { - ...baseEnv, - ...prepared.env - } - if (args.launchConfig) { - effectiveLaunchConfig = { - ...args.launchConfig, - agentEnv: { - ...args.launchConfig.agentEnv, - ...prepared.env - } - } - } - } - const requestedAgentTeamsPath = baseEnv?.ORCA_AGENT_TEAMS_TEAM_ID ? baseEnv.PATH : undefined - const agentTeamsEnvToDelete = shouldRefreshAgentTeamsEnv - ? ['TERM_PROGRAM', 'ORCA_ATTRIBUTION_SHIM_DIR'] + const earlyReservationKey = makePaneSpawnReservationKey( + args.worktreeId, + args.connectionId, + earlyPaneKey + ) + const pendingRuntimeCreate = earlyReservationKey + ? pendingRuntimePaneCreatesByOwnerKey.get(earlyReservationKey) : undefined - if (baseEnv && stablePaneKey) { - baseEnv.ORCA_PANE_KEY = stablePaneKey - if (typeof args.tabId === 'string') { - baseEnv.ORCA_TAB_ID = args.tabId - } else if (!args.connectionId) { - delete baseEnv.ORCA_TAB_ID - } - if (typeof args.worktreeId === 'string') { - baseEnv.ORCA_WORKTREE_ID = args.worktreeId - } else if (!args.connectionId) { - delete baseEnv.ORCA_WORKTREE_ID - } - } else if (baseEnv) { - // Why: ORCA_PANE_KEY crosses into shells/hook registries; only a key proven to match this spawn's tab+leaf may cross the IPC boundary. - delete baseEnv.ORCA_PANE_KEY - delete baseEnv.ORCA_TAB_ID - delete baseEnv.ORCA_WORKTREE_ID - delete baseEnv.ORCA_AGENT_LAUNCH_TOKEN + if (pendingRuntimeCreate) { + await pendingRuntimeCreate.promise } - const validatedPaneKey = stablePaneKey - // Why: SSH can strip ORCA_PANE_KEY when remote hooks are off; IPC tab/leaf metadata still names the pane. - const reservationPaneKey = metadataPaneKey ?? validatedPaneKey - const validatedLeafId = verifiedLeafId ?? metadataLeafId - const effectiveShellOverride = terminalRuntimeOptions.shellOverride - const nativeWindowsConptySpawn = isNativeWindowsLocalPtySpawn({ - connectionId: args.connectionId, - cwd: args.cwd, - shellOverride: effectiveShellOverride - }) - const codexSelectionTarget = getCodexSelectionTargetForPty( - effectiveShellOverride, - cwd, - expectedWslDistro - ) - const codexResumePreparation = prepareCodexResumeHome({ - connectionId: args.connectionId, - launchAgent: args.launchAgent, - providerSession: args.resumeProviderSession, - target: codexSelectionTarget, - launchEnv: baseEnv, - workspacePath: cwd - }) - const codexResumeLaunch = codexResumePreparation - ? await resolveCodexResumeLaunch(args.command, codexResumePreparation) - : noCodexResumeLaunch(args.command) - const codexResumeHome = codexResumeLaunch.codexResumeHome - const launchCommand = codexResumeLaunch.command - baseEnv = stripSequencedStartupResumeArgv(baseEnv, codexResumeLaunch) - // Why: declared after the strip so a local-provider spawn cannot capture the - // pre-strip env — only the daemon branch below re-derives this from baseEnv. - let env: Record | undefined = baseEnv - let selectedCodexHomePath = !args.connectionId - ? getCompatibleSelectedCodexHomePath( - codexSelectionTarget, - codexResumeHome - ? codexResumeHome.codexHomePath - : (getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { - workspacePath: cwd, - launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined - }) ?? null) - ) - : null - if (args.launchAgent === 'codex' && args.sessionId === undefined) { - const resolution = resolveCodexHomeAfterManagedAuthReadiness({ - selectedCodexHomePath, - getSettings: () => getSettings?.(), - requiredCodexHomePath: codexResumeHome?.codexHomePath, - target: codexSelectionTarget, - resolveCurrent: () => - getCompatibleSelectedCodexHomePath( - codexSelectionTarget, - getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { - workspacePath: cwd, - launchAgent: 'codex' - }) ?? null - ), - resolveAfterUnavailable: (unavailableManagedHomePath) => - getCompatibleSelectedCodexHomePath( - codexSelectionTarget, - getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { - workspacePath: cwd, - launchAgent: 'codex', - unavailableManagedHomePath - }) ?? null - ) - }) - selectedCodexHomePath = resolution instanceof Promise ? await resolution : resolution - } - const codexResumeHomeSelected = Boolean( - codexResumeHome && codexHomePathsEqual(selectedCodexHomePath, codexResumeHome.codexHomePath) - ) - const skipCodexHomeEnv = - isDaemonHostSpawn && - shouldSkipCodexHomeEnvForWindowsShell(effectiveShellOverride, cwd) && - !selectedCodexHomePath - const stripInheritedOrcaCodexHome = - isDaemonHostSpawn && - shouldStripInheritedOrcaCodexHome({ - target: codexSelectionTarget, - selectedCodexHomePath, - skipCodexHomeEnv, - settings: getSettings?.() - }) - if (isDaemonHostSpawn) { - if (effectiveSessionId === undefined) { - // Should be unreachable: effectiveSessionId is a string when isDaemonHostSpawn; defense-in-depth. - throw new Error('Invariant violation: daemon spawn without sessionId') - } - const sessionIdForEnv = effectiveSessionId - // Why: this id reaches filesystem paths; reject traversal/separators so a crafted IPC payload can't escape the expected roots. - if (!isSafePtySessionId(sessionIdForEnv, app.getPath('userData'))) { - throw new Error('Invalid PTY session id') - } - // Why: clone before mutating so injections don't leak back into args.env (renderer may reuse it). - env = { ...baseEnv } - try { - buildPtyHostEnv(sessionIdForEnv, env, { - isPackaged: app.isPackaged, - userDataPath: app.getPath('userData'), - selectedCodexHomePath, - skipCodexHomeEnv, - stripInheritedOrcaCodexHome, - githubAttributionEnabled: getSettings?.()?.enableGitHubAttribution ?? false, - launchCommand, - launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined, - shellPath: effectiveShellOverride ?? process.env.COMSPEC, - isWsl: shouldSkipCodexHomeEnvForWindowsShell(effectiveShellOverride, cwd), - wslDistro: codexSelectionTarget.runtime === 'wsl' ? expectedWslDistro : null, - agentStatusHooksEnabled: isAgentStatusHooksEnabled(getSettings?.()), - networkProxySettings: getSettings?.(), - deferGitConfigGuardToDaemon: - provider.supportsGitCredentialGuardHost?.(effectiveSessionId) === true - }) - stampWslOrchestrationCompatibilityHost( - env, - runtime?.getOrchestrationCompatibilityHostId?.(), - codexSelectionTarget.runtime === 'wsl' ? expectedWslDistro : null - ) - promoteAgentTeamsShimPath(env, requestedAgentTeamsPath) - } catch (err) { - // Why: buildPtyHostEnv has fs side-effects (Pi/OMP install); clear per-PTY state on throw, but only minted ids — caller ids may name existing PTYs. - if (isMintedSessionId) { - clearProviderPtyState(sessionIdForEnv) - } - throw err - } - } - spawnTiming.mark('host_env') - const spawnEnv = preAllocatedHandle - ? { ...env, ORCA_TERMINAL_HANDLE: preAllocatedHandle } - : env - const envToDelete = claudeAuth?.stripAuthEnv - ? [...CLAUDE_AUTH_ENV_VARS, 'ANTHROPIC_CUSTOM_HEADERS'] - : undefined - let combinedEnvToDelete = mergePtyEnvDeletions( - envToDelete, - args.envToDelete ?? [], - agentTeamsEnvToDelete ?? [], - isDaemonHostSpawn ? getInheritedAgentHookEnvKeysToDelete(spawnEnv) : [], - getInheritedClaudeSessionStampEnvKeysToDelete(spawnEnv), - skipCodexHomeEnv ? CODEX_HOME_ENV_KEYS : [], - // Why: the persistent daemon compares its own merged CODEX_HOME pair; - // main cannot safely decide ownership for a process it may not parent. - stripInheritedOrcaCodexHome ? ['ORCA_CODEX_HOME'] : [] - ) - if (codexResumeHomeSelected) { - combinedEnvToDelete = removeCodexHomeDeletionRequests(combinedEnvToDelete) - } - deleteRequestedEnvKeys(spawnEnv, combinedEnvToDelete) - promoteAgentTeamsShimPath(spawnEnv, requestedAgentTeamsPath) - const spawnOptions: PtySpawnOptions = { - cols: args.cols, - rows: args.rows, - cwd, - env: spawnEnv, - ...(isMintedSessionId ? { isNewSession: true } : {}) - } - if (!args.connectionId && !isDaemonHostSpawn) { - spawnOptions.codexHomePathOverride = { value: selectedCodexHomePath } - } - if (combinedEnvToDelete) { - spawnOptions.envToDelete = combinedEnvToDelete - } - if (launchCommand !== undefined) { - spawnOptions.command = launchCommand - } - if (args.commandDelivery !== undefined) { - spawnOptions.commandDelivery = args.commandDelivery - } - if (args.startupCommandDelivery !== undefined) { - spawnOptions.startupCommandDelivery = args.startupCommandDelivery - } - if (isTuiAgent(args.launchAgent)) { - spawnOptions.launchAgent = args.launchAgent - } - if (args.worktreeId !== undefined) { - spawnOptions.worktreeId = args.worktreeId - } - if (reservationPaneKey) { - spawnOptions.paneKey = reservationPaneKey - } - if (typeof args.tabId === 'string' && args.tabId.length > 0 && args.tabId.length <= 512) { - spawnOptions.tabId = args.tabId - } - if (effectiveSessionId !== undefined) { - spawnOptions.sessionId = effectiveSessionId - } - // Why: without this, the Windows daemon path ignores the user's Default Shell preference (LocalPtyProvider already honors it via getWindowsShell()). - if (effectiveShellOverride !== undefined) { - spawnOptions.shellOverride = effectiveShellOverride - } - const hadSessionSizeBeforeAttach = - effectiveSessionAppId !== undefined ? ptySizes.has(effectiveSessionAppId) : false - const sessionSizeBeforeAttach = - effectiveSessionAppId !== undefined ? ptySizes.get(effectiveSessionAppId) : undefined - if (effectiveSessionId !== undefined) { - // Why: daemon PTYs can emit before spawn() resolves; set real geometry now or early bytes default to 80x24 and wrap TUIs. - ptySizes.set(effectiveSessionAppId ?? effectiveSessionId, { - cols: args.cols, - rows: args.rows - }) - } - if (process.platform === 'win32' && !args.connectionId) { - // Why: the renderer models PowerShell as one shell family; thread the implementation choice so both PTY paths resolve the same executable. - spawnOptions.terminalWindowsWslDistro = expectedWslDistro - spawnOptions.terminalWindowsPowerShellImplementation = getSettings - ? (getSettings()?.terminalWindowsPowerShellImplementation ?? 'auto') - : undefined - } - if (startupTerminalColorQueryReplyColors) { - spawnOptions.startupIngress = { - colors: startupTerminalColorQueryReplyColors, - deadlineMs: 5_000 - } - } - const existingPaneSpawn = reservationPaneKey - ? paneSpawnReservationsByPaneKey.get(reservationPaneKey) + const existingPaneSpawn = earlyReservationKey + ? paneSpawnReservationsByOwnerKey.get(earlyReservationKey) : undefined if (existingPaneSpawn) { - return await existingPaneSpawn.promise + return { ...(await existingPaneSpawn.promise), isReattach: true } } - const finishTerminalInstall = beginPtySpawnForWorktree( - args.worktreeId, - cwd, - args.connectionId - ) - const paneSpawnReservation = reservationPaneKey ? reservePaneSpawn(reservationPaneKey) : null - const initiallyHidden = args.initiallyHidden === true - // Why: daemon PTYs can emit before spawn() resolves, so the hidden mark must beat byte zero (terminal-query-authority.md §races); other providers are safe with the post-spawn mark below. - const preSpawnHiddenMarkId = - initiallyHidden && isDaemonHostSpawn && effectiveSessionAppId !== undefined - ? effectiveSessionAppId + const earlyStablePaneOwner = + earlyPaneKey && args.worktreeId + ? resolveStablePaneOwner(runtime, store, earlyPaneKey, args.worktreeId, args.connectionId) : null - if (preSpawnHiddenMarkId !== null) { - transitionSpawnHiddenRendererPtyDeliveryState(preSpawnHiddenMarkId, true) - } + const earlyWorktreeId = args.worktreeId + let paneSpawnReservationKey = + earlyStablePaneOwner && earlyReservationKey ? earlyReservationKey : null + let paneSpawnReservation = paneSpawnReservationKey + ? reservePaneSpawn(paneSpawnReservationKey) + : null + let finishTerminalInstall = (): void => {} let result: PtySpawnResult + let stablePaneOwner: StablePaneOwner | null = null let rejectedRegistrationCandidate: PtySpawnResult | null = null let pendingRegistrationPtyId: string | null = null let preparedProvisionalExecutionContext = false let releaseWorktreeSpawn: (() => void) | undefined try { + if (!earlyStablePaneOwner) { + await assertFolderWorkspacePtyPathUsable(args.worktreeId) + } + const provider = getProvider(args.connectionId) + const preAdoptedStablePane = + earlyStablePaneOwner && earlyWorktreeId + ? await adoptStablePane({ + cols: args.cols, + rows: args.rows, + cwd, + connectionId: args.connectionId, + worktreeId: earlyWorktreeId, + tabId: earlyStablePaneOwner.tabId, + leafId: earlyStablePaneOwner.leafId, + ownsPaneSpawnReservation: true + }) + : null + if (earlyStablePaneOwner && !preAdoptedStablePane) { + await assertFolderWorkspacePtyPathUsable(args.worktreeId) + } + const freshSpawnRecovery = preAdoptedStablePane + ? undefined + : recoverFreshSpawnProviderRouting(provider, args.connectionId, args.sessionId) + if (freshSpawnRecovery) { + await freshSpawnRecovery + } + const isClaudeLaunch = + !preAdoptedStablePane && !args.connectionId && isClaudeLaunchCommand(args.command) + if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) { + throw new Error('A Claude account switch is in progress. Try again after it finishes.') + } + const terminalRuntimeOptions = + process.platform === 'win32' && !args.connectionId + ? resolveLocalWindowsTerminalRuntimeOptions({ + requestedShellOverride: args.shellOverride, + settings: getSettings?.(), + projectRuntime: args.projectRuntime, + fallbackHostShell: process.env.COMSPEC || 'powershell.exe' + }) + : { shellOverride: args.shellOverride, terminalWindowsWslDistro: null } + const initialShellOverride = terminalRuntimeOptions.shellOverride + const isDaemonHostSpawn = + !args.connectionId && + !(provider instanceof LocalPtyProvider) && + !routesFreshSpawnsToLocalProvider(provider) + // Why: daemon host-env setup needs a stable id BEFORE provider.spawn so buildPtyHostEnv hooks/Pi cleanup can run; daemon still honors opts.sessionId ?? mint(). + // Note: sessionId is STABLE across daemon restarts by design — do NOT simplify to a fresh UUID per spawn; that orphans reconnectable state. + // Why: only clear ids minted in THIS request on failure — a caller-supplied args.sessionId may name an existing PTY we must not clobber. + const isMintedSessionId = args.sessionId === undefined && isDaemonHostSpawn + const effectiveSessionId = + args.sessionId ?? (isDaemonHostSpawn ? mintPtySessionId(args.worktreeId) : undefined) + const effectiveSessionAppId = + effectiveSessionId !== undefined + ? getAppPtyId(args.connectionId, effectiveSessionId) + : undefined + const effectiveSessionRelayId = + effectiveSessionId !== undefined + ? getRelayPtyId(args.connectionId, effectiveSessionId) + : undefined + const expectedWslDistro = !args.connectionId + ? (resolveWslSessionContext({ + cwd, + sessionId: effectiveSessionId, + shellOverride: terminalRuntimeOptions.shellOverride, + terminalWindowsWslDistro: terminalRuntimeOptions.terminalWindowsWslDistro + })?.distro ?? null) + : null + const initialSelectionTarget = getCodexSelectionTargetForPty( + initialShellOverride, + cwd, + expectedWslDistro + ) + const claudeAuth = + isClaudeLaunch && prepareClaudeAuth + ? await prepareClaudeAuth(initialSelectionTarget) + : null + spawnTiming.mark('auth') + if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) { + throw new Error('A Claude account switch is in progress. Try again after it finishes.') + } + if (claudeAuth?.stripAuthEnv && hasClaudeAuthEnvConflict(args.env)) { + throw new Error( + 'This Claude launch defines explicit Anthropic auth environment variables. Remove those overrides before using a managed Claude account.' + ) + } + // Why: the daemon-backed provider skips LocalPtyProvider's buildSpawnEnv, so assemble the same host-local env here for parity. + // Safety: skip entirely for SSH — every injection is a loopback secret or a local path that leaks or misleads on the remote host. + const startupTerminalColorQueryReplyColors = getStartupTerminalColorQueryReplyColors(args) + // Why: forward pane env to SSH only when the relay hook path is enabled, or a newer relay could emit statuses this build can't route. + const sshSourceEnv = stripRemotePaneEnvWhenHooksDisabled(args.connectionId, args.env) + const baseEnvWithAuth = claudeAuth + ? { ...sshSourceEnv, ...claudeAuth.envPatch } + : sshSourceEnv + const spawnPaneKey = baseEnvWithAuth?.ORCA_PANE_KEY + const parsedSpawnPaneKey = parseValidPaneKey(spawnPaneKey) + const verifiedPaneKey = + parsedSpawnPaneKey && + typeof args.tabId === 'string' && + args.tabId === parsedSpawnPaneKey.tabId && + args.leafId === parsedSpawnPaneKey.leafId + ? makePaneKey(parsedSpawnPaneKey.tabId, parsedSpawnPaneKey.leafId) + : null + const verifiedLeafId = + verifiedPaneKey && parsedSpawnPaneKey ? parsedSpawnPaneKey.leafId : null + const metadataLeafId = + typeof args.leafId === 'string' && isTerminalLeafId(args.leafId) ? args.leafId : null + const metadataPaneKey = + typeof args.tabId === 'string' && + isValidTerminalTabId(args.tabId) && + args.tabId.length <= 512 && + metadataLeafId + ? makePaneKey(args.tabId, metadataLeafId) + : null + const legacySpawnPaneKey = verifiedPaneKey ? null : parseLegacyNumericPaneKey(spawnPaneKey) + const migrationUnsupportedPaneKey = + legacySpawnPaneKey && + typeof args.tabId === 'string' && + args.tabId === legacySpawnPaneKey.tabId && + typeof args.leafId === 'string' && + isTerminalLeafId(args.leafId) + ? makePaneKey(args.tabId, args.leafId) + : null + const stablePaneKey = verifiedPaneKey ?? migrationUnsupportedPaneKey + let baseEnv = baseEnvWithAuth ? { ...baseEnvWithAuth } : undefined + const shouldRefreshAgentTeamsEnv = + !preAdoptedStablePane && + !args.connectionId && + runtime !== undefined && + stablePaneKey !== null && + shouldRefreshNativeClaudeAgentTeamsEnv({ + command: args.command, + launchConfig: args.launchConfig + }) + let effectiveLaunchConfig = args.launchConfig + const shouldPreAllocateTerminalHandle = + runtime !== undefined && + ((!(provider instanceof LocalPtyProvider) && + !routesFreshSpawnsToLocalProvider(provider)) || + shouldRefreshAgentTeamsEnv) + const preAllocatedHandle = shouldPreAllocateTerminalHandle + ? (preAdoptedStablePane?.owner.handle ?? runtime.createPreAllocatedTerminalHandle()) + : null + if (shouldRefreshAgentTeamsEnv && preAllocatedHandle) { + // Why: Agent Teams ids/tokens are process-local, so the team env must be regenerated for the new leader PTY. + const prepared = await runtime.prepareClaudeAgentTeamsLeaderForHandle({ + handle: preAllocatedHandle, + baseEnv: baseEnv ?? {} + }) + baseEnv = { + ...baseEnv, + ...prepared.env + } + if (args.launchConfig) { + effectiveLaunchConfig = { + ...args.launchConfig, + agentEnv: { + ...args.launchConfig.agentEnv, + ...prepared.env + } + } + } + } + const requestedAgentTeamsPath = baseEnv?.ORCA_AGENT_TEAMS_TEAM_ID + ? baseEnv[resolvePathEnvKey(baseEnv, process.platform)] + : undefined + const agentTeamsEnvToDelete = shouldRefreshAgentTeamsEnv + ? ['TERM_PROGRAM', 'ORCA_ATTRIBUTION_SHIM_DIR'] + : undefined + if (baseEnv && stablePaneKey) { + baseEnv.ORCA_PANE_KEY = stablePaneKey + if (typeof args.tabId === 'string') { + baseEnv.ORCA_TAB_ID = args.tabId + } else if (!args.connectionId) { + delete baseEnv.ORCA_TAB_ID + } + if (typeof args.worktreeId === 'string') { + baseEnv.ORCA_WORKTREE_ID = args.worktreeId + } else if (!args.connectionId) { + delete baseEnv.ORCA_WORKTREE_ID + } + } else if (baseEnv) { + // Why: ORCA_PANE_KEY crosses into shells/hook registries; only a key proven to match this spawn's tab+leaf may cross the IPC boundary. + delete baseEnv.ORCA_PANE_KEY + delete baseEnv.ORCA_TAB_ID + delete baseEnv.ORCA_WORKTREE_ID + delete baseEnv.ORCA_AGENT_LAUNCH_TOKEN + } + const validatedPaneKey = stablePaneKey + // Why: SSH can strip ORCA_PANE_KEY when remote hooks are off; IPC tab/leaf metadata still names the pane. + const reservationPaneKey = metadataPaneKey ?? validatedPaneKey + const validatedLeafId = verifiedLeafId ?? metadataLeafId + const effectiveShellOverride = terminalRuntimeOptions.shellOverride + const nativeWindowsConptySpawn = isNativeWindowsLocalPtySpawn({ + connectionId: args.connectionId, + cwd: args.cwd, + shellOverride: effectiveShellOverride + }) + const codexSelectionTarget = getCodexSelectionTargetForPty( + effectiveShellOverride, + cwd, + expectedWslDistro + ) + const codexResumePreparation = preAdoptedStablePane + ? null + : prepareCodexResumeHome({ + connectionId: args.connectionId, + launchAgent: args.launchAgent, + providerSession: args.resumeProviderSession, + target: codexSelectionTarget, + launchEnv: baseEnv, + workspacePath: cwd + }) + const codexResumeLaunch = codexResumePreparation + ? await resolveCodexResumeLaunch(args.command, codexResumePreparation) + : noCodexResumeLaunch(preAdoptedStablePane ? undefined : args.command) + const codexResumeHome = codexResumeLaunch.codexResumeHome + const launchCommand = codexResumeLaunch.command + baseEnv = stripSequencedStartupResumeArgv(baseEnv, codexResumeLaunch) + // Why: declared after the strip so a local-provider spawn cannot capture the + // pre-strip env — only the daemon branch below re-derives this from baseEnv. + let env: Record | undefined = baseEnv + let selectedCodexHomePath = + !preAdoptedStablePane && !args.connectionId + ? getCompatibleSelectedCodexHomePath( + codexSelectionTarget, + codexResumeHome + ? codexResumeHome.codexHomePath + : (getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { + workspacePath: cwd, + launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined + }) ?? null) + ) + : null + if (!preAdoptedStablePane && args.launchAgent === 'codex' && args.sessionId === undefined) { + const resolution = resolveCodexHomeAfterManagedAuthReadiness({ + selectedCodexHomePath, + getSettings: () => getSettings?.(), + requiredCodexHomePath: codexResumeHome?.codexHomePath, + target: codexSelectionTarget, + resolveCurrent: () => + getCompatibleSelectedCodexHomePath( + codexSelectionTarget, + getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { + workspacePath: cwd, + launchAgent: 'codex' + }) ?? null + ), + resolveAfterUnavailable: (unavailableManagedHomePath) => + getCompatibleSelectedCodexHomePath( + codexSelectionTarget, + getSelectedCodexHomePath?.(codexSelectionTarget, baseEnv, { + workspacePath: cwd, + launchAgent: 'codex', + unavailableManagedHomePath + }) ?? null + ) + }) + selectedCodexHomePath = resolution instanceof Promise ? await resolution : resolution + } + const codexResumeHomeSelected = Boolean( + codexResumeHome && + codexHomePathsEqual(selectedCodexHomePath, codexResumeHome.codexHomePath) + ) + const skipCodexHomeEnv = + isDaemonHostSpawn && + shouldSkipCodexHomeEnvForWindowsShell(effectiveShellOverride, cwd) && + !selectedCodexHomePath + const stripInheritedOrcaCodexHome = + isDaemonHostSpawn && + shouldStripInheritedOrcaCodexHome({ + target: codexSelectionTarget, + selectedCodexHomePath, + skipCodexHomeEnv, + settings: getSettings?.() + }) + if (isDaemonHostSpawn && !preAdoptedStablePane) { + if (effectiveSessionId === undefined) { + // Should be unreachable: effectiveSessionId is a string when isDaemonHostSpawn; defense-in-depth. + throw new Error('Invariant violation: daemon spawn without sessionId') + } + const sessionIdForEnv = effectiveSessionId + // Why: this id reaches filesystem paths; reject traversal/separators so a crafted IPC payload can't escape the expected roots. + if (!isSafePtySessionId(sessionIdForEnv, app.getPath('userData'))) { + throw new Error('Invalid PTY session id') + } + // Why: clone before mutating so injections don't leak back into args.env (renderer may reuse it). + env = { ...baseEnv } + try { + buildPtyHostEnv(sessionIdForEnv, env, { + isPackaged: app.isPackaged, + userDataPath: app.getPath('userData'), + selectedCodexHomePath, + skipCodexHomeEnv, + stripInheritedOrcaCodexHome, + githubAttributionEnabled: getSettings?.()?.enableGitHubAttribution ?? false, + launchCommand, + launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined, + shellPath: effectiveShellOverride ?? process.env.COMSPEC, + isWsl: shouldSkipCodexHomeEnvForWindowsShell(effectiveShellOverride, cwd), + wslDistro: codexSelectionTarget.runtime === 'wsl' ? expectedWslDistro : null, + agentStatusHooksEnabled: isAgentStatusHooksEnabled(getSettings?.()), + networkProxySettings: getSettings?.(), + deferGitConfigGuardToDaemon: + provider.supportsGitCredentialGuardHost?.(effectiveSessionId) === true + }) + stampWslOrchestrationCompatibilityHost( + env, + runtime?.getOrchestrationCompatibilityHostId?.(), + codexSelectionTarget.runtime === 'wsl' ? expectedWslDistro : null + ) + promoteAgentTeamsShimPath(env, requestedAgentTeamsPath) + } catch (err) { + // Why: buildPtyHostEnv has fs side-effects (Pi/OMP install); clear per-PTY state on throw, but only minted ids — caller ids may name existing PTYs. + if (isMintedSessionId) { + clearProviderPtyState(sessionIdForEnv) + } + throw err + } + } + spawnTiming.mark('host_env') + const spawnEnv = preAllocatedHandle + ? { ...env, ORCA_TERMINAL_HANDLE: preAllocatedHandle } + : env + const envToDelete = claudeAuth?.stripAuthEnv + ? [...CLAUDE_AUTH_ENV_VARS, 'ANTHROPIC_CUSTOM_HEADERS'] + : undefined + let combinedEnvToDelete = mergePtyEnvDeletions( + envToDelete, + args.envToDelete ?? [], + agentTeamsEnvToDelete ?? [], + isDaemonHostSpawn ? getInheritedAgentHookEnvKeysToDelete(spawnEnv) : [], + getInheritedClaudeSessionStampEnvKeysToDelete(spawnEnv), + skipCodexHomeEnv ? CODEX_HOME_ENV_KEYS : [], + // Why: the persistent daemon compares its own merged CODEX_HOME pair; + // main cannot safely decide ownership for a process it may not parent. + stripInheritedOrcaCodexHome ? ['ORCA_CODEX_HOME'] : [] + ) + if (codexResumeHomeSelected) { + combinedEnvToDelete = removeCodexHomeDeletionRequests(combinedEnvToDelete) + } + deleteRequestedEnvKeys(spawnEnv, combinedEnvToDelete) + promoteAgentTeamsShimPath(spawnEnv, requestedAgentTeamsPath) + const spawnOptions: PtySpawnOptions = { + cols: args.cols, + rows: args.rows, + cwd, + env: spawnEnv, + ...(isMintedSessionId ? { isNewSession: true } : {}) + } + if (!args.connectionId && !isDaemonHostSpawn) { + spawnOptions.codexHomePathOverride = { value: selectedCodexHomePath } + } + if (combinedEnvToDelete) { + spawnOptions.envToDelete = combinedEnvToDelete + } + if (launchCommand !== undefined) { + spawnOptions.command = launchCommand + } + if (args.commandDelivery !== undefined) { + spawnOptions.commandDelivery = args.commandDelivery + } + if (args.startupCommandDelivery !== undefined) { + spawnOptions.startupCommandDelivery = args.startupCommandDelivery + } + if (isTuiAgent(args.launchAgent)) { + spawnOptions.launchAgent = args.launchAgent + } + if (args.worktreeId !== undefined) { + spawnOptions.worktreeId = args.worktreeId + } + if (reservationPaneKey) { + spawnOptions.paneKey = reservationPaneKey + } + if (typeof args.tabId === 'string' && args.tabId.length > 0 && args.tabId.length <= 512) { + spawnOptions.tabId = args.tabId + } + if (effectiveSessionId !== undefined) { + spawnOptions.sessionId = effectiveSessionId + } + // Why: without this, the Windows daemon path ignores the user's Default Shell preference (LocalPtyProvider already honors it via getWindowsShell()). + if (effectiveShellOverride !== undefined) { + spawnOptions.shellOverride = effectiveShellOverride + } + const hadSessionSizeBeforeAttach = + effectiveSessionAppId !== undefined ? ptySizes.has(effectiveSessionAppId) : false + const sessionSizeBeforeAttach = + effectiveSessionAppId !== undefined ? ptySizes.get(effectiveSessionAppId) : undefined + if (effectiveSessionId !== undefined) { + // Why: daemon PTYs can emit before spawn() resolves; set real geometry now or early bytes default to 80x24 and wrap TUIs. + ptySizes.set(effectiveSessionAppId ?? effectiveSessionId, { + cols: args.cols, + rows: args.rows + }) + } + if (process.platform === 'win32' && !args.connectionId) { + // Why: the renderer models PowerShell as one shell family; thread the implementation choice so both PTY paths resolve the same executable. + spawnOptions.terminalWindowsWslDistro = expectedWslDistro + spawnOptions.terminalWindowsPowerShellImplementation = getSettings + ? (getSettings()?.terminalWindowsPowerShellImplementation ?? 'auto') + : undefined + } + if (startupTerminalColorQueryReplyColors) { + spawnOptions.startupIngress = { + colors: startupTerminalColorQueryReplyColors, + deadlineMs: 5_000 + } + } + const resolvedPaneSpawnReservationKey = makePaneSpawnReservationKey( + args.worktreeId, + args.connectionId, + reservationPaneKey + ) + if ( + paneSpawnReservationKey && + resolvedPaneSpawnReservationKey !== paneSpawnReservationKey + ) { + throw new Error('terminal_pane_identity_changed') + } + if (!paneSpawnReservationKey) { + paneSpawnReservationKey = resolvedPaneSpawnReservationKey + const pendingRuntimeCreateAfterPreflight = paneSpawnReservationKey + ? pendingRuntimePaneCreatesByOwnerKey.get(paneSpawnReservationKey) + : undefined + if (pendingRuntimeCreateAfterPreflight) { + await pendingRuntimeCreateAfterPreflight.promise + } + const existingPaneSpawnAfterPreflight = paneSpawnReservationKey + ? paneSpawnReservationsByOwnerKey.get(paneSpawnReservationKey) + : undefined + if (existingPaneSpawnAfterPreflight) { + return { ...(await existingPaneSpawnAfterPreflight.promise), isReattach: true } + } + paneSpawnReservation = paneSpawnReservationKey + ? reservePaneSpawn(paneSpawnReservationKey) + : null + } + finishTerminalInstall = beginPtySpawnForWorktree(args.worktreeId, cwd, args.connectionId) + const initiallyHidden = args.initiallyHidden === true + // Why: daemon PTYs can emit before spawn() resolves, so the hidden mark must beat byte zero (terminal-query-authority.md §races); other providers are safe with the post-spawn mark below. + const preSpawnHiddenMarkId = + initiallyHidden && isDaemonHostSpawn && effectiveSessionAppId !== undefined + ? effectiveSessionAppId + : null + if (preSpawnHiddenMarkId !== null) { + transitionSpawnHiddenRendererPtyDeliveryState(preSpawnHiddenMarkId, true) + } releaseWorktreeSpawn = await runtime?.acquireWorktreeTerminalSpawn?.(args.worktreeId) try { if (preAllocatedHandle) { trustedTerminalHandleEnv.add(preAllocatedHandle) } spawnTiming.mark('options') - const expectedPtyId = effectiveSessionAppId ?? effectiveSessionId + const stablePaneOwnerCandidate = resolveStablePaneOwner( + runtime, + store, + reservationPaneKey, + args.worktreeId, + args.connectionId + ) + const expectedPtyId = + stablePaneOwnerCandidate?.ptyId ?? effectiveSessionAppId ?? effectiveSessionId if (expectedPtyId) { runtime?.beginPtyRegistration?.(expectedPtyId) pendingRegistrationPtyId = expectedPtyId @@ -5361,14 +5978,42 @@ export function registerPtyHandlers( if (isDaemonHostSpawn && expectedPtyId) { preparedProvisionalExecutionContext = runtime?.preparePtyExecutionContext?.(expectedPtyId, expectedWslDistro, { - resetIncarnation: isMintedSessionId, - preserveExisting: !isMintedSessionId + resetIncarnation: isMintedSessionId && !stablePaneOwnerCandidate, + preserveExisting: !isMintedSessionId || Boolean(stablePaneOwnerCandidate) }) ?? false } const sequenceBeforeProviderSpawn = expectedPtyId ? (runtime?.getPtyOutputSequence?.(expectedPtyId) ?? 0) : 0 - result = await provider.spawn(spawnOptions) + const stablePaneSpawn = preAdoptedStablePane + ? preAdoptedStablePane + : await spawnForStablePane({ + runtime, + store, + provider, + spawnOptions, + owner: stablePaneOwnerCandidate, + worktreeId: args.worktreeId, + connectionId: args.connectionId, + resolveOwner: () => + resolveStablePaneOwner( + runtime, + store, + reservationPaneKey, + args.worktreeId, + args.connectionId + ) + }) + result = stablePaneSpawn.result + stablePaneOwner = stablePaneSpawn.owner + if ( + stablePaneOwner && + isMintedSessionId && + effectiveSessionAppId && + effectiveSessionAppId !== result.id + ) { + clearProviderPtyState(effectiveSessionAppId) + } rejectedRegistrationCandidate = result if (pendingRegistrationPtyId !== result.id) { if (pendingRegistrationPtyId) { @@ -5518,10 +6163,13 @@ export function registerPtyHandlers( lastAttachedAt: Date.now() }) } - if (preAllocatedHandle) { + if (preAllocatedHandle && !stablePaneOwner?.handle) { runtime?.registerPreAllocatedHandleForPty(result.id, preAllocatedHandle) } ptySizes.set(result.id, { cols: args.cols, rows: args.rows }) + if (effectiveSessionAppId !== undefined && effectiveSessionAppId !== result.id) { + ptySizes.delete(effectiveSessionAppId) + } // Why: patch the load-bearing ptyId binding synchronously so a force-quit in the renderer's ~450 ms debounce window can't orphan daemon history or an SSH relay lease (Issue #217). if ( store && @@ -5653,11 +6301,13 @@ export function registerPtyHandlers( pendingRegistrationPtyId = null } // Why: arm main's per-PTY Command Code output detector from the launch command (startupCommand parity); banner detection covers PTYs without one. - runtime?.noteTerminalSpawnCommand?.( - result.id, - typeof launchCommand === 'string' ? launchCommand : null - ) - if (isClaudeLaunch) { + if (!stablePaneOwner) { + runtime?.noteTerminalSpawnCommand?.( + result.id, + typeof launchCommand === 'string' ? launchCommand : null + ) + } + if (isClaudeLaunch && !stablePaneOwner) { markClaudePtySpawned(result.id) } // Why: record the paneKey mapping so clearProviderPtyState can clear the agent-hooks server's per-paneKey caches on exit. @@ -5706,7 +6356,7 @@ export function registerPtyHandlers( }) } // Why: telemetry-plan.md§Agent launch semantics — fire agent_started only after spawn resolved; safeParse each field so a spoofed IPC payload can't poison the event (missing required field skips it). - if (args.telemetry) { + if (args.telemetry && !stablePaneOwner) { const agentKindParse = agentKindSchema.safeParse(args.telemetry.agent_kind) const launchSourceParse = launchSourceSchema.safeParse(args.telemetry.launch_source) const requestKindParse = requestKindSchema.safeParse(args.telemetry.request_kind) @@ -5734,7 +6384,7 @@ export function registerPtyHandlers( } // Why: renderer tab state cannot reliably infer background and reattached PTYs in the daemon inventory. sendPtySpawnedToRenderer(result.id) - return resolvePaneSpawnReservation(reservationPaneKey, paneSpawnReservation, response) + return resolvePaneSpawnReservation(paneSpawnReservationKey, paneSpawnReservation, response) } catch (err) { if (pendingRegistrationPtyId) { runtime?.cancelPendingPtyRegistration?.( @@ -5746,10 +6396,10 @@ export function registerPtyHandlers( // Why: once the reservation is created, any later throw — // spawn failure, persist failure, or a post-spawn helper such as // seedHeadlessTerminal/registerPty/track — must settle it. Otherwise - // it lingers in paneSpawnReservationsByPaneKey and every future spawn + // it lingers in paneSpawnReservationsByOwnerKey and every future spawn // for this pane awaits a promise that never resolves. reject is a // no-op once the reservation has already resolved. - rejectPaneSpawnReservation(reservationPaneKey, paneSpawnReservation, err) + rejectPaneSpawnReservation(paneSpawnReservationKey, paneSpawnReservation, err) throw err } finally { releaseWorktreeSpawn?.() @@ -6326,8 +6976,24 @@ export function registerPtyHandlers( ipcMain.handle( 'pty:getAuthoritativeBufferSnapshotCapabilities', - (_event, args: { ids?: unknown }) => { + async (_event, args: { ids?: unknown }) => { const ids = Array.isArray(args?.ids) ? args.ids.slice(0, 512) : [] + const hasLocalPtyId = ids.some((value) => { + if ( + typeof value !== 'string' || + value.length === 0 || + value.length > 512 || + value.startsWith('remote:') || + parseAppSshPtyId(value) + ) { + return false + } + const ownedConnectionId = ptyOwnership.get(value) + return ownedConnectionId === undefined || ownedConnectionId === null + }) + if (hasLocalPtyId) { + await getLocalPtyProviderStartupPromise() + } const capabilities: { id: string; authoritative: boolean | null }[] = [] const seen = new Set() for (const value of ids) { diff --git a/src/main/ipc/renderer-shutdown-checkpoint.test.ts b/src/main/ipc/renderer-shutdown-checkpoint.test.ts index 78accf8abe1..76fc0509eea 100644 --- a/src/main/ipc/renderer-shutdown-checkpoint.test.ts +++ b/src/main/ipc/renderer-shutdown-checkpoint.test.ts @@ -1,10 +1,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -const { syncHandlers } = vi.hoisted(() => ({ +const { syncHandlers, invokeHandlers } = vi.hoisted(() => ({ syncHandlers: new Map< string, (event: { returnValue?: unknown }, args: Record) => void - >() + >(), + invokeHandlers: new Map Promise<{ ok: boolean }>>() })) vi.mock('electron', () => ({ @@ -16,15 +17,25 @@ vi.mock('electron', () => ({ ) => { syncHandlers.set(channel, handler) } - ) + ), + handle: vi.fn((channel: string, handler: () => Promise<{ ok: boolean }>) => { + invokeHandlers.set(channel, handler) + }) } })) -import { registerRendererShutdownCheckpointHandler } from './renderer-shutdown-checkpoint' +import { + registerRendererShutdownCheckpointHandler, + SHUTDOWN_CHECKPOINT_FLUSH_DEADLINE_MS +} from './renderer-shutdown-checkpoint' + +const AWAIT_CHANNEL = 'app:await-before-unload-checkpoint' describe('registerRendererShutdownCheckpointHandler', () => { beforeEach(() => { syncHandlers.clear() + invokeHandlers.clear() + vi.restoreAllMocks() }) it('stages every shutdown mutation before queueing persistence', () => { @@ -34,7 +45,7 @@ describe('registerRendererShutdownCheckpointHandler', () => { callOrder.push(`session:${hostId ?? 'local'}`) }), updateUI: vi.fn(() => callOrder.push('ui')), - flushPendingAsync: vi.fn(() => { + flushPendingOrThrowAsync: vi.fn(() => { callOrder.push('persist') return Promise.resolve() }) @@ -62,7 +73,11 @@ describe('registerRendererShutdownCheckpointHandler', () => { 'runtime:host-1' ) expect(store.updateUI).toHaveBeenCalledWith({ activeView: 'settings' }) - expect(store.flushPendingAsync).toHaveBeenCalledTimes(1) + expect(store.flushPendingOrThrowAsync).toHaveBeenCalledTimes(1) + // Why: a live app keeps mutating state, so draining to a stable generation would livelock. + expect(store.flushPendingOrThrowAsync).toHaveBeenCalledWith( + expect.objectContaining({ drainToStableGeneration: false }) + ) expect(callOrder).toEqual(['session:local', 'session:runtime:host-1', 'ui', 'persist']) expect(event.returnValue).toEqual({ ok: true }) }) @@ -73,7 +88,7 @@ describe('registerRendererShutdownCheckpointHandler', () => { updateUI: vi.fn(() => { throw new Error('disk full') }), - flushPendingAsync: vi.fn(() => Promise.resolve()) + flushPendingOrThrowAsync: vi.fn(() => Promise.resolve()) } registerRendererShutdownCheckpointHandler(store as never) @@ -84,11 +99,11 @@ describe('registerRendererShutdownCheckpointHandler', () => { expect(event.returnValue).toEqual({ ok: false }) }) - it('does not queue persistence when staging is incomplete', () => { + it('does not queue persistence when staging is incomplete', async () => { const store = { stageWorkspaceSessionBeforeUnload: vi.fn(), updateUI: vi.fn(), - flushPendingAsync: vi.fn(() => Promise.resolve()) + flushPendingOrThrowAsync: vi.fn(() => Promise.resolve()) } registerRendererShutdownCheckpointHandler(store as never) @@ -99,19 +114,16 @@ describe('registerRendererShutdownCheckpointHandler', () => { const event: { returnValue?: unknown } = {} handler?.(event, { sessions: [], ui: { activeView: 'settings' } }) - expect(store.flushPendingAsync).not.toHaveBeenCalled() + expect(store.flushPendingOrThrowAsync).not.toHaveBeenCalled() expect(event.returnValue).toEqual({ ok: false }) + await expect(invokeHandlers.get(AWAIT_CHANNEL)?.()).resolves.toEqual({ ok: false }) }) - it('returns before the asynchronous persistence settles', () => { - let resolve!: () => void - const pending = new Promise((next) => { - resolve = next - }) + it('stages synchronously without waiting on the durable write', () => { const store = { stageWorkspaceSessionBeforeUnload: vi.fn(), updateUI: vi.fn(), - flushPendingAsync: vi.fn(() => pending) + flushPendingOrThrowAsync: vi.fn(() => new Promise(() => {})) } registerRendererShutdownCheckpointHandler(store as never) @@ -120,6 +132,84 @@ describe('registerRendererShutdownCheckpointHandler', () => { handler?.(event, { sessions: [], ui: { activeView: 'settings' } }) expect(event.returnValue).toEqual({ ok: true }) - resolve() + }) + + it('holds the checkpoint open until the durable write settles', async () => { + let resolveFlush!: () => void + const store = { + stageWorkspaceSessionBeforeUnload: vi.fn(), + updateUI: vi.fn(), + flushPendingOrThrowAsync: vi.fn( + () => + new Promise((next) => { + resolveFlush = next + }) + ) + } + registerRendererShutdownCheckpointHandler(store as never) + + syncHandlers.get('app:stage-before-unload-sync')?.({}, { sessions: [], ui: {} }) + const checkpoint = invokeHandlers.get(AWAIT_CHANNEL)?.() + let settled: unknown = 'pending' + void checkpoint?.then((result) => { + settled = result + }) + + await Promise.resolve() + expect(settled).toBe('pending') + + resolveFlush() + await expect(checkpoint).resolves.toEqual({ ok: true }) + }) + + it('reports a failed durable write instead of a successful checkpoint', async () => { + const store = { + stageWorkspaceSessionBeforeUnload: vi.fn(), + updateUI: vi.fn(), + flushPendingOrThrowAsync: vi.fn(() => Promise.reject(new Error('disk full'))) + } + vi.spyOn(console, 'error').mockImplementation(() => {}) + registerRendererShutdownCheckpointHandler(store as never) + + const event: { returnValue?: unknown } = {} + syncHandlers.get('app:stage-before-unload-sync')?.(event, { sessions: [], ui: {} }) + + expect(event.returnValue).toEqual({ ok: true }) + await expect(invokeHandlers.get(AWAIT_CHANNEL)?.()).resolves.toEqual({ ok: false }) + }) + + it('fails the checkpoint when the durable write outlives its deadline', async () => { + const store = { + stageWorkspaceSessionBeforeUnload: vi.fn(), + updateUI: vi.fn(), + flushPendingOrThrowAsync: vi.fn( + (_options: { signal: AbortSignal }) => new Promise(() => {}) + ) + } + vi.spyOn(console, 'error').mockImplementation(() => {}) + vi.useFakeTimers() + try { + registerRendererShutdownCheckpointHandler(store as never) + syncHandlers.get('app:stage-before-unload-sync')?.({}, { sessions: [], ui: {} }) + const checkpoint = invokeHandlers.get(AWAIT_CHANNEL)?.() + + await vi.advanceTimersByTimeAsync(SHUTDOWN_CHECKPOINT_FLUSH_DEADLINE_MS) + + await expect(checkpoint).resolves.toEqual({ ok: false }) + expect(store.flushPendingOrThrowAsync.mock.calls[0]?.[0]?.signal.aborted).toBe(true) + } finally { + vi.useRealTimers() + } + }) + + it('reports success before any checkpoint is staged', async () => { + const store = { + stageWorkspaceSessionBeforeUnload: vi.fn(), + updateUI: vi.fn(), + flushPendingOrThrowAsync: vi.fn(() => Promise.resolve()) + } + registerRendererShutdownCheckpointHandler(store as never) + + await expect(invokeHandlers.get(AWAIT_CHANNEL)?.()).resolves.toEqual({ ok: true }) }) }) diff --git a/src/main/ipc/renderer-shutdown-checkpoint.ts b/src/main/ipc/renderer-shutdown-checkpoint.ts index a1fafa16634..e875f950d75 100644 --- a/src/main/ipc/renderer-shutdown-checkpoint.ts +++ b/src/main/ipc/renderer-shutdown-checkpoint.ts @@ -8,7 +8,42 @@ type StageBeforeUnloadSyncArgs = { ui: Partial } +export type ShutdownCheckpointResult = { ok: boolean } + +/** Matches the will-quit teardown budget so a stalled disk can't strand a restart. */ +export const SHUTDOWN_CHECKPOINT_FLUSH_DEADLINE_MS = 20_000 + +function flushStagedStateWithDeadline(store: Store): Promise { + const controller = new AbortController() + let timer: ReturnType | null = null + const deadline = new Promise((resolve) => { + timer = setTimeout(() => { + controller.abort() + console.error('[app] Timed out persisting staged renderer state') + resolve({ ok: false }) + }, SHUTDOWN_CHECKPOINT_FLUSH_DEADLINE_MS) + }) + // Why not drain to a stable generation: the staged snapshot lands in the first + // write, and a live app keeps mutating state, which would livelock the drain. + const flush = store + .flushPendingOrThrowAsync({ signal: controller.signal, drainToStableGeneration: false }) + .then((): ShutdownCheckpointResult => ({ ok: true })) + .catch((error): ShutdownCheckpointResult => { + console.error('[app] Failed to persist staged renderer state:', error) + return { ok: false } + }) + return Promise.race([flush, deadline]).finally(() => { + if (timer) { + clearTimeout(timer) + } + }) +} + export function registerRendererShutdownCheckpointHandler(store: Store): void { + // Why: beforeunload cannot await, so the sync reply only reports staging. + // Durability is joined out-of-band by paths that are about to navigate. + let pendingCheckpoint: Promise = Promise.resolve({ ok: true }) + ipcMain.on('app:stage-before-unload-sync', (event, args: StageBeforeUnloadSyncArgs) => { let ok = true try { @@ -20,11 +55,12 @@ export function registerRendererShutdownCheckpointHandler(store: Store): void { console.error('[app] Failed to stage renderer state before unload:', error) ok = false } - if (ok) { - void store.flushPendingAsync().catch((error) => { - console.error('[app] Failed to persist staged renderer state:', error) - }) - } + pendingCheckpoint = ok ? flushStagedStateWithDeadline(store) : Promise.resolve({ ok: false }) event.returnValue = { ok } }) + + ipcMain.handle( + 'app:await-before-unload-checkpoint', + (): Promise => pendingCheckpoint + ) } diff --git a/src/main/ipc/runtime-environments.test.ts b/src/main/ipc/runtime-environments.test.ts index d0101ee3968..0e3739d6ccb 100644 --- a/src/main/ipc/runtime-environments.test.ts +++ b/src/main/ipc/runtime-environments.test.ts @@ -1689,6 +1689,363 @@ describe('registerRuntimeEnvironmentHandlers', () => { }) }) + it('tells the renderer when retiring the transport closes its streaming subscription', async () => { + // Why: disconnect advances the transport generation before closing sockets. + // Gating the terminal 'close' on that generation stranded the renderer with a + // handle it believed was open, so every later subscribe wrote into a socket + // main no longer owned — blank, wedged remote terminals after a reconnect. + registerRuntimeEnvironmentHandlers(store as never) + let transportCallbacks: { + onResponse: (response: Record) => void + onClose: () => void + } | null = null + const close = vi.fn(() => { + transportCallbacks?.onClose() + }) + subscribeRemoteRuntimeRequestMock.mockImplementation( + async ( + _environment: unknown, + _method: string, + _params: unknown, + _timeoutMs: number, + callbacks: NonNullable + ) => { + transportCallbacks = callbacks + return { requestId: 'multiplex-1', close, sendBinary: vi.fn() } + } + ) + + const add = handler< + { name: string; pairingCode: string }, + { environment: { id: string; name: string } } + >('runtimeEnvironments:addFromPairingCode') + const added = await add(null, { name: 'desk', pairingCode: pairingCode() }) + + const senderSend = vi.fn() + const subscribe = handler< + { selector: string; method: string; params?: unknown; subscriptionId?: string }, + { subscriptionId: string; requestId: string } + >('runtimeEnvironments:subscribe') + const subscribed = await subscribe( + { + sender: { + id: 1, + isDestroyed: () => false, + send: senderSend, + once: vi.fn(), + removeListener: vi.fn() + } + }, + { + selector: added.environment.id, + method: 'terminal.multiplex', + params: {}, + subscriptionId: 'multiplex-sub' + } + ) + + const disconnect = handler<{ selector: string }, { disconnected: { id: string } }>( + 'runtimeEnvironments:disconnect' + ) + disconnect(null, { selector: added.environment.id }) + + const closeEvents = senderSend.mock.calls.filter( + (call) => + call[0] === 'runtimeEnvironments:subscriptionEvent' && + (call[1] as { type?: string }).type === 'close' + ) + expect(closeEvents).toEqual([ + [ + 'runtimeEnvironments:subscriptionEvent', + { subscriptionId: subscribed.subscriptionId, type: 'close' } + ] + ]) + }) + + it("retires an environment's remaining subscriptions when one teardown throws", async () => { + // Why: the sweep exists to retire dead handles, so a single failing teardown + // must not strand the very sockets it was called to close. + registerRuntimeEnvironmentHandlers(store as never) + const closeCalls: string[] = [] + let streamCount = 0 + subscribeRemoteRuntimeRequestMock.mockImplementation(async () => { + streamCount += 1 + const requestId = `stream-${streamCount}` + return { + requestId, + close: () => { + closeCalls.push(requestId) + if (requestId === 'stream-1') { + throw new Error('socket teardown exploded') + } + }, + sendBinary: vi.fn() + } + }) + + const add = handler< + { name: string; pairingCode: string }, + { environment: { id: string; name: string } } + >('runtimeEnvironments:addFromPairingCode') + const added = await add(null, { name: 'desk', pairingCode: pairingCode() }) + + const senderSend = vi.fn() + const subscribe = handler< + { selector: string; method: string; params?: unknown; subscriptionId?: string }, + { subscriptionId: string; requestId: string } + >('runtimeEnvironments:subscribe') + const sender = { + sender: { + id: 1, + isDestroyed: () => false, + send: senderSend, + once: vi.fn(), + removeListener: vi.fn() + } + } + await subscribe(sender, { + selector: added.environment.id, + method: 'terminal.multiplex', + params: {}, + subscriptionId: 'doomed-sub' + }) + await subscribe(sender, { + selector: added.environment.id, + method: 'browser.screencast', + params: {}, + subscriptionId: 'sibling-sub' + }) + + const disconnect = handler<{ selector: string }, { disconnected: { id: string } }>( + 'runtimeEnvironments:disconnect' + ) + expect(() => disconnect(null, { selector: added.environment.id })).not.toThrow() + + expect(closeCalls).toEqual(['stream-1', 'stream-2']) + expect( + senderSend.mock.calls + .filter((call) => (call[1] as { type?: string }).type === 'close') + .map((call) => (call[1] as { subscriptionId: string }).subscriptionId) + ).toEqual(['doomed-sub', 'sibling-sub']) + + // Both entries are gone, so a later unsubscribe finds nothing to release. + const unsubscribe = handler<{ subscriptionId: string }, { unsubscribed: boolean }>( + 'runtimeEnvironments:unsubscribe' + ) + expect(await unsubscribe({ sender: { id: 1 } }, { subscriptionId: 'sibling-sub' })).toEqual({ + unsubscribed: false + }) + }) + + it('contains a throwing renderer send on a host-initiated close', async () => { + // Why: this is the notifyClosed call site with no surrounding guard. A host + // close arriving on a disposed render frame would otherwise throw out through + // the transport's onClose and into the WebSocket close handler. + registerRuntimeEnvironmentHandlers(store as never) + let transportCallbacks: { + onResponse: (response: Record) => void + onClose: () => void + } | null = null + subscribeRemoteRuntimeRequestMock.mockImplementation( + async ( + _environment: unknown, + _method: string, + _params: unknown, + _timeoutMs: number, + callbacks: NonNullable + ) => { + transportCallbacks = callbacks + return { requestId: 'host-closed-stream', close: vi.fn(), sendBinary: vi.fn() } + } + ) + + const add = handler< + { name: string; pairingCode: string }, + { environment: { id: string; name: string } } + >('runtimeEnvironments:addFromPairingCode') + const added = await add(null, { name: 'desk', pairingCode: pairingCode() }) + + const senderSend = vi.fn((_channel: string, payload: { type: string }) => { + if (payload.type === 'close') { + throw new Error('Render frame was disposed') + } + }) + const subscribe = handler< + { selector: string; method: string; params?: unknown; subscriptionId?: string }, + { subscriptionId: string; requestId: string } + >('runtimeEnvironments:subscribe') + await subscribe( + { + sender: { + id: 1, + isDestroyed: () => false, + send: senderSend, + once: vi.fn(), + removeListener: vi.fn() + } + }, + { + selector: added.environment.id, + method: 'terminal.multiplex', + params: {}, + subscriptionId: 'host-closed-sub' + } + ) + + // The host closes the stream on its own; nothing wraps this call site. + expect(() => transportCallbacks!.onClose()).not.toThrow() + expect( + senderSend.mock.calls.filter((call) => (call[1] as { type?: string }).type === 'close') + ).toHaveLength(1) + + // The entry is still released, so a later unsubscribe finds nothing. + const unsubscribe = handler<{ subscriptionId: string }, { unsubscribed: boolean }>( + 'runtimeEnvironments:unsubscribe' + ) + expect(await unsubscribe({ sender: { id: 1 } }, { subscriptionId: 'host-closed-sub' })).toEqual( + { + unsubscribed: false + } + ) + }) + + it('retires remaining subscriptions when a liveness probe inside notifyClosed throws', async () => { + // Why: notifyClosed guards its own send, but the sweep must not depend on + // everything else inside it staying throw-free -- that is how the abandoned + // -siblings defect comes back the next time a line is added there. + registerRuntimeEnvironmentHandlers(store as never) + const closedStreams: string[] = [] + let streamCount = 0 + subscribeRemoteRuntimeRequestMock.mockImplementation(async () => { + streamCount += 1 + const requestId = `stream-${streamCount}` + return { + requestId, + close: () => closedStreams.push(requestId), + sendBinary: vi.fn() + } + }) + + const add = handler< + { name: string; pairingCode: string }, + { environment: { id: string; name: string } } + >('runtimeEnvironments:addFromPairingCode') + const added = await add(null, { name: 'desk', pairingCode: pairingCode() }) + + const deliveredCloses: string[] = [] + const senderSend = vi.fn( + (_channel: string, payload: { subscriptionId: string; type: string }) => { + if (payload.type === 'close') { + deliveredCloses.push(payload.subscriptionId) + } + } + ) + let probeShouldThrow = false + const subscribe = handler< + { selector: string; method: string; params?: unknown; subscriptionId?: string }, + { subscriptionId: string; requestId: string } + >('runtimeEnvironments:subscribe') + const sender = { + sender: { + id: 1, + isDestroyed: () => { + if (probeShouldThrow) { + throw new Error('WebContents liveness probe exploded') + } + return false + }, + send: senderSend, + once: vi.fn(), + removeListener: vi.fn() + } + } + await subscribe(sender, { + selector: added.environment.id, + method: 'terminal.multiplex', + params: {}, + subscriptionId: 'probe-throws-sub' + }) + await subscribe(sender, { + selector: added.environment.id, + method: 'browser.screencast', + params: {}, + subscriptionId: 'surviving-sub' + }) + // Why: arm only after subscribe, whose own isDestroyed checks must succeed. + probeShouldThrow = true + + const disconnect = handler<{ selector: string }, { disconnected: { id: string } }>( + 'runtimeEnvironments:disconnect' + ) + expect(() => disconnect(null, { selector: added.environment.id })).not.toThrow() + + // Both transports still closed even though every notifyClosed probe threw. + expect(closedStreams).toEqual(['stream-1', 'stream-2']) + expect(deliveredCloses).toEqual([]) + }) + + it('suppresses stale payloads from a retired transport but never re-sends its close', async () => { + registerRuntimeEnvironmentHandlers(store as never) + let transportCallbacks: { + onResponse: (response: Record) => void + onClose: () => void + } | null = null + subscribeRemoteRuntimeRequestMock.mockImplementation( + async ( + _environment: unknown, + _method: string, + _params: unknown, + _timeoutMs: number, + callbacks: NonNullable + ) => { + transportCallbacks = callbacks + return { requestId: 'multiplex-2', close: vi.fn(), sendBinary: vi.fn() } + } + ) + + const add = handler< + { name: string; pairingCode: string }, + { environment: { id: string; name: string } } + >('runtimeEnvironments:addFromPairingCode') + const added = await add(null, { name: 'desk', pairingCode: pairingCode() }) + + const senderSend = vi.fn() + const subscribe = handler< + { selector: string; method: string; params?: unknown; subscriptionId?: string }, + { subscriptionId: string; requestId: string } + >('runtimeEnvironments:subscribe') + await subscribe( + { + sender: { + id: 1, + isDestroyed: () => false, + send: senderSend, + once: vi.fn(), + removeListener: vi.fn() + } + }, + { + selector: added.environment.id, + method: 'terminal.multiplex', + params: {}, + subscriptionId: 'multiplex-stale' + } + ) + + invalidateRuntimeEnvironmentTransport(added.environment.id) + senderSend.mockClear() + // A late frame from the retired socket must not reach the renderer... + transportCallbacks!.onResponse({ + id: 'r1', + ok: true, + result: {}, + _meta: { runtimeId: 'runtime-a' } + }) + // ...and its late close must not re-fire after the retirement already sent one. + transportCallbacks!.onClose() + expect(senderSend).not.toHaveBeenCalled() + }) + it('rejects cross-window streaming subscription control', async () => { registerRuntimeEnvironmentHandlers(store as never) const close = vi.fn() diff --git a/src/main/ipc/runtime-environments.ts b/src/main/ipc/runtime-environments.ts index 6bf71edd634..e31f8569dec 100644 --- a/src/main/ipc/runtime-environments.ts +++ b/src/main/ipc/runtime-environments.ts @@ -25,6 +25,7 @@ type RetainedRemoteRuntimeSubscription = RemoteRuntimeSubscription & { environmentId: string ownerWebContentsId: number removeDestroyedListener: () => void + notifyClosed: () => void } const remoteRuntimeSubscriptions = new Map() const getUserDataPath = (): string => app.getPath('userData') @@ -36,7 +37,22 @@ function closeSubscriptionsForEnvironment(environmentId: string): void { continue } remoteRuntimeSubscriptions.delete(subscriptionId) - subscription.close() + // Why: one failing teardown must not abandon this environment's other + // sockets -- that strands exactly the dead handles this sweep exists to + // retire. Guard the two steps independently so neither can skip the other, + // and so the isolation stays structural rather than resting on a claim that + // nothing inside notifyClosed will ever throw. + try { + subscription.close() + } catch (error) { + console.warn('[runtime-environments] subscription close failed during retirement:', error) + } + try { + // Why: a shared-control logical close never calls back, so notify directly. + subscription.notifyClosed() + } catch (error) { + console.warn('[runtime-environments] subscription close notice failed:', error) + } } } export function invalidateRuntimeEnvironmentTransport(environmentId: string): void { @@ -120,6 +136,21 @@ export function registerRuntimeEnvironmentHandlers(store: Store): void { removeDestroyedListener() subscription?.close() } + // Why: the renderer treats close as terminal and drops its handle, so send it once. + // Latch before sending so a re-entrant call cannot duplicate it, and never + // throw: a dying renderer must not abort its siblings' retirement. + let closeNotified = false + const notifyClosed = (): void => { + if (closeNotified || sender.isDestroyed()) { + return + } + closeNotified = true + try { + sender.send('runtimeEnvironments:subscriptionEvent', { subscriptionId, type: 'close' }) + } catch { + // The renderer is gone; there is no one left to tell. + } + } sender.once('destroyed', closeSubscription) destroyedListenerAttached = true try { @@ -131,6 +162,12 @@ export function registerRuntimeEnvironmentHandlers(store: Store): void { args.timeoutMs, { onEvent: (payload) => { + if (payload.type === 'close') { + // Why: retirement advances the generation before closing, so gating + // close on it stranded the renderer with a dead subscription. + notifyClosed() + return + } if (transportIsCurrent() && !sender.isDestroyed()) { sender.send('runtimeEnvironments:subscriptionEvent', { subscriptionId, @@ -172,6 +209,7 @@ export function registerRuntimeEnvironmentHandlers(store: Store): void { environmentId: environment.id, ownerWebContentsId, removeDestroyedListener, + notifyClosed, sendBinary: (bytes) => subscription?.sendBinary(bytes) ?? false, close: () => { removeDestroyedListener() diff --git a/src/main/ipc/ssh.test.ts b/src/main/ipc/ssh.test.ts index a846e2958c4..0152c977ebc 100644 --- a/src/main/ipc/ssh.test.ts +++ b/src/main/ipc/ssh.test.ts @@ -20,6 +20,8 @@ const { mockRegisterSshGitProvider, mockPortForwardManager, mockPortScannerCallbacks, + mockListConfigHosts, + mockResolveConfigHost, mockNextConnectionManagers, mockNextPortForwardManagers } = vi.hoisted(() => ({ @@ -28,6 +30,7 @@ const { powerMonitorOnMock: vi.fn(), mockSshStore: { listTargets: vi.fn().mockReturnValue([]), + listSuppressedSshConfigAliases: vi.fn().mockReturnValue([]), getTarget: vi.fn(), addTarget: vi.fn(), updateTarget: vi.fn(), @@ -88,10 +91,23 @@ const { callbacksRef: { current: null as unknown } }, mockPortScannerCallbacks: new Map(), + mockListConfigHosts: vi.fn().mockReturnValue({ + hosts: [], + totalHostCount: 0, + newHostCount: 0, + matchCount: 0, + hasMore: false + }), + mockResolveConfigHost: vi.fn().mockResolvedValue(null), mockNextConnectionManagers: [] as unknown[], mockNextPortForwardManagers: [] as unknown[] })) +vi.mock('../ssh/ssh-config-host-picker', () => ({ + listUserSshConfigHostSummaries: mockListConfigHosts, + resolveUserSshConfigHost: mockResolveConfigHost +})) + vi.mock('electron', () => ({ ipcMain: { handle: handleMock, @@ -441,6 +457,8 @@ describe('SSH IPC handlers', () => { expect(channels).toContain('ssh:updateTarget') expect(channels).toContain('ssh:removeTarget') expect(channels).toContain('ssh:importConfig') + expect(channels).toContain('ssh:listConfigHosts') + expect(channels).toContain('ssh:resolveConfigHost') expect(channels).toContain('ssh:connect') expect(channels).toContain('ssh:disconnect') expect(channels).toContain('ssh:terminateSessions') @@ -554,6 +572,35 @@ describe('SSH IPC handlers', () => { expect(result).toEqual({ targets: imported, repoReadoptions: [] }) }) + it('ssh:listConfigHosts loads summaries against current targets', async () => { + mockSshStore.listTargets.mockReturnValue([ + { id: 'ssh-1', label: 'other', host: 'other.com', port: 22, username: 'x' } + ]) + + const result = await handlers.get('ssh:listConfigHosts')!(null, { query: 'oth' }) + + expect(mockSshStore.listTargets).toHaveBeenCalled() + expect(mockListConfigHosts).toHaveBeenCalledWith(mockSshStore.listTargets(), 'oth', [], { + refresh: false + }) + expect(result).toMatchObject({ hosts: [], hasMore: false }) + }) + + // Only a picker (re)open re-reads ~/.ssh/config; filter keystrokes reuse the parse. + it('ssh:listConfigHosts refreshes the parsed config only when asked', async () => { + mockSshStore.listTargets.mockReturnValue([]) + + await handlers.get('ssh:listConfigHosts')!(null, { query: '', refresh: true }) + + expect(mockListConfigHosts).toHaveBeenCalledWith([], '', [], { refresh: true }) + }) + + it('ssh:resolveConfigHost resolves only the selected alias', async () => { + await handlers.get('ssh:resolveConfigHost')!(null, { alias: 'prod' }) + + expect(mockResolveConfigHost).toHaveBeenCalledWith('prod') + }) + it('ssh:connect throws for unknown targetId', async () => { mockSshStore.getTarget.mockReturnValue(undefined) diff --git a/src/main/ipc/ssh.ts b/src/main/ipc/ssh.ts index 708107c64bc..6fd962692a7 100644 --- a/src/main/ipc/ssh.ts +++ b/src/main/ipc/ssh.ts @@ -3,6 +3,10 @@ import { ipcMain, powerMonitor, type BrowserWindow } from 'electron' import { appendFileSync } from 'node:fs' import type { Store } from '../persistence' import { SshConnectionStore } from '../ssh/ssh-connection-store' +import { + listUserSshConfigHostSummaries, + resolveUserSshConfigHost +} from '../ssh/ssh-config-host-picker' import type { SshConnectionCallbacks } from '../ssh/ssh-connection' import { SshConnectionManager } from '../ssh/ssh-connection-manager' import { @@ -12,11 +16,13 @@ import { } from '../ssh/ssh-auto-reconnect-budget' import type { SshChannelMultiplexer } from '../ssh/ssh-channel-multiplexer' import { SshRelaySession, type SshRelayAiVaultHostInfo } from '../ssh/ssh-relay-session' +import type { SshAiVaultRelayListParams } from '../../shared/ssh-ai-vault-relay' import { SshPortForwardManager } from '../ssh/ssh-port-forward' import type { DetectedPort, EnrichedDetectedPort, SavedPortForward, + SshConfigHostListArgs, SshRepoReadoption, SshTarget, SshConnectionStatus, @@ -77,6 +83,8 @@ const SSH_IPC_CHANNELS = [ 'ssh:updateTarget', 'ssh:removeTarget', 'ssh:importConfig', + 'ssh:listConfigHosts', + 'ssh:resolveConfigHost', 'ssh:connect', 'ssh:disconnect', 'ssh:terminateSessions', @@ -176,6 +184,21 @@ export function getActiveSshAiVaultHostInfos(): SshRelayAiVaultHostInfo[] { }) } +export async function requestActiveSshAiVaultSessionList( + targetId: string, + params: SshAiVaultRelayListParams, + options: { signal?: AbortSignal; timeoutMs?: number } = {} +): Promise { + if (isRuntimeOwnedSshTargetId(targetId)) { + return null + } + const session = activeSessions.get(targetId) + if (!session) { + throw new Error('SSH relay is not ready') + } + return session.requestAiVaultSessionList(params, options) +} + function runTargetLifecycle(targetId: string, operation: () => Promise): Promise { const prior = targetLifecycleInFlight.get(targetId) const operationPromise = (async () => { @@ -985,6 +1008,21 @@ export function registerSshHandlers( return { targets, repoReadoptions } }) + // Why: add-host dialog picks one config entry to prefill the form; does not + // mutate the target store (bulk sync stays on Settings → Import). + ipcMain.handle('ssh:listConfigHosts', (_event, args?: SshConfigHostListArgs) => { + return listUserSshConfigHostSummaries( + sshStore!.listTargets(), + args?.query, + sshStore!.listSuppressedSshConfigAliases(), + { refresh: args?.refresh === true } + ) + }) + + ipcMain.handle('ssh:resolveConfigHost', (_event, args: { alias: string }) => { + return resolveUserSshConfigHost(args.alias) + }) + // ── Connection lifecycle ─────────────────────────────────────────── async function connectTarget( diff --git a/src/main/ipc/telemetry.test.ts b/src/main/ipc/telemetry.test.ts index 1f412a6d0e9..2645d98dff5 100644 --- a/src/main/ipc/telemetry.test.ts +++ b/src/main/ipc/telemetry.test.ts @@ -160,6 +160,7 @@ describe('telemetry IPC handlers', () => { count_bucket: 'count_1', bucket_source: 'crossed_now' }) + handler({}, 'daemon_audit_eligibility', {}) expect(trackMock).not.toHaveBeenCalled() expect(getCohortAtEmitMock).not.toHaveBeenCalled() }) diff --git a/src/main/ipc/telemetry.ts b/src/main/ipc/telemetry.ts index 02f1b9e16be..c1fe7d0f68d 100644 --- a/src/main/ipc/telemetry.ts +++ b/src/main/ipc/telemetry.ts @@ -24,6 +24,7 @@ let storeRef: Store | null = null const MAIN_OWNED_TELEMETRY_EVENTS = new Set([ 'app_starred_orca', + 'daemon_audit_eligibility', 'star_nag_outcome', 'feature_interaction_usage_bucket_reached' ]) diff --git a/src/main/ipc/workspace-cleanup-activity.test.ts b/src/main/ipc/workspace-cleanup-activity.test.ts index 72f20291f4a..bfb1c080db3 100644 --- a/src/main/ipc/workspace-cleanup-activity.test.ts +++ b/src/main/ipc/workspace-cleanup-activity.test.ts @@ -55,17 +55,18 @@ describe('resolveWorkspaceCleanupActivityWorktree', () => { expect(worktree.lastActivityAt).toBe(20_000) }) - it('uses linked worktree gitdir metadata when the .git pointer is stale', async () => { + it('uses linked worktree commit metadata when the .git pointer is stale', async () => { const gitDirPath = path.join('/repo', '.git', 'worktrees', 'repo-feature') const gitDirHeadPath = path.join(gitDirPath, 'HEAD') - const gitDirLogsHeadPath = path.join(gitDirPath, 'logs', 'HEAD') + const commitEditMsgPath = path.join(gitDirPath, 'COMMIT_EDITMSG') + const origHeadPath = path.join(gitDirPath, 'ORIG_HEAD') const statPath = vi.fn(async (targetPath: string) => { const mtimes: Record = { '/repo-feature': 10_000, [path.join('/repo-feature', '.git')]: 20_000, - [gitDirPath]: 50_000, [gitDirHeadPath]: 60_000, - [gitDirLogsHeadPath]: 70_000 + [origHeadPath]: 65_000, + [commitEditMsgPath]: 70_000 } return { mtimeMs: mtimes[targetPath] ?? 0 } }) @@ -79,17 +80,86 @@ describe('resolveWorkspaceCleanupActivityWorktree', () => { ) expect(readTextFile).toHaveBeenCalledWith(path.join('/repo-feature', '.git')) - expect(statPath).toHaveBeenCalledWith(gitDirPath) expect(statPath).toHaveBeenCalledWith(gitDirHeadPath) - expect(statPath).toHaveBeenCalledWith(gitDirLogsHeadPath) + expect(statPath).toHaveBeenCalledWith(commitEditMsgPath) + expect(statPath).toHaveBeenCalledWith(origHeadPath) expect(worktree.lastActivityAt).toBe(70_000) }) + it('ignores gitdir metadata that git maintenance and git status restamp', async () => { + const gitDirPath = path.join('/repo', '.git', 'worktrees', 'repo-feature') + const statPath = vi.fn(async (targetPath: string) => { + const mtimes: Record = { + '/repo-feature': 10_000, + [path.join('/repo-feature', '.git')]: 10_000, + [gitDirPath]: 90_000, + [path.join(gitDirPath, 'index')]: 90_000, + [path.join(gitDirPath, 'logs', 'HEAD')]: 90_000 + } + return { mtimeMs: mtimes[targetPath] ?? 0 } + }) + const readTextFile = vi.fn(async () => `gitdir: ${gitDirPath}\n`) + + const worktree = await resolveWorkspaceCleanupActivityWorktree( + REPO, + makeWorktree(), + statPath, + readTextFile + ) + + expect(statPath).not.toHaveBeenCalledWith(gitDirPath) + expect(statPath).not.toHaveBeenCalledWith(path.join(gitDirPath, 'index')) + expect(statPath).not.toHaveBeenCalledWith(path.join(gitDirPath, 'logs', 'HEAD')) + expect(worktree.lastActivityAt).toBe(10_000) + }) + + it('reads the newest reflog entry timestamp instead of the reflog file mtime', async () => { + const gitDirPath = path.join('/repo', '.git', 'worktrees', 'repo-feature') + const reflogPath = path.join(gitDirPath, 'logs', 'HEAD') + const statPath = vi.fn(async () => ({ mtimeMs: 10_000 })) + const readTextFile = vi.fn(async (targetPath: string) => + targetPath === reflogPath + ? [ + '0000 1111 Dev 1700000000 -0700\tbranch: Created from HEAD', + '1111 2222 Dev 1700000900 -0700\tcommit: work', + '' + ].join('\n') + : `gitdir: ${gitDirPath}\n` + ) + + const worktree = await resolveWorkspaceCleanupActivityWorktree( + REPO, + makeWorktree(), + statPath, + readTextFile + ) + + expect(readTextFile).toHaveBeenCalledWith(reflogPath) + expect(worktree.lastActivityAt).toBe(1_700_000_900_000) + }) + + it('degrades to other probes when the reflog was expired to an empty file', async () => { + const gitDirPath = path.join('/repo', '.git', 'worktrees', 'repo-feature') + const statPath = vi.fn(async () => ({ mtimeMs: 10_000 })) + const readTextFile = vi.fn(async (targetPath: string) => + targetPath === path.join(gitDirPath, 'logs', 'HEAD') ? '' : `gitdir: ${gitDirPath}\n` + ) + + const worktree = await resolveWorkspaceCleanupActivityWorktree( + REPO, + makeWorktree(), + statPath, + readTextFile + ) + + expect(worktree.lastActivityAt).toBe(10_000) + }) + it('resolves relative linked worktree gitdir pointers from the worktree path', async () => { const gitDirPath = path.resolve('/repo-feature', '.repo/gitdir') - const gitDirLogsHeadPath = path.join(gitDirPath, 'logs', 'HEAD') + const commitEditMsgPath = path.join(gitDirPath, 'COMMIT_EDITMSG') const statPath = vi.fn(async (targetPath: string) => ({ - mtimeMs: targetPath === gitDirLogsHeadPath ? 40_000 : 10_000 + mtimeMs: targetPath === commitEditMsgPath ? 40_000 : 10_000 })) const readTextFile = vi.fn(async () => 'gitdir: .repo/gitdir\n') @@ -100,7 +170,7 @@ describe('resolveWorkspaceCleanupActivityWorktree', () => { readTextFile ) - expect(statPath).toHaveBeenCalledWith(gitDirLogsHeadPath) + expect(statPath).toHaveBeenCalledWith(commitEditMsgPath) expect(worktree.lastActivityAt).toBe(40_000) }) @@ -108,14 +178,13 @@ describe('resolveWorkspaceCleanupActivityWorktree', () => { const worktreePath = String.raw`\\wsl.localhost\Ubuntu\home\me\repo-feature` const gitDirPath = String.raw`\\wsl.localhost\Ubuntu\home\me\repo\.git\worktrees\repo-feature` const gitDirHeadPath = path.join(gitDirPath, 'HEAD') - const gitDirLogsHeadPath = path.join(gitDirPath, 'logs', 'HEAD') + const commitEditMsgPath = path.join(gitDirPath, 'COMMIT_EDITMSG') const statPath = vi.fn(async (targetPath: string) => { const mtimes: Record = { [worktreePath]: 10_000, [path.join(worktreePath, '.git')]: 20_000, - [gitDirPath]: 50_000, [gitDirHeadPath]: 60_000, - [gitDirLogsHeadPath]: 70_000 + [commitEditMsgPath]: 70_000 } return { mtimeMs: mtimes[targetPath] ?? 0 } }) @@ -129,10 +198,11 @@ describe('resolveWorkspaceCleanupActivityWorktree', () => { ) expect(readTextFile).toHaveBeenCalledWith(path.join(worktreePath, '.git')) - expect(statPath).toHaveBeenCalledWith(gitDirPath) expect(statPath).toHaveBeenCalledWith(gitDirHeadPath) - expect(statPath).toHaveBeenCalledWith(gitDirLogsHeadPath) - expect(statPath).not.toHaveBeenCalledWith('/home/me/repo/.git/worktrees/repo-feature') + expect(statPath).toHaveBeenCalledWith(commitEditMsgPath) + expect(statPath).not.toHaveBeenCalledWith( + path.join('/home/me/repo/.git/worktrees/repo-feature', 'HEAD') + ) expect(worktree.lastActivityAt).toBe(70_000) }) diff --git a/src/main/ipc/workspace-cleanup-activity.ts b/src/main/ipc/workspace-cleanup-activity.ts index 9026b4464d9..56ac36f6b29 100644 --- a/src/main/ipc/workspace-cleanup-activity.ts +++ b/src/main/ipc/workspace-cleanup-activity.ts @@ -1,20 +1,13 @@ import { lstat, readFile } from 'node:fs/promises' import path from 'node:path' import type { Repo, Worktree } from '../../shared/types' +import { getPersistedWorkspaceCleanupActivityAt } from '../../shared/workspace-cleanup' import { parseWslUncPath } from '../../shared/wsl-paths' import { toWindowsWslPath } from '../wsl' type StatPath = (targetPath: string) => Promise<{ mtimeMs: number }> type ReadTextFile = (targetPath: string) => Promise -export function getPersistedWorkspaceCleanupActivityAt( - worktree: Pick -): number { - const persistedActivityAt = Number.isFinite(worktree.lastActivityAt) ? worktree.lastActivityAt : 0 - const createdAt = Number.isFinite(worktree.createdAt) ? (worktree.createdAt ?? 0) : 0 - return Math.max(persistedActivityAt, createdAt) -} - export function resolvePersistedWorkspaceCleanupActivityWorktree(worktree: Worktree): Worktree { const persistedActivityAt = getPersistedWorkspaceCleanupActivityAt(worktree) if (persistedActivityAt <= worktree.lastActivityAt) { @@ -56,7 +49,7 @@ async function resolveWorkspaceCleanupActivityAt( return persistedActivityAt } - const filesystemActivityAt = await getNewestLocalWorktreeStatMtime( + const filesystemActivityAt = await getNewestLocalWorktreeActivityAt( worktree.path, statPath, readTextFile @@ -67,26 +60,54 @@ async function resolveWorkspaceCleanupActivityAt( // Why: best-effort only. Win32 stat over \\wsl.localhost (9P) can falsely // report ENOENT (see wslUncDirectoryExists), so a failed stat degrades to the // persisted activity timestamp instead of blocking or mislabeling the row. -async function getNewestLocalWorktreeStatMtime( +async function getNewestLocalWorktreeActivityAt( worktreePath: string, statPath: StatPath, readTextFile: ReadTextFile ): Promise { const gitPath = path.join(worktreePath, '.git') const gitDirPath = await readLocalWorktreeGitDir(worktreePath, gitPath, readTextFile) - const gitDirMtimePromises = gitDirPath + // Why: every entry here must move only on a user action. Excluded on purpose: + // the gitdir directory and logs/HEAD (restamped for every linked worktree at + // once by `git gc` / `git reflog expire`, which made one maintenance run look + // like activity everywhere), and index (rewritten by `git status` — this scan + // runs one per candidate, so it would erase the evidence it just read). + const gitDirProbes = gitDirPath ? [ - readMtime(gitDirPath, statPath), readMtime(path.join(gitDirPath, 'HEAD'), statPath), - readMtime(path.join(gitDirPath, 'logs', 'HEAD'), statPath) + readMtime(path.join(gitDirPath, 'COMMIT_EDITMSG'), statPath), + readMtime(path.join(gitDirPath, 'ORIG_HEAD'), statPath), + readNewestReflogEntryAt(path.join(gitDirPath, 'logs', 'HEAD'), readTextFile) ] : [] - const mtimes = await Promise.all([ + const timestamps = await Promise.all([ readMtime(worktreePath, statPath), readMtime(gitPath, statPath), - ...gitDirMtimePromises + ...gitDirProbes ]) - return Math.max(0, ...mtimes) + return Math.max(0, ...timestamps) +} + +// Why: the reflog records when HEAD actually moved, so it survives the mtime +// churn that makes logs/HEAD itself unreadable as a signal. Expired reflogs are +// truncated to an empty file, which degrades to the other probes. +async function readNewestReflogEntryAt( + reflogPath: string, + readTextFile: ReadTextFile +): Promise { + try { + const lines = (await readTextFile(reflogPath)).split('\n') + for (let index = lines.length - 1; index >= 0; index -= 1) { + // The trailing timezone + tab anchors the capture, so no digit-count floor is needed. + const seconds = /\s(\d{1,11})\s[-+]\d{4}\t/.exec(lines[index] ?? '')?.[1] + if (seconds) { + return Number(seconds) * 1000 + } + } + return 0 + } catch { + return 0 + } } async function readLocalWorktreeGitDir( diff --git a/src/main/ipc/workspace-cleanup-scan.ts b/src/main/ipc/workspace-cleanup-scan.ts index f5deb16a2bd..32794f61977 100644 --- a/src/main/ipc/workspace-cleanup-scan.ts +++ b/src/main/ipc/workspace-cleanup-scan.ts @@ -13,8 +13,8 @@ import type { WorkspaceCleanupScanProgress, WorkspaceCleanupScanResult } from '../../shared/workspace-cleanup' +import { getPersistedWorkspaceCleanupActivityAt } from '../../shared/workspace-cleanup' import { - getPersistedWorkspaceCleanupActivityAt, resolvePersistedWorkspaceCleanupActivityWorktree, resolveWorkspaceCleanupActivityWorktree } from './workspace-cleanup-activity' diff --git a/src/main/ipc/worktree-remote.ts b/src/main/ipc/worktree-remote.ts index d37918595ff..b09b4e71c93 100644 --- a/src/main/ipc/worktree-remote.ts +++ b/src/main/ipc/worktree-remote.ts @@ -54,6 +54,7 @@ import { getSetupRunnerEnvVars, loadHooks, parseOrcaYaml, + resolveSetupRunnerShell, shouldRunSetupForCreate } from '../hooks' import { requireSshGitProvider } from '../providers/ssh-git-dispatch' @@ -178,6 +179,13 @@ function appendWorktreeCreateWarning(current: string | undefined, next: string): return current ? `${current} Also ${next[0]?.toLowerCase() ?? ''}${next.slice(1)}` : next } +function getSetupRunnerCommandPlatformForLaunch( + setup: CreateWorktreeResult['setup'], + fallbackPlatform: 'windows' | 'posix' +): 'windows' | 'posix' { + return getSetupRunnerCommandPlatformForPath(setup?.runnerScriptPath ?? '', fallbackPlatform) +} + function validateWorkspaceLineageParentBeforeCreate( store: Store, parentWorkspace: CreateWorktreeArgs['parentWorkspace'], @@ -266,14 +274,15 @@ async function spawnLocalStartupAndSetupTerminals(args: { let sequencedStartup = startup let wrappedSetupCommandStr: string | undefined if (startup && setup?.waitForAgentStartup === true) { - const platform = getSetupRunnerCommandPlatformForPath( - setup.runnerScriptPath, + const platform = getSetupRunnerCommandPlatformForLaunch( + setup, process.platform === 'win32' ? 'windows' : 'posix' ) const sequenced = createSequencedSetupAgentCommands({ runnerScriptPath: setup.runnerScriptPath, startupCommand: startup.command, - platform + platform, + shell: setup.shell }) sequencedStartup = { ...startup, @@ -329,10 +338,11 @@ async function spawnLocalStartupAndSetupTerminals(args: { wrappedSetupCommandStr ?? buildSetupRunnerCommand( setup.runnerScriptPath, - getSetupRunnerCommandPlatformForPath( - setup.runnerScriptPath, + getSetupRunnerCommandPlatformForLaunch( + setup, process.platform === 'win32' ? 'windows' : 'posix' - ) + ), + setup.shell ) const setupLaunchMode = (settings as Partial>) @@ -1144,6 +1154,8 @@ async function createRemoteSetupRunnerScript( fsProvider: IFilesystemProvider ): Promise { const useWindowsFormat = isWindowsAbsolutePathLike(worktreePath) + // Why: SSH terminals choose their shell on the remote host; local Windows + // preferences cannot safely select a remote runner format or launch command. const runnerRelativePath = useWindowsFormat ? 'orca/setup-runner.cmd' : 'orca/setup-runner.sh' const { stdout } = await gitProvider.exec( ['rev-parse', '--git-path', runnerRelativePath], @@ -2504,11 +2516,13 @@ export async function createLocalWorktree( try { // Why: main only writes the runner script and must not execute setup itself, or we reintroduce the old hidden background-hook behavior. // Why: worktree already exists, so a runner-gen failure degrades to "created without setup launch" rather than failing creation. + // Why: both trailing args are optional — the shell is undefined off Windows. setup = createSetupRunnerScript( repo, worktreePath, setupScript, - ...localWorktreeGitOptionArgs + localWorktreeGitOptionArgs[0], + resolveSetupRunnerShell(settings) ) } catch (error) { console.error(`[hooks] Failed to prepare setup runner for ${worktreePath}:`, error) diff --git a/src/main/ipc/worktrees-windows.test.ts b/src/main/ipc/worktrees-windows.test.ts index 0298baa40bd..ee9540048cd 100644 --- a/src/main/ipc/worktrees-windows.test.ts +++ b/src/main/ipc/worktrees-windows.test.ts @@ -20,6 +20,7 @@ const { getDefaultTabsLaunchMock, createIssueCommandRunnerScriptMock, createSetupRunnerScriptMock, + resolveSetupRunnerShellMock, shouldRunSetupForCreateMock, runHookMock, hasHooksFileMock, @@ -49,6 +50,7 @@ const { getDefaultTabsLaunchMock: vi.fn(), createIssueCommandRunnerScriptMock: vi.fn(), createSetupRunnerScriptMock: vi.fn(), + resolveSetupRunnerShellMock: vi.fn(), shouldRunSetupForCreateMock: vi.fn(), runHookMock: vi.fn(), hasHooksFileMock: vi.fn(), @@ -110,6 +112,7 @@ vi.mock('../hooks', () => ({ loadHooks: loadHooksMock, runHook: runHookMock, hasHooksFile: hasHooksFileMock, + resolveSetupRunnerShell: resolveSetupRunnerShellMock, shouldRunSetupForCreate: shouldRunSetupForCreateMock })) @@ -177,6 +180,7 @@ describe('registerWorktreeHandlers – Windows path handling', () => { getDefaultTabsLaunchMock.mockReset() createIssueCommandRunnerScriptMock.mockReset() createSetupRunnerScriptMock.mockReset() + resolveSetupRunnerShellMock.mockReset() shouldRunSetupForCreateMock.mockReset() runHookMock.mockReset() hasHooksFileMock.mockReset() @@ -230,6 +234,7 @@ describe('registerWorktreeHandlers – Windows path handling', () => { refreshLocalBaseRefOnWorktreeCreate: false, workspaceDir: 'C:\\workspaces' }) + resolveSetupRunnerShellMock.mockReturnValue(undefined) store.getWorktreeMeta.mockReturnValue(undefined) store.setWorktreeMeta.mockReturnValue({}) resolveLocalGitUsernameMock.mockResolvedValue('') @@ -345,6 +350,61 @@ describe('registerWorktreeHandlers – Windows path handling', () => { ) }) + it('passes the configured Windows setup shell into local setup runner generation', async () => { + const setupShell = { family: 'posix' as const } + store.getSettings.mockReturnValue({ + branchPrefix: 'none', + nestWorkspaces: false, + refreshLocalBaseRefOnWorktreeCreate: false, + terminalWindowsShell: 'git-bash', + workspaceDir: 'C:\\workspaces' + }) + resolveSetupRunnerShellMock.mockReturnValue(setupShell) + listWorktreesMock.mockResolvedValue([ + { + path: 'C:/workspaces/improve-dashboard', + head: 'abc123', + branch: 'refs/heads/improve-dashboard', + isBare: false, + isMainWorktree: false + } + ]) + getEffectiveHooksMock.mockReturnValue({ scripts: { setup: 'pnpm install' } }) + getEffectiveHooksFromConfigMock.mockReturnValue({ scripts: { setup: 'pnpm install' } }) + shouldRunSetupForCreateMock.mockReturnValue(true) + createSetupRunnerScriptMock.mockReturnValue({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: setupShell, + envVars: { + ORCA_ROOT_PATH: 'C:\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspaces\\improve-dashboard' + } + }) + + const result = await handlers['worktrees:create'](null, { + repoId: 'repo-1', + name: 'improve-dashboard', + setupDecision: 'run' + }) + + expect(resolveSetupRunnerShellMock).toHaveBeenCalledWith( + expect.objectContaining({ terminalWindowsShell: 'git-bash' }) + ) + expect(createSetupRunnerScriptMock).toHaveBeenCalledWith( + expect.objectContaining({ id: 'repo-1' }), + 'C:\\workspaces\\improve-dashboard', + 'pnpm install', + undefined, + setupShell + ) + expect(result).toMatchObject({ + setup: { + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: setupShell + } + }) + }) + it('preserves create-time metadata on the next list when Windows path formatting differs', async () => { const worktreeEntry = { path: 'C:/workspaces/improve-dashboard', @@ -439,4 +499,29 @@ describe('registerWorktreeHandlers – Windows path handling', () => { repoId: 'repo-1' }) }) + it('gives the issue-command runner the same setup shell as the setup runner', () => { + // Regression (C4): native Windows issue runners stayed .cmd even when setup + // resolved to Git Bash, so same-session bash issue templates broke. + resolveSetupRunnerShellMock.mockReturnValue({ family: 'posix' }) + createIssueCommandRunnerScriptMock.mockReturnValue({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\issue-command-runner.sh', + envVars: {}, + shell: { family: 'posix' } + }) + + handlers['hooks:createIssueCommandRunner'](null, { + repoId: 'repo-1', + worktreePath: 'C:\\workspaces\\improve-dashboard', + command: 'gh issue view 42' + }) + + expect(resolveSetupRunnerShellMock).toHaveBeenCalledWith(store.getSettings()) + expect(createIssueCommandRunnerScriptMock).toHaveBeenCalledWith( + expect.objectContaining({ id: 'repo-1' }), + 'C:\\workspaces\\improve-dashboard', + 'gh issue view 42', + expect.anything(), + { family: 'posix' } + ) + }) }) diff --git a/src/main/ipc/worktrees.test.ts b/src/main/ipc/worktrees.test.ts index 7e50c874f34..c83eece63b6 100644 --- a/src/main/ipc/worktrees.test.ts +++ b/src/main/ipc/worktrees.test.ts @@ -50,6 +50,7 @@ const { buildPosixRunnerScriptMock, buildWindowsRunnerScriptMock, getSetupRunnerEnvVarsMock, + resolveSetupRunnerShellMock, runHookMock, hasHooksFileMock, loadHooksMock, @@ -100,6 +101,7 @@ const { buildPosixRunnerScriptMock: vi.fn(), buildWindowsRunnerScriptMock: vi.fn(), getSetupRunnerEnvVarsMock: vi.fn(), + resolveSetupRunnerShellMock: vi.fn(), runHookMock: vi.fn(), hasHooksFileMock: vi.fn(), loadHooksMock: vi.fn(), @@ -199,6 +201,7 @@ vi.mock('../hooks', () => ({ getSetupRunnerEnvVars: getSetupRunnerEnvVarsMock, loadHooks: loadHooksMock, parseOrcaYaml: parseOrcaYamlMock, + resolveSetupRunnerShell: resolveSetupRunnerShellMock, runHook: runHookMock, hasHooksFile: hasHooksFileMock, shouldRunSetupForCreate: shouldRunSetupForCreateMock @@ -369,6 +372,7 @@ describe('registerWorktreeHandlers', () => { buildPosixRunnerScriptMock, buildWindowsRunnerScriptMock, getSetupRunnerEnvVarsMock, + resolveSetupRunnerShellMock, shouldRunSetupForCreateMock, runHookMock, hasHooksFileMock, @@ -484,6 +488,7 @@ describe('registerWorktreeHandlers', () => { (script: string) => `#!/usr/bin/env bash\nset -e\n${script.replace(/\r\n/g, '\n')}\n` ) buildWindowsRunnerScriptMock.mockImplementation((script: string) => script) + resolveSetupRunnerShellMock.mockReturnValue(undefined) getSetupRunnerEnvVarsMock.mockImplementation( (repoArg: { path: string }, worktreePath: string) => ({ ORCA_ROOT_PATH: repoArg.path, @@ -1226,10 +1231,11 @@ describe('registerWorktreeHandlers', () => { getEffectiveHooksFromConfigMock.mockReturnValue({ scripts: { setup: 'pnpm install' } }) shouldRunSetupForCreateMock.mockReturnValue(true) createSetupRunnerScriptMock.mockReturnValueOnce({ - runnerScriptPath: '/workspace/repo/.git/orca/setup-runner.sh', + runnerScriptPath: 'C:\\workspace\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix', executable: 'wsl.exe' }, envVars: { - ORCA_ROOT_PATH: '/workspace/repo', - ORCA_WORKTREE_PATH: '/workspace/improve-dashboard' + ORCA_ROOT_PATH: 'C:\\workspace\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspace\\improve-dashboard' }, waitForAgentStartup: true }) @@ -1254,8 +1260,8 @@ describe('registerWorktreeHandlers', () => { expect(result.setup).toEqual( expect.objectContaining({ - runnerScriptPath: '/workspace/repo/.git/orca/setup-runner.sh', - command: expect.stringContaining('bash /workspace/repo/.git/orca/setup-runner.sh') + runnerScriptPath: 'C:\\workspace\\repo\\.git\\orca\\setup-runner.sh', + command: expect.stringContaining('bash /mnt/c/workspace/repo/.git/orca/setup-runner.sh') }) ) expect(result.setup?.command).toContain('printf') @@ -4944,6 +4950,103 @@ describe('registerWorktreeHandlers', () => { ) }) + it('keeps Windows SSH setup runners independent from the local Git Bash setting', async () => { + const repo = { + id: 'repo-ssh', + path: 'C:\\remote\\repo', + displayName: 'ssh', + badgeColor: '#000', + addedAt: 0, + connectionId: 'conn-1', + worktreeBaseRef: 'origin/main' + } + const provider = { + exec: vi.fn().mockImplementation(async (args: string[]) => { + if (args[0] === 'remote') { + return { stdout: 'origin\n', stderr: '' } + } + if (args[0] === 'rev-parse' && args[1] === '--git-path') { + return { + stdout: + 'C:\\remote\\repo\\.git\\worktrees\\improve-dashboard\\orca\\setup-runner.cmd\n', + stderr: '' + } + } + if (args[0] === 'rev-parse') { + throw new Error('missing local branch') + } + return { stdout: '', stderr: '' } + }), + fetchRemoteTrackingRef: vi.fn().mockResolvedValue(undefined), + addWorktree: vi.fn().mockResolvedValue(undefined), + listWorktrees: vi.fn().mockResolvedValue([ + { + path: 'C:\\remote\\improve-dashboard', + head: 'abc123', + branch: 'refs/heads/improve-dashboard', + isBare: false, + isMainWorktree: false + } + ]) + } + const fsProvider = { + readFile: vi.fn().mockResolvedValue({ + content: 'scripts:\n setup: pnpm install\n', + isBinary: false + }), + createDir: vi.fn().mockResolvedValue(undefined), + writeFile: vi.fn().mockResolvedValue(undefined) + } + store.getRepos.mockReturnValue([repo]) + store.getRepo.mockReturnValue(repo) + store.getSettings.mockReturnValue({ + branchPrefix: 'none', + nestWorkspaces: false, + refreshLocalBaseRefOnWorktreeCreate: false, + terminalWindowsShell: 'git-bash', + workspaceDir: 'C:\\workspace' + }) + getSshGitProviderMock.mockReturnValue(provider) + getSshFilesystemProviderMock.mockReturnValue(fsProvider) + getActiveMultiplexerMock.mockReturnValue({ + request: vi.fn().mockResolvedValue(undefined), + notify: vi.fn() + }) + store.setWorktreeMeta.mockImplementation((_worktreeId, meta) => meta) + parseOrcaYamlMock.mockReturnValue({ scripts: { setup: 'pnpm install' } }) + getEffectiveHooksFromConfigMock.mockReturnValue({ scripts: { setup: 'pnpm install' } }) + shouldRunSetupForCreateMock.mockReturnValue(true) + resolveSetupRunnerShellMock.mockReturnValue({ family: 'posix' }) + + const result = await handlers['worktrees:create'](null, { + repoId: 'repo-ssh', + name: 'improve-dashboard', + setupDecision: 'run' + }) + + expect(provider.exec).toHaveBeenCalledWith( + ['rev-parse', '--git-path', 'orca/setup-runner.cmd'], + 'C:\\remote\\improve-dashboard' + ) + expect(fsProvider.writeFile).toHaveBeenCalledWith( + 'C:\\remote\\repo\\.git\\worktrees\\improve-dashboard\\orca\\setup-runner.cmd', + 'pnpm install' + ) + expect(resolveSetupRunnerShellMock).not.toHaveBeenCalled() + expect(result).toEqual( + expect.objectContaining({ + setup: { + runnerScriptPath: + 'C:\\remote\\repo\\.git\\worktrees\\improve-dashboard\\orca\\setup-runner.cmd', + envVars: expect.objectContaining({ + ORCA_ROOT_PATH: 'C:\\remote\\repo', + ORCA_WORKTREE_PATH: 'C:\\remote\\improve-dashboard' + }) + } + }) + ) + }) + it('creates sparse checkout metadata and remote sparse config for SSH worktrees', async () => { const repo = { id: 'repo-ssh', @@ -6642,7 +6745,9 @@ describe('registerWorktreeHandlers', () => { expect.objectContaining({ id: 'repo-1' }), '/workspace/improve-dashboard', 'codex exec "long command"', - {} + {}, + // Why: issue runners take the resolved setup shell; it is undefined off Windows. + undefined ) expect(result).toMatchObject({ runnerScriptPath: '/workspace/repo/.git/orca/issue-command-runner.sh', @@ -7621,7 +7726,9 @@ describe('registerWorktreeHandlers', () => { expect(createSetupRunnerScriptMock).toHaveBeenCalledWith( expect.objectContaining({ id: 'repo-1' }), '/workspace/improve-dashboard', - 'pnpm worktree:setup' + 'pnpm worktree:setup', + undefined, + undefined ) expect(result).toMatchObject({ worktree: expect.objectContaining({ @@ -7682,7 +7789,8 @@ describe('registerWorktreeHandlers', () => { expect.objectContaining({ id: 'repo-1' }), '/workspace/improve-dashboard', 'pnpm worktree:setup', - { wslDistro: 'Ubuntu' } + { wslDistro: 'Ubuntu' }, + undefined ) expect(addWorktreeMock).toHaveBeenCalledWith( '/workspace/repo', @@ -7719,7 +7827,9 @@ describe('registerWorktreeHandlers', () => { expect(createSetupRunnerScriptMock).toHaveBeenCalledWith( expect.objectContaining({ id: 'repo-1' }), '/workspace/improve-dashboard', - 'pnpm worktree:setup # worktree' + 'pnpm worktree:setup # worktree', + undefined, + undefined ) expect(result).toEqual( expect.objectContaining({ @@ -8240,6 +8350,7 @@ describe('registerWorktreeHandlers', () => { expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith(worktreeId, { runtime: runtimeStub, + resolvedWorktreeId: worktreeId, localProvider: ptyProvider, onPtyStopped: clearProviderPtyStateMock }) @@ -8254,6 +8365,69 @@ describe('registerWorktreeHandlers', () => { }) }) + // Folder projects can be SSH-backed, and folder workspace ids are `repoId::path::workspace:` + // — reusable across hosts — so the sweep must name the owning connection. + it('fences an SSH folder workspace PTY sweep to the owning connection', async () => { + const sshPtyProvider = { id: 'ssh-pty-provider' } as never + const worktreeId = 'repo-folder::/remote/folder::workspace:child-1' + store.getRepo.mockReturnValue({ + id: 'repo-folder', + path: '/remote/folder', + displayName: 'folder', + badgeColor: '#000', + addedAt: 0, + kind: 'folder', + connectionId: 'conn-1' + }) + getSshPtyProviderMock.mockReturnValue(sshPtyProvider) + // One global meta key can describe the same-id local copy; the resolved repo still owns this delete. + store.getWorktreeMeta.mockReturnValue(makeWorktreeMeta({ hostId: 'local' })) + + await handlers['worktrees:remove'](null, { worktreeId }) + + expect(getSshPtyProviderMock).toHaveBeenCalledWith('conn-1') + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith(worktreeId, { + runtime: runtimeStub, + resolvedWorktreeId: worktreeId, + resolvedConnectionId: 'conn-1', + localProvider: sshPtyProvider, + onPtyStopped: clearProviderPtyStateMock, + includeProviderInventory: true, + includeLocalRegistry: false + }) + }) + + it('fences a mirrored runtime folder workspace sweep to its environment', async () => { + const runtimePtyProvider = {} as never + const worktreeId = 'repo-folder::/runtime/folder::workspace:child-1' + store.getRepo.mockReturnValue({ + id: 'repo-folder', + path: '/runtime/folder', + displayName: 'folder', + badgeColor: '#000', + addedAt: 0, + kind: 'folder', + executionHostId: 'runtime:env-1' + }) + getLocalPtyProviderMock.mockReturnValue(runtimePtyProvider) + + await handlers['worktrees:remove'](null, { + worktreeId, + hostId: 'runtime:env-1' + }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith(worktreeId, { + runtime: runtimeStub, + resolvedWorktreeId: worktreeId, + resolvedRuntimeEnvironmentId: 'env-1', + localProvider: runtimePtyProvider, + onPtyStopped: clearProviderPtyStateMock, + includeProviderInventory: false, + includeLocalRegistry: false + }) + expect(getSshPtyProviderMock).not.toHaveBeenCalled() + }) + it('runs the archive hook on remove when skipArchive is not set', async () => { mockKnownFeatureWorktree() removeWorktreeMock.mockResolvedValue(undefined) @@ -9840,6 +10014,120 @@ describe('registerWorktreeHandlers', () => { expect(callOrder).toEqual(['preflight', 'kill', 'git']) }) + // Regression: `repoId::path` ids repeat across hosts, so an SSH delete used to reach the + // runtime's same-id local (or other-connection) terminals and stop them. + it('fences an SSH worktree delete PTY sweep to the owning connection', async () => { + const repo = { + id: 'repo-ssh', + path: '/remote/repo', + displayName: 'ssh', + badgeColor: '#000', + addedAt: 0, + connectionId: 'conn-1', + worktreeBaseRef: null + } + const sshPtyProvider = { id: 'ssh-pty-provider' } as never + store.getRepos.mockReturnValue([repo]) + store.getRepo.mockReturnValue(repo) + getSshGitProviderMock.mockReturnValue({ + listWorktrees: vi.fn().mockResolvedValue([ + { path: '/remote/repo', head: 'main', branch: 'main', isBare: false, isMainWorktree: true }, + { + path: '/remote/feature-wt', + head: 'feature', + branch: 'feature', + isBare: false, + isMainWorktree: false + } + ]), + removeWorktree: vi.fn().mockResolvedValue({}), + worktreeIsClean: vi.fn().mockResolvedValue({ clean: true }) + }) + getSshPtyProviderMock.mockReturnValue(sshPtyProvider) + getEffectiveHooksFromConfigMock.mockReturnValue(null) + + await handlers['worktrees:remove'](null, { worktreeId: 'repo-ssh::/remote/feature-wt' }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith('repo-ssh::/remote/feature-wt', { + runtime: runtimeStub, + resolvedWorktreeId: 'repo-ssh::/remote/feature-wt', + resolvedConnectionId: 'conn-1', + localProvider: sshPtyProvider, + onPtyStopped: clearProviderPtyStateMock, + requirePhysicalStop: true, + includeLocalRegistry: false + }) + }) + + // The local counterpart still identifies itself by exact id so a selector that resolves + // two hosts can no longer decide which workspace loses its terminals. + it('pins a local worktree delete PTY sweep to the exact worktree id', async () => { + mockKnownFeatureWorktree() + getEffectiveHooksMock.mockReturnValue(null) + removeWorktreeMock.mockResolvedValue({}) + + await handlers['worktrees:remove'](null, { worktreeId: 'repo-1::/workspace/feature-wt' }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith( + 'repo-1::/workspace/feature-wt', + expect.objectContaining({ resolvedWorktreeId: 'repo-1::/workspace/feature-wt' }) + ) + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith( + 'repo-1::/workspace/feature-wt', + expect.not.objectContaining({ resolvedConnectionId: expect.anything() }) + ) + }) + + // Why (#11960): the PTY gate previously had no escape hatch at all, so a + // workspace with an unprovable PTY was unremovable forever. + it('forwards an explicit Force Delete to the PTY gate', async () => { + mockKnownFeatureWorktree() + getEffectiveHooksMock.mockReturnValue(null) + + await handlers['worktrees:remove'](null, { + worktreeId: 'repo-1::/workspace/feature-wt', + force: true, + allowUnverifiedPtyStop: true + }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith( + 'repo-1::/workspace/feature-wt', + expect.objectContaining({ requirePhysicalStop: true, allowUnverifiedStop: true }) + ) + }) + + // Why (#11960): the ordinary Delete confirmation already sets force:true to skip + // the dirty-file prompt. Waiving PTY-stop proof off that signal would silently + // disable the gate on the primary delete path. + it('keeps the PTY gate strict for a confirmed delete that only sets force', async () => { + mockKnownFeatureWorktree() + getEffectiveHooksMock.mockReturnValue(null) + + await handlers['worktrees:remove'](null, { + worktreeId: 'repo-1::/workspace/feature-wt', + force: true + }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith( + 'repo-1::/workspace/feature-wt', + expect.not.objectContaining({ allowUnverifiedStop: true }) + ) + }) + + it('keeps the PTY gate strict for a plain delete', async () => { + mockKnownFeatureWorktree() + getEffectiveHooksMock.mockReturnValue(null) + + await handlers['worktrees:remove'](null, { + worktreeId: 'repo-1::/workspace/feature-wt' + }) + + expect(killAllProcessesForWorktreeMock).toHaveBeenCalledWith( + 'repo-1::/workspace/feature-wt', + expect.not.objectContaining({ allowUnverifiedStop: true }) + ) + }) + it('does not start Git removal when physical PTY teardown cannot be proven', async () => { mockKnownFeatureWorktree() getEffectiveHooksMock.mockReturnValue(null) diff --git a/src/main/ipc/worktrees.ts b/src/main/ipc/worktrees.ts index fe2d6d5fff3..c8dceec6bed 100644 --- a/src/main/ipc/worktrees.ts +++ b/src/main/ipc/worktrees.ts @@ -91,6 +91,7 @@ import { loadHooks, parseOrcaYaml, readIssueCommand, + resolveSetupRunnerShell, runHook, hasHooksFile, hasUnrecognizedOrcaYamlKeys, @@ -149,6 +150,8 @@ type RemoveWorktreeArgs = { worktreeId: string hostId?: ExecutionHostId force?: boolean + /** Explicit Force Delete only — `force` alone is set by the ordinary confirmation (#11960). */ + allowUnverifiedPtyStop?: boolean skipArchive?: boolean } @@ -157,17 +160,26 @@ type DetectedWorktreeRequestArgs = { repoId: string } | ListDetectedWorktreesArg async function stopPtysForDestructiveWorktreeRemoval( runtime: OrcaRuntimeService, worktreeId: string, - connectionId?: string + options: { connectionId?: string; allowUnverifiedStop?: boolean } = {} ): Promise { + const { connectionId, allowUnverifiedStop } = options const provider = connectionId ? getSshPtyProvider(connectionId) : getLocalPtyProvider() if (!provider) { throw new Error(`PTY provider unavailable for worktree deletion: ${worktreeId}`) } const teardownResult = await killAllProcessesForWorktree(worktreeId, { runtime, + // Why: `repoId::path` ids repeat across hosts, so an unfenced sweep stops a same-id + // workspace's terminals on another connection — and the selector lookup this replaces + // throws `selector_ambiguous` the moment two hosts own the id. + resolvedWorktreeId: worktreeId, + ...(connectionId ? { resolvedConnectionId: connectionId } : {}), localProvider: provider, onPtyStopped: clearProviderPtyState, requirePhysicalStop: true, + // Why (#11960): set only by an explicit Force Delete, never by the ordinary + // confirmation — otherwise the gate would be off on the primary delete path. + ...(allowUnverifiedStop ? { allowUnverifiedStop: true } : {}), ...(connectionId ? { includeLocalRegistry: false } : {}) }) const total = @@ -418,10 +430,17 @@ function gitStatusErrorMeansNotRepository(error: unknown): boolean { return /not a git repository/i.test(`${message}\n${stderr}`) } -function getWorktreeRemovalOptionsKey(args: { force?: boolean; skipArchive?: boolean }): string { +function getWorktreeRemovalOptionsKey(args: { + force?: boolean + allowUnverifiedPtyStop?: boolean + skipArchive?: boolean +}): string { const forceKey = args.force === true ? 'force' : 'normal' const archiveKey = args.skipArchive === true ? 'skip-archive' : 'run-archive' - return `${forceKey}:${archiveKey}` + // Why: a Force Delete retry must not coalesce onto the in-flight attempt that + // just failed the PTY gate — it would inherit that failure instead of retrying. + const ptyKey = args.allowUnverifiedPtyStop === true ? 'allow-unverified-pty' : 'require-pty-stop' + return `${forceKey}:${archiveKey}:${ptyKey}` } function getWorktreeRemovalInFlightKey(worktreeId: string, hostId?: ExecutionHostId): string { @@ -2276,10 +2295,30 @@ export function registerWorktreeHandlers( } // Why: folder workspaces share one root, so there's no Git remove step to close shells; sweep PTYs before dropping metadata. await withWorktreeRemoveStageSpan('pty_sweep', 'folder', async () => { + // Folder projects can be SSH-backed, so fence the sweep to the owning host exactly + // like the git paths — the local inventory must never reach a remote workspace's id. + // The resolved repo is authoritative here: path-derived metadata is shared by + // same-id host copies and can describe a different owner's workspace. + const ownerHost = parseExecutionHostId(removalHostId) + const sshPtyProvider = + ownerHost?.kind === 'ssh' ? getSshPtyProvider(ownerHost.targetId) : undefined + const externalHost = ownerHost?.kind === 'ssh' || ownerHost?.kind === 'runtime' await killAllProcessesForWorktree(args.worktreeId, { runtime, - localProvider: getLocalPtyProvider(), - onPtyStopped: clearProviderPtyState + resolvedWorktreeId: args.worktreeId, + ...(ownerHost?.kind === 'ssh' ? { resolvedConnectionId: ownerHost.targetId } : {}), + ...(ownerHost?.kind === 'runtime' + ? { resolvedRuntimeEnvironmentId: ownerHost.environmentId } + : {}), + localProvider: sshPtyProvider ?? getLocalPtyProvider(), + onPtyStopped: clearProviderPtyState, + ...(externalHost + ? { + includeProviderInventory: + ownerHost?.kind === 'ssh' && Boolean(sshPtyProvider), + includeLocalRegistry: false + } + : {}) }).catch((err) => { console.warn(`[worktree-teardown] failed for ${args.worktreeId}:`, err) }) @@ -2357,11 +2396,10 @@ export function registerWorktreeHandlers( ) let removalCompleted = false try { - await stopPtysForDestructiveWorktreeRemoval( - runtime, - args.worktreeId, - repo.connectionId - ) + await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId, { + connectionId: repo.connectionId, + allowUnverifiedStop: args.allowUnverifiedPtyStop + }) await fsProvider!.deletePath(worktreePath, true) removalCompleted = true } finally { @@ -2378,7 +2416,9 @@ export function registerWorktreeHandlers( const removalGate = await runtime.acquireFileWatcherRemoval(worktreePath) let removalCompleted = false try { - await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId) + await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId, { + allowUnverifiedStop: args.allowUnverifiedPtyStop + }) await removeLocalWorktreePath(worktreePath, localWorktreeGitOptions) removalCompleted = true } finally { @@ -2423,7 +2463,9 @@ export function registerWorktreeHandlers( const removalGate = await runtime.acquireFileWatcherRemoval(worktreePath) let removalCompleted = false try { - await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId) + await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId, { + allowUnverifiedStop: args.allowUnverifiedPtyStop + }) await removeLocalWorktreePath(worktreePath, localWorktreeGitOptions) removalCompleted = true } finally { @@ -2581,11 +2623,10 @@ export function registerWorktreeHandlers( let removalCompleted = false try { await withWorktreeRemoveStageSpan('pty_sweep', 'remote', async () => { - await stopPtysForDestructiveWorktreeRemoval( - runtime, - args.worktreeId, - remoteConnectionId - ) + await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId, { + connectionId: remoteConnectionId, + allowUnverifiedStop: args.allowUnverifiedPtyStop + }) }) rawRemovalResult = await withWorktreeRemoveStageSpan( 'git_remove', @@ -2688,7 +2729,9 @@ export function registerWorktreeHandlers( // Why: hold the watcher/terminal gate through Git and any recursive fallback so no late spawn recreates a native handle. // Linked-path deletion is destructive too, so PTYs must release every handle before Windows or WSL filesystem cleanup starts. await withWorktreeRemoveStageSpan('pty_sweep', 'local', async () => { - await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId) + await stopPtysForDestructiveWorktreeRemoval(runtime, args.worktreeId, { + allowUnverifiedStop: args.allowUnverifiedPtyStop + }) }) // Why: preflight only ignored these paths, not mutated them; keep watcher installs fenced through Git removal. @@ -3118,7 +3161,8 @@ export function registerWorktreeHandlers( repo, args.worktreePath, args.command, - getLocalProjectWorktreeGitOptions(store, repo) + getLocalProjectWorktreeGitOptions(store, repo), + resolveSetupRunnerShell(store.getSettings()) ) } ) diff --git a/src/main/linux-package-install-command.test.ts b/src/main/linux-package-install-command.test.ts new file mode 100644 index 00000000000..368e6620fd5 --- /dev/null +++ b/src/main/linux-package-install-command.test.ts @@ -0,0 +1,254 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const { statSyncMock } = vi.hoisted(() => ({ statSyncMock: vi.fn() })) + +vi.mock('node:fs', () => ({ statSync: statSyncMock })) + +// Executables the fake filesystem exposes, keyed by absolute path. +let executables: Map + +function install(absolutePath: string, options?: { file?: boolean; mode?: number }): void { + executables.set(absolutePath, { file: options?.file ?? true, mode: options?.mode ?? 0o755 }) +} + +async function loadCommandModule() { + return import('./linux-package-install-command') +} + +beforeEach(() => { + vi.resetModules() + executables = new Map() + statSyncMock.mockReset().mockImplementation((candidate: string) => { + const entry = executables.get(candidate) + if (!entry) { + const error = new Error(`ENOENT: ${candidate}`) as NodeJS.ErrnoException + error.code = 'ENOENT' + throw error + } + return { isFile: () => entry.file, mode: entry.mode } + }) +}) + +afterEach(() => { + vi.restoreAllMocks() + vi.unstubAllEnvs() +}) + +describe('quoteForPosixShell', () => { + it('wraps plain values in single quotes', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell('/tmp/orca.deb')).toBe("'/tmp/orca.deb'") + }) + + it('quotes spaces', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell('/tmp/Orca Setup.deb')).toBe("'/tmp/Orca Setup.deb'") + }) + + it('neutralizes expansion, command substitution, separators, and double quotes', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell('/tmp/$HOME.deb')).toBe("'/tmp/$HOME.deb'") + expect(quoteForPosixShell('/tmp/`id`.deb')).toBe("'/tmp/`id`.deb'") + expect(quoteForPosixShell('/tmp/a;rm -rf ~.deb')).toBe("'/tmp/a;rm -rf ~.deb'") + expect(quoteForPosixShell('/tmp/"quoted".deb')).toBe('\'/tmp/"quoted".deb\'') + }) + + it('closes and reopens the quote around a literal single quote', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell("/tmp/it's.deb")).toBe(`'/tmp/it'"'"'s.deb'`) + }) + + it('escapes every single quote in a value', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell("'; rm -rf /; '")).toBe(`''"'"'; rm -rf /; '"'"''`) + }) + + it('quotes an empty value', async () => { + const { quoteForPosixShell } = await loadCommandModule() + expect(quoteForPosixShell('')).toBe("''") + }) +}) + +describe('resolveTrustedExecutable', () => { + it('resolves from /usr/bin first', async () => { + install('/usr/bin/sudo') + install('/bin/sudo') + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('sudo')).toBe('/usr/bin/sudo') + }) + + it('falls through the remaining trusted directories', async () => { + install('/sbin/dpkg') + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('dpkg')).toBe('/sbin/dpkg') + }) + + it('consults only the trusted directories', async () => { + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('sudo')).toBeNull() + expect(statSyncMock.mock.calls.map((call) => call[0])).toEqual([ + '/usr/bin/sudo', + '/bin/sudo', + '/usr/sbin/sudo', + '/sbin/sudo' + ]) + }) + + it('ignores a user-writable absolute PATH decoy', async () => { + install('/home/user/.local/bin/sudo') + vi.stubEnv('PATH', '/home/user/.local/bin:/usr/bin') + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('sudo')).toBeNull() + expect(statSyncMock).not.toHaveBeenCalledWith('/home/user/.local/bin/sudo') + }) + + it('rejects a non-executable file', async () => { + install('/usr/bin/apt', { mode: 0o644 }) + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('apt')).toBeNull() + }) + + it('accepts a file executable only by group or other', async () => { + install('/usr/bin/apt', { mode: 0o011 }) + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('apt')).toBe('/usr/bin/apt') + }) + + it('rejects a directory of the same name', async () => { + install('/usr/bin/apt', { file: false }) + const { resolveTrustedExecutable } = await loadCommandModule() + expect(resolveTrustedExecutable('apt')).toBeNull() + }) +}) + +describe('buildLinuxPackageInstallCommand', () => { + it('refuses a non-absolute package path before looking for anything', async () => { + // Why: zypper/dnf/yum/rpm take no `--`, so a relative or dash-leading path would become an option. + install('/usr/bin/sudo') + install('/usr/bin/apt') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + for (const packagePath of ['orca.deb', './orca.deb', '--force-all', '-i']) { + expect(buildLinuxPackageInstallCommand('deb', packagePath)).toEqual({ + ok: false, + reason: 'invalid-package-path' + }) + } + }) + + it('reports no-sudo when sudo is absent', async () => { + install('/usr/bin/apt') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb')).toEqual({ + ok: false, + reason: 'no-sudo' + }) + }) + + it('reports no-package-manager when no manager is installed', async () => { + install('/usr/bin/sudo') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb')).toEqual({ + ok: false, + reason: 'no-package-manager' + }) + }) + + it('does not fall back to an rpm manager for a deb package', async () => { + install('/usr/bin/sudo') + install('/usr/bin/dnf') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb')).toEqual({ + ok: false, + reason: 'no-package-manager' + }) + }) + + it('builds an apt command', async () => { + install('/usr/bin/sudo') + install('/usr/bin/apt') + install('/usr/bin/dpkg') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb')).toEqual({ + ok: true, + command: "/usr/bin/sudo /usr/bin/apt install -- '/tmp/orca.deb'" + }) + }) + + it('falls back to dpkg', async () => { + install('/usr/bin/sudo') + install('/usr/bin/dpkg') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb')).toEqual({ + ok: true, + command: "/usr/bin/sudo /usr/bin/dpkg -i -- '/tmp/orca.deb'" + }) + }) + + it('builds a zypper command', async () => { + install('/usr/bin/sudo') + install('/usr/bin/zypper') + install('/usr/bin/dnf') + install('/usr/bin/yum') + install('/usr/bin/rpm') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('rpm', '/tmp/orca.rpm')).toEqual({ + ok: true, + command: + "/usr/bin/sudo /usr/bin/zypper --no-refresh install --allow-unsigned-rpm -f '/tmp/orca.rpm'" + }) + }) + + it('prefers dnf over yum and rpm', async () => { + install('/usr/bin/sudo') + install('/usr/bin/dnf') + install('/usr/bin/yum') + install('/usr/bin/rpm') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('rpm', '/tmp/orca.rpm')).toEqual({ + ok: true, + command: "/usr/bin/sudo /usr/bin/dnf install --nogpgcheck '/tmp/orca.rpm'" + }) + }) + + it('falls back to yum', async () => { + install('/usr/bin/sudo') + install('/usr/bin/yum') + install('/usr/bin/rpm') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('rpm', '/tmp/orca.rpm')).toEqual({ + ok: true, + command: "/usr/bin/sudo /usr/bin/yum install --nogpgcheck '/tmp/orca.rpm'" + }) + }) + + it('falls back to rpm', async () => { + install('/usr/bin/sudo') + install('/sbin/rpm') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('rpm', '/tmp/orca.rpm')).toEqual({ + ok: true, + command: "/usr/bin/sudo /sbin/rpm -Uvh '/tmp/orca.rpm'" + }) + }) + + it('never adds an unattended-confirmation flag', async () => { + install('/usr/bin/sudo') + install('/usr/bin/apt') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + const result = buildLinuxPackageInstallCommand('deb', '/tmp/orca.deb') + expect(result.ok).toBe(true) + expect(result.ok ? result.command : '').not.toMatch( + /(^|\s)(-y|--yes|--noconfirm|--assumeyes)(\s|$)/ + ) + }) + + it('quotes a hostile package path', async () => { + install('/usr/bin/sudo') + install('/usr/bin/apt') + const { buildLinuxPackageInstallCommand } = await loadCommandModule() + expect(buildLinuxPackageInstallCommand('deb', "/tmp/a b'; id #.deb")).toEqual({ + ok: true, + command: `/usr/bin/sudo /usr/bin/apt install -- '/tmp/a b'"'"'; id #.deb'` + }) + }) +}) diff --git a/src/main/linux-package-install-command.ts b/src/main/linux-package-install-command.ts new file mode 100644 index 00000000000..6a0c6d2d526 --- /dev/null +++ b/src/main/linux-package-install-command.ts @@ -0,0 +1,83 @@ +import { statSync } from 'node:fs' +import path from 'node:path' +import type { LinuxRootPackageType } from '../shared/types' + +// Why: an absolute but user-writable PATH entry must never be treated as a trusted package manager. +const TRUSTED_EXECUTABLE_DIRECTORIES = ['/usr/bin', '/bin', '/usr/sbin', '/sbin'] + +const DEB_PACKAGE_MANAGERS: { name: string; args: string[] }[] = [ + { name: 'apt', args: ['install', '--'] }, + { name: 'dpkg', args: ['-i', '--'] } +] + +// No `--` terminator: these tools do not accept one. Safe because capture requires an absolute path, +// so the argument can never be read as an option. +const RPM_PACKAGE_MANAGERS: { name: string; args: string[] }[] = [ + { + name: 'zypper', + args: ['--no-refresh', 'install', '--allow-unsigned-rpm', '-f'] + }, + { name: 'dnf', args: ['install', '--nogpgcheck'] }, + { name: 'yum', args: ['install', '--nogpgcheck'] }, + { name: 'rpm', args: ['-Uvh'] } +] + +export type LinuxPackageInstallCommandResult = + | { ok: true; command: string } + | { ok: false; reason: 'no-sudo' | 'no-package-manager' | 'invalid-package-path' } + +/** POSIX single-quoting: the only metacharacter left is `'`, closed and re-opened around a literal. */ +export function quoteForPosixShell(value: string): string { + return `'${value.split("'").join(`'"'"'`)}'` +} + +/** + * Resolves an executable strictly from the trusted system directories. A symlink inside those + * directories is fine — its target is what `statSync` checks — but nothing outside them is consulted + * and no shell is ever invoked for discovery. + */ +export function resolveTrustedExecutable(name: string): string | null { + for (const directory of TRUSTED_EXECUTABLE_DIRECTORIES) { + // posix.join: these are POSIX paths, and this module only ever runs on Linux. + const candidate = path.posix.join(directory, name) + try { + const stats = statSync(candidate) + if (stats.isFile() && (stats.mode & 0o111) !== 0) { + return candidate + } + } catch { + // Absent here; keep looking in the remaining trusted directories. + } + } + return null +} + +/** + * Builds the interactive command the user pastes into their own terminal. Every token except the + * package path is a fixed literal, and the path is POSIX-single-quoted — Orca never runs this. + */ +export function buildLinuxPackageInstallCommand( + packageType: LinuxRootPackageType, + packagePath: string +): LinuxPackageInstallCommandResult { + // Why: several package managers accept no `--` terminator, so a relative or dash-leading path would + // be read as an option. Hold that property here rather than relying on a caller two modules away. + if (!path.isAbsolute(packagePath)) { + return { ok: false, reason: 'invalid-package-path' } + } + const sudoPath = resolveTrustedExecutable('sudo') + if (!sudoPath) { + return { ok: false, reason: 'no-sudo' } + } + const candidates = packageType === 'deb' ? DEB_PACKAGE_MANAGERS : RPM_PACKAGE_MANAGERS + for (const candidate of candidates) { + const managerPath = resolveTrustedExecutable(candidate.name) + if (!managerPath) { + continue + } + // No -y/--noconfirm: the user must see and confirm the privileged transaction. + const tokens = [sudoPath, managerPath, ...candidate.args, quoteForPosixShell(packagePath)] + return { ok: true, command: tokens.join(' ') } + } + return { ok: false, reason: 'no-package-manager' } +} diff --git a/src/main/linux-package-install-diagnostic.test.ts b/src/main/linux-package-install-diagnostic.test.ts new file mode 100644 index 00000000000..5b8e1b1c77b --- /dev/null +++ b/src/main/linux-package-install-diagnostic.test.ts @@ -0,0 +1,337 @@ +import os from 'node:os' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type * as DiagnosticModule from './linux-package-install-diagnostic' + +const ESC = String.fromCharCode(27) + +let diagnostic: typeof DiagnosticModule + +beforeEach(async () => { + vi.resetModules() + vi.spyOn(console, 'info').mockImplementation(() => {}) + vi.spyOn(console, 'warn').mockImplementation(() => {}) + vi.spyOn(console, 'error').mockImplementation(() => {}) + vi.spyOn(console, 'debug').mockImplementation(() => {}) + diagnostic = await import('./linux-package-install-diagnostic') +}) + +afterEach(() => { + vi.restoreAllMocks() +}) + +describe('redactLinuxPackageInstallText', () => { + it('strips ANSI escape sequences', () => { + const text = `${ESC}[31mdpkg: error${ESC}[0m processing` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe('dpkg: error processing') + }) + + it('strips ANSI sequences with private and intermediate bytes', () => { + const text = `${ESC}[?25lworking${ESC}[?25h` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe('working') + }) + + it('replaces control characters and collapses whitespace', () => { + const text = `line one\r\n\tline\u0000two spaced\u007f` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe('line one line two spaced') + }) + + it('replaces the cached package path with a placeholder', () => { + const packagePath = '/home/user/.cache/orca-updater/Orca-1.2.3.deb' + const text = `dpkg: error processing ${packagePath} (--install)` + expect(diagnostic.redactLinuxPackageInstallText(text, packagePath)).toBe( + 'dpkg: error processing (--install)' + ) + }) + + it('replaces every occurrence of the package path', () => { + const packagePath = '/tmp/orca.deb' + const text = `${packagePath} failed; retry ${packagePath}` + expect(diagnostic.redactLinuxPackageInstallText(text, packagePath)).toBe( + ' failed; retry ' + ) + }) + + it('replaces the home directory with a placeholder', () => { + const home = os.homedir() + const text = `could not read ${home}/.config/orca/settings.json` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe( + 'could not read /.config/orca/settings.json' + ) + }) + + it('prefers the package placeholder for a path inside the home directory', () => { + const home = os.homedir() + const packagePath = `${home}/.cache/orca-updater/Orca-1.2.3.deb` + expect(diagnostic.redactLinuxPackageInstallText(`install ${packagePath}`, packagePath)).toBe( + 'install ' + ) + }) + + it('replaces the bare username with a placeholder', () => { + // Why: sudo names the user without any path around it, so the rule never sees it. + vi.spyOn(os, 'userInfo').mockReturnValue({ username: 'devuser' } as os.UserInfo) + expect( + diagnostic.redactLinuxPackageInstallText('devuser is not in the sudoers file', null) + ).toBe(' is not in the sudoers file') + }) + + it('leaves a username shorter than three characters alone', () => { + // Short names would corrupt unrelated words. + vi.spyOn(os, 'userInfo').mockReturnValue({ username: 'ci' } as os.UserInfo) + expect(diagnostic.redactLinuxPackageInstallText('ci: incident in circuit', null)).toBe( + 'ci: incident in circuit' + ) + }) + + it('survives an unavailable user record', () => { + vi.spyOn(os, 'userInfo').mockImplementation(() => { + throw new Error('no passwd entry') + }) + expect(diagnostic.redactLinuxPackageInstallText('dpkg: unrecoverable error', null)).toBe( + 'dpkg: unrecoverable error' + ) + }) + + it('truncates to 1024 characters', () => { + const result = diagnostic.redactLinuxPackageInstallText('a'.repeat(2000), null) + expect(result).toHaveLength(1024) + }) + + it('keeps text at exactly the limit', () => { + const result = diagnostic.redactLinuxPackageInstallText('a'.repeat(1024), null) + expect(result).toHaveLength(1024) + }) + + it('returns null for empty and whitespace-only input', () => { + expect(diagnostic.redactLinuxPackageInstallText('', null)).toBeNull() + expect(diagnostic.redactLinuxPackageInstallText(' \n\t ', null)).toBeNull() + expect(diagnostic.redactLinuxPackageInstallText(`${ESC}[0m`, null)).toBeNull() + }) + + it('returns null for null and undefined', () => { + expect(diagnostic.redactLinuxPackageInstallText(null, null)).toBeNull() + expect(diagnostic.redactLinuxPackageInstallText(undefined, null)).toBeNull() + }) + + it('uses the message of an Error', () => { + expect(diagnostic.redactLinuxPackageInstallText(new Error('pkexec failed'), null)).toBe( + 'pkexec failed' + ) + }) + + it('serializes plain objects and other primitives', () => { + expect(diagnostic.redactLinuxPackageInstallText({ code: 127 }, null)).toBe('{"code":127}') + expect(diagnostic.redactLinuxPackageInstallText(127, null)).toBe('127') + }) + + it('returns null for an unserializable object', () => { + const circular: Record = {} + circular.self = circular + expect(diagnostic.redactLinuxPackageInstallText(circular, null)).toBeNull() + }) + + it('strips an OSC hyperlink along with its URL payload', () => { + const BEL = String.fromCharCode(7) + const text = `${ESC}]8;;https://tracker.invalid/report${BEL}dpkg: error${ESC}]8;;${BEL} processing` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe('dpkg: error processing') + }) + + it('strips a string-terminated DCS sequence and a two-byte escape', () => { + const text = `${ESC}P1;2|payload${ESC}\\dpkg${ESC}c: error` + expect(diagnostic.redactLinuxPackageInstallText(text, null)).toBe('dpkg: error') + }) + + it('ignores an empty package path', () => { + expect(diagnostic.redactLinuxPackageInstallText('plain output', '')).toBe('plain output') + }) +}) + +describe('createUpdaterDiagnosticLogger', () => { + it('retains redacted error output while capturing', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture('/tmp/orca.deb') + logger.error(`${ESC}[31mpkexec: /tmp/orca.deb not authorized${ESC}[0m`) + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: 'pkexec: not authorized', + reason: 'authentication-denied' + }) + }) + + it('ignores non-error levels', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.info('downloading') + logger.warn('retrying') + logger.debug('verbose') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toBeNull() + }) + + it('still forwards every level to the console', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + logger.info('a') + logger.warn('b') + logger.error('c') + logger.debug('d') + expect(console.info).toHaveBeenCalledWith('[autoUpdater]', 'a') + expect(console.warn).toHaveBeenCalledWith('[autoUpdater]', 'b') + expect(console.error).toHaveBeenCalledWith('[autoUpdater]', 'c') + expect(console.debug).toHaveBeenCalledWith('[autoUpdater]', 'd') + }) + + it('retains nothing outside a capture window', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + logger.error('unrelated failure') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toBeNull() + }) + + it('keeps the last usable error and ignores empty ones', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.error('first failure') + logger.error('second failure') + logger.error('') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: 'second failure', + reason: 'package-install-failed' + }) + }) + + it('hands back and clears the diagnostic when capture ends', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.error('request dismissed') + expect(diagnostic.endLinuxPackageInstallDiagnosticCapture()).toEqual({ + message: 'request dismissed', + reason: 'authentication-denied' + }) + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toBeNull() + logger.error('later noise') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toBeNull() + }) + + it('drops a previous attempt when a new capture begins', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture('/tmp/a.deb') + logger.error('old failure') + diagnostic.beginLinuxPackageInstallDiagnosticCapture('/tmp/b.deb') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toBeNull() + logger.error('new failure at /tmp/b.deb') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: 'new failure at ', + reason: 'package-install-failed' + }) + }) + + it('classifies the original output, not the redacted text', () => { + // A user named "age" turns "agent" into "nt", which would hide the missing polkit agent. + vi.spyOn(os, 'userInfo').mockReturnValue({ username: 'age' } as os.UserInfo) + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.error('Error executing command as another user: No authentication agent found for age.') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: + 'Error executing command as another user: No authentication nt found for .', + reason: 'authentication-agent-unavailable' + }) + }) + + it('keeps a specific verdict when a generic line follows it', () => { + // electron-updater logs the polkit output first, then "Command failed, exited with code 126". + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.error('polkit-agent-helper-1: no authentication agent found') + logger.error('Command failed, exited with code 126') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: 'polkit-agent-helper-1: no authentication agent found', + reason: 'authentication-agent-unavailable' + }) + }) + + it('lets a later specific line replace an earlier one', () => { + const logger = diagnostic.createUpdaterDiagnosticLogger() + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + logger.error('no authentication agent') + logger.error('request dismissed') + expect(diagnostic.getLinuxPackageInstallDiagnostic()).toEqual({ + message: 'request dismissed', + reason: 'authentication-denied' + }) + }) + + it('returns null from an empty capture window', () => { + diagnostic.beginLinuxPackageInstallDiagnosticCapture(null) + expect(diagnostic.endLinuxPackageInstallDiagnosticCapture()).toBeNull() + }) +}) + +describe('classifyLinuxPackageInstallFailure', () => { + it('reports a missing authentication agent', () => { + for (const text of [ + 'Error executing command as another user: No authentication agent found.', + 'polkit-agent-helper: agent not found', + 'polkit agent was not found' + ]) { + expect(diagnostic.classifyLinuxPackageInstallFailure(text)).toBe( + 'authentication-agent-unavailable' + ) + } + }) + + it('reports a denied authentication', () => { + for (const text of [ + 'Error executing command as another user: Request dismissed', + 'polkit: Authentication failed', + 'Error executing command as another user: Not authorized', + 'Authorization failed for org.freedesktop.policykit.exec', + 'pkexec: 3 incorrect password attempts' + ]) { + expect(diagnostic.classifyLinuxPackageInstallFailure(text)).toBe('authentication-denied') + } + }) + + it('prefers the agent reason when both patterns appear', () => { + expect( + diagnostic.classifyLinuxPackageInstallFailure( + 'No authentication agent found; authentication failed' + ) + ).toBe('authentication-agent-unavailable') + }) + + it('falls back to a generic failure for localized output', () => { + expect( + diagnostic.classifyLinuxPackageInstallFailure( + "Erreur lors de l'exécution : aucun agent d'authentification trouvé" + ) + ).toBe('package-install-failed') + }) + + it('falls back to a generic failure for unrecognized and missing output', () => { + expect(diagnostic.classifyLinuxPackageInstallFailure('dpkg: dependency problems')).toBe( + 'package-install-failed' + ) + expect(diagnostic.classifyLinuxPackageInstallFailure(null)).toBe('package-install-failed') + expect(diagnostic.classifyLinuxPackageInstallFailure('')).toBe('package-install-failed') + }) +}) + +describe('parseLinuxPackageInstallExitCode', () => { + it('parses electron-updater exit-code messages', () => { + expect( + diagnostic.parseLinuxPackageInstallExitCode( + new Error('Command /usr/bin/pkexec exited with code 127') + ) + ).toBe(127) + expect(diagnostic.parseLinuxPackageInstallExitCode('Command failed exited with code 0')).toBe(0) + }) + + it('parses a negative code and matches case-insensitively', () => { + expect(diagnostic.parseLinuxPackageInstallExitCode('Exited With Code -1')).toBe(-1) + }) + + it('returns null when no code is present', () => { + expect(diagnostic.parseLinuxPackageInstallExitCode(new Error('spawn ENOENT'))).toBeNull() + expect(diagnostic.parseLinuxPackageInstallExitCode('exited with code abc')).toBeNull() + expect(diagnostic.parseLinuxPackageInstallExitCode(null)).toBeNull() + expect(diagnostic.parseLinuxPackageInstallExitCode({ code: 127 })).toBeNull() + }) +}) diff --git a/src/main/linux-package-install-diagnostic.ts b/src/main/linux-package-install-diagnostic.ts new file mode 100644 index 00000000000..3d0afd7fdf9 --- /dev/null +++ b/src/main/linux-package-install-diagnostic.ts @@ -0,0 +1,209 @@ +import os from 'node:os' +import type { LinuxPackageInstallFailureReason } from '../shared/types' + +/** The redacted text shown locally, paired with the reason classified from the ORIGINAL output. */ +export type LinuxPackageInstallDiagnostic = { + message: string + reason: LinuxPackageInstallFailureReason +} + +const MAX_DIAGNOSTIC_LENGTH = 1_024 +// Built via RegExp so the source carries no raw control bytes. Alternatives in order: CSI; then the +// string sequences (OSC/DCS/PM/APC/SOS), whose payload — an OSC 8 hyperlink URL, say — must be +// dropped with the introducer rather than left behind; then any remaining two-byte escape. +const ANSI_ESCAPE = new RegExp( + [ + String.raw`\u001b\[[0-9;?]*[ -/]*[@-~]`, + String.raw`\u001b[\]P^_X][^\u0007\u001b]*(?:\u0007|\u001b\\)?`, + String.raw`\u001b[@-~]` + ].join('|'), + 'g' +) +const CONTROL_CHARACTERS = new RegExp(String.raw`[\u0000-\u001f\u007f]`, 'g') + +// Why: pkexec/polkit print these before any package manager runs; matching them keeps the UI from +// blaming dpkg for an authentication problem. Anything else stays generic on purpose. +const AGENT_UNAVAILABLE_PATTERNS = [ + /no authentication agent/i, + /polkit.{0,20}agent.{0,20}not found/i +] +const AUTHENTICATION_DENIED_PATTERNS = [ + /request dismissed/i, + /authentication failed/i, + /not authorized/i, + /authorization failed/i, + /incorrect password attempt/i +] + +let capturing = false +let retainedDiagnostic: string | null = null +// Why: classification must read the ORIGINAL text. Redaction can rewrite a pattern word — a user +// named "age" turns "No authentication agent found" into "No authentication nt" — which would +// silently downgrade a missing-agent failure to the generic reason. +let retainedReason: LinuxPackageInstallFailureReason | null = null +let redactedPackagePath: string | null = null + +function stringifyLoggerValue(value: unknown): string { + if (typeof value === 'string') { + return value + } + if (value instanceof Error) { + return value.message + } + if (value === null || value === undefined) { + return '' + } + if (typeof value === 'object') { + try { + return JSON.stringify(value) ?? '' + } catch { + return '' + } + } + return String(value) +} + +// Short names would corrupt unrelated words, so they are left alone. +const MIN_REDACTED_USERNAME_LENGTH = 3 + +function readUserName(): string | null { + try { + return os.userInfo().username || null + } catch { + return null + } +} + +function replaceAllLiteral(text: string, needle: string, replacement: string): string { + if (needle.length === 0) { + return text + } + return text.split(needle).join(replacement) +} + +/** + * Turns arbitrary updater/child output into text safe to show locally: no ANSI, no control bytes, + * no home directory, no cached package path, bounded length. + */ +export function redactLinuxPackageInstallText( + value: unknown, + packagePath: string | null +): string | null { + const raw = stringifyLoggerValue(value) + if (raw.length === 0) { + return null + } + let text = raw.replace(ANSI_ESCAPE, '').replace(CONTROL_CHARACTERS, ' ') + if (packagePath) { + text = replaceAllLiteral(text, packagePath, '') + } + const homeDir = os.homedir() + if (homeDir) { + text = replaceAllLiteral(text, homeDir, '') + } + // Why: sudo reports " is not in the sudoers file", which the home-directory rule cannot catch. + const userName = readUserName() + if (userName && userName.length >= MIN_REDACTED_USERNAME_LENGTH) { + text = replaceAllLiteral(text, userName, '') + } + text = text.replace(/\s+/g, ' ').trim() + if (text.length === 0) { + return null + } + return text.length > MAX_DIAGNOSTIC_LENGTH ? text.slice(0, MAX_DIAGNOSTIC_LENGTH) : text +} + +/** Starts retaining redacted error output for one native root-package install attempt. */ +export function beginLinuxPackageInstallDiagnosticCapture(packagePath: string | null): void { + capturing = true + retainedDiagnostic = null + retainedReason = null + redactedPackagePath = packagePath +} + +/** Stops capture and hands back the retained diagnostic, clearing it for the next attempt. */ +export function endLinuxPackageInstallDiagnosticCapture(): LinuxPackageInstallDiagnostic | null { + const captured = getLinuxPackageInstallDiagnostic() + capturing = false + retainedDiagnostic = null + retainedReason = null + redactedPackagePath = null + return captured +} + +export function getLinuxPackageInstallDiagnostic(): LinuxPackageInstallDiagnostic | null { + return retainedDiagnostic === null + ? null + : { message: retainedDiagnostic, reason: retainedReason ?? 'package-install-failed' } +} + +function recordLinuxPackageInstallDiagnostic(value: unknown): void { + if (!capturing) { + return + } + const raw = stringifyLoggerValue(value) + const redacted = redactLinuxPackageInstallText(raw, redactedPackagePath) + if (!redacted) { + return + } + const reason = classifyLinuxPackageInstallFailure(raw) + // Why: electron-updater logs the polkit output first and a generic "exited with code N" line after, + // so a later generic line must not erase the specific verdict the card branches on. + if ( + reason === 'package-install-failed' && + retainedReason !== null && + retainedReason !== 'package-install-failed' + ) { + return + } + retainedDiagnostic = redacted + retainedReason = reason +} + +/** + * The `autoUpdater.logger`. Every level still reaches the same console method; only error output + * during an in-flight root-package install is retained, redacted, for the recovery card. + */ +export function createUpdaterDiagnosticLogger(): { + info: (m: unknown) => void + warn: (m: unknown) => void + error: (m: unknown) => void + debug: (m: unknown) => void +} { + return { + info: (m: unknown) => console.info('[autoUpdater]', m), + warn: (m: unknown) => console.warn('[autoUpdater]', m), + error: (m: unknown) => { + recordLinuxPackageInstallDiagnostic(m) + console.error('[autoUpdater]', m) + }, + debug: (m: unknown) => console.debug('[autoUpdater]', m) + } +} + +export function classifyLinuxPackageInstallFailure( + diagnostic: string | null +): LinuxPackageInstallFailureReason { + if (!diagnostic) { + return 'package-install-failed' + } + if (AGENT_UNAVAILABLE_PATTERNS.some((pattern) => pattern.test(diagnostic))) { + return 'authentication-agent-unavailable' + } + if (AUTHENTICATION_DENIED_PATTERNS.some((pattern) => pattern.test(diagnostic))) { + return 'authentication-denied' + } + // Localized or unrecognized output must never be reported as a missing agent. + return 'package-install-failed' +} + +/** Parses the child exit status out of electron-updater's `Command exited with code `. */ +export function parseLinuxPackageInstallExitCode(error: unknown): number | null { + const message = error instanceof Error ? error.message : typeof error === 'string' ? error : '' + const match = /exited with code (-?\d{1,5})\b/i.exec(message) + if (!match) { + return null + } + const code = Number.parseInt(match[1], 10) + return Number.isFinite(code) ? code : null +} diff --git a/src/main/linux-package-update-recovery.test.ts b/src/main/linux-package-update-recovery.test.ts new file mode 100644 index 00000000000..e3c4a27533f --- /dev/null +++ b/src/main/linux-package-update-recovery.test.ts @@ -0,0 +1,670 @@ +import { createHash } from 'node:crypto' +import fsp from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type * as NodeFs from 'node:fs' +import type { LinuxPackageInstallRecovery } from '../shared/types' +import type * as RecoveryModule from './linux-package-update-recovery' + +const { showItemInFolderMock, getPackageTypeMock, buildCommandMock, hashPasses } = vi.hoisted( + () => ({ + showItemInFolderMock: vi.fn(), + getPackageTypeMock: vi.fn(), + buildCommandMock: vi.fn(), + hashPasses: { count: 0 } + }) +) + +vi.mock('electron', () => ({ shell: { showItemInFolder: showItemInFolderMock } })) + +vi.mock('./linux-update-package-type', () => ({ getLinuxRootPackageType: getPackageTypeMock })) + +vi.mock('./linux-package-install-command', () => ({ + buildLinuxPackageInstallCommand: buildCommandMock +})) + +// Counts hash passes without changing read behavior. +vi.mock('node:fs', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + createReadStream: (...args: Parameters) => { + hashPasses.count += 1 + return actual.createReadStream(...args) + } + } +}) + +// Real symlinks, POSIX modes, and the XDG cache layout make these cases meaningless on Windows. +const describePosix = describe.skipIf(process.platform === 'win32') + +const VERSION = '1.2.3' +const PAYLOAD = 'orca package payload' +const SHA512 = createHash('sha512').update(PAYLOAD).digest('base64') + +let recovery: typeof RecoveryModule +let tempRoot: string +let cacheRoot: string +let updaterDir: string +let downloadDir: string +let outsideDir: string + +function recoveryFor(overrides: Partial = {}) { + return { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'package-install-failed', + version: VERSION, + ...overrides + } satisfies LinuxPackageInstallRecovery +} + +async function writePackage(name: string, contents = PAYLOAD): Promise { + const filePath = path.join(downloadDir, name) + await fsp.writeFile(filePath, contents) + return filePath +} + +/** Captures a well-formed downloaded event unless a field is overridden. */ +function capture(overrides: Record = {}): void { + const downloadedFile = (overrides.downloadedFile ?? path.join(downloadDir, 'orca.deb')) as string + recovery.captureLinuxPackageArtifact({ + version: VERSION, + files: [{ url: path.basename(downloadedFile), sha512: SHA512 }], + ...overrides, + downloadedFile + }) +} + +beforeEach(async () => { + vi.resetModules() + hashPasses.count = 0 + showItemInFolderMock.mockReset() + getPackageTypeMock.mockReset().mockReturnValue('deb') + buildCommandMock.mockReset().mockReturnValue({ ok: true, command: 'installed command' }) + tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'orca-recovery-')) + cacheRoot = path.join(tempRoot, 'cache') + updaterDir = path.join(cacheRoot, 'orca-updater') + // The only shape electron-updater downloads into: //pending. + downloadDir = path.join(updaterDir, 'pending') + outsideDir = path.join(tempRoot, 'outside') + await fsp.mkdir(downloadDir, { recursive: true }) + await fsp.mkdir(outsideDir, { recursive: true }) + vi.stubEnv('XDG_CACHE_HOME', cacheRoot) + recovery = await import('./linux-package-update-recovery') +}) + +afterEach(async () => { + vi.unstubAllEnvs() + vi.restoreAllMocks() + await fsp.rm(tempRoot, { recursive: true, force: true }) +}) + +describe('captureLinuxPackageArtifact', () => { + it('retains the downloaded package with the digest from the event metadata', () => { + capture() + expect(recovery.getTrackedLinuxPackageArtifact()).toEqual({ + packageType: 'deb', + version: VERSION, + path: path.join(downloadDir, 'orca.deb'), + sha512: SHA512 + }) + }) + + it('ignores the event on a build that is not a root package', () => { + getPackageTypeMock.mockReturnValue(null) + capture() + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('requires an absolute downloaded path', () => { + capture({ downloadedFile: 'orca.deb' }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('requires a string downloaded path', () => { + recovery.captureLinuxPackageArtifact({ + downloadedFile: 123, + version: VERSION, + files: [{ url: 'orca.deb', sha512: SHA512 }] + }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('requires the package extension to match the installed format', () => { + capture({ downloadedFile: path.join(downloadDir, 'orca.rpm') }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('accepts an uppercase extension', () => { + capture({ downloadedFile: path.join(downloadDir, 'Orca.DEB') }) + expect(recovery.getTrackedLinuxPackageArtifact()?.path).toBe(path.join(downloadDir, 'Orca.DEB')) + }) + + it('requires a non-empty string version', () => { + capture({ version: 7 }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + capture({ version: '' }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('matches an absolute file URL by basename', () => { + capture({ + files: [{ url: 'https://downloads.example.com/releases/1.2.3/orca.deb', sha512: SHA512 }] + }) + expect(recovery.getTrackedLinuxPackageArtifact()?.sha512).toBe(SHA512) + }) + + it('matches a percent-encoded relative URL against the decoded basename', () => { + const downloadedFile = path.join(downloadDir, 'Orca Setup 1.2.3.deb') + capture({ downloadedFile, files: [{ url: 'Orca%20Setup%201.2.3.deb', sha512: SHA512 }] }) + expect(recovery.getTrackedLinuxPackageArtifact()?.path).toBe(downloadedFile) + }) + + it('ignores entries for other files and formats', () => { + capture({ + files: [ + { url: 'orca.AppImage', sha512: 'other-appimage-digest' }, + { url: 'orca-arm64.deb', sha512: 'other-arch-digest' }, + { url: 'orca.deb', sha512: SHA512 } + ] + }) + expect(recovery.getTrackedLinuxPackageArtifact()?.sha512).toBe(SHA512) + }) + + it('accepts duplicate entries that agree on the digest', () => { + capture({ + files: [ + { url: 'orca.deb', sha512: SHA512 }, + { url: 'https://downloads.example.com/orca.deb', sha512: SHA512 } + ] + }) + expect(recovery.getTrackedLinuxPackageArtifact()?.sha512).toBe(SHA512) + }) + + it('refuses an ambiguous basename with two different digests', () => { + capture({ + files: [ + { url: 'orca.deb', sha512: SHA512 }, + { url: 'https://mirror.example.com/orca.deb', sha512: 'conflicting-digest' } + ] + }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('refuses an entry with a missing or non-string digest', () => { + capture({ files: [{ url: 'orca.deb' }] }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + capture({ files: [{ url: 'orca.deb', sha512: 42 }] }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('refuses a digest that cannot decode to 64 bytes', () => { + // Why: an undecodable digest is a metadata problem — arming here would blame the user's file. + capture({ + files: [{ url: 'orca.deb', sha512: createHash('sha256').update(PAYLOAD).digest('base64') }] + }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('refuses a digest with characters outside the base64 alphabet', () => { + // Buffer.from would silently drop the '!', so the round-trip check must reject this. + capture({ files: [{ url: 'orca.deb', sha512: `${SHA512.slice(0, 4)}!${SHA512.slice(4)}` }] }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('refuses a digest that is not base64 at all', () => { + capture({ files: [{ url: 'orca.deb', sha512: 'not-a-digest' }] }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('keeps a retained artifact when a later event carries a malformed digest', () => { + capture() + capture({ files: [{ url: 'orca.deb', sha512: 'not-a-digest' }] }) + expect(recovery.getTrackedLinuxPackageArtifact()?.sha512).toBe(SHA512) + }) + + it('refuses a malformed percent-encoded URL', () => { + capture({ files: [{ url: 'orca%ZZ.deb', sha512: SHA512 }] }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('refuses a missing or non-array file list', () => { + capture({ files: undefined }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + capture({ files: { url: 'orca.deb', sha512: SHA512 } }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('tolerates a non-object event', () => { + expect(() => recovery.captureLinuxPackageArtifact(undefined)).not.toThrow() + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('replaces the retained artifact with a newer download', () => { + capture() + capture({ + version: '1.2.4', + downloadedFile: path.join(downloadDir, 'orca-next.deb'), + files: [{ url: 'orca-next.deb', sha512: SHA512 }] + }) + expect(recovery.getTrackedLinuxPackageArtifact()).toMatchObject({ + version: '1.2.4', + path: path.join(downloadDir, 'orca-next.deb') + }) + }) + + it('keeps the retained artifact when a new download has no usable digest', () => { + capture() + capture({ files: [{ url: 'orca.deb' }] }) + expect(recovery.getTrackedLinuxPackageArtifact()?.path).toBe(path.join(downloadDir, 'orca.deb')) + }) + + it('does not arm recovery from a download with no usable digest', () => { + capture({ files: [{ url: 'orca.deb' }] }) + capture({ files: [{ url: 'orca%ZZ.deb', sha512: SHA512 }] }) + capture({ + files: [ + { url: 'orca.deb', sha512: SHA512 }, + { url: 'https://mirror.example.com/orca.deb', sha512: 'conflicting-digest' } + ] + }) + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('keeps the retained artifact when an unrelated download event arrives', () => { + capture() + capture({ downloadedFile: path.join(downloadDir, 'orca.AppImage') }) + expect(recovery.getTrackedLinuxPackageArtifact()?.path).toBe(path.join(downloadDir, 'orca.deb')) + }) +}) + +describe('clearTrackedLinuxPackageArtifact', () => { + it('clears the retained artifact', () => { + capture() + recovery.clearTrackedLinuxPackageArtifact() + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('preserves the artifact across a recheck of the same version', () => { + capture() + recovery.clearTrackedLinuxPackageArtifactForOtherVersion(VERSION) + expect(recovery.getTrackedLinuxPackageArtifact()?.version).toBe(VERSION) + }) + + it('clears the artifact when another version takes over', () => { + capture() + recovery.clearTrackedLinuxPackageArtifactForOtherVersion('1.3.0') + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) + + it('preserves the artifact for an unknown or empty version', () => { + capture() + recovery.clearTrackedLinuxPackageArtifactForOtherVersion(undefined) + recovery.clearTrackedLinuxPackageArtifactForOtherVersion('') + recovery.clearTrackedLinuxPackageArtifactForOtherVersion(42) + expect(recovery.getTrackedLinuxPackageArtifact()?.version).toBe(VERSION) + }) + + it('is a no-op without a retained artifact', () => { + expect(() => recovery.clearTrackedLinuxPackageArtifactForOtherVersion('1.3.0')).not.toThrow() + expect(recovery.getTrackedLinuxPackageArtifact()).toBeNull() + }) +}) + +describePosix('resolveLinuxPackageInstallInstructions', () => { + it('returns the built command and package file name for a verified package', async () => { + const filePath = await writePackage('orca.deb') + capture() + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: true, + command: 'installed command', + packageFileName: 'orca.deb' + }) + expect(buildCommandMock).toHaveBeenCalledWith('deb', filePath) + }) + + it('reports missing without a retained artifact', async () => { + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'missing' + }) + }) + + it('reports missing when the recovery version does not match', async () => { + await writePackage('orca.deb') + capture() + await expect( + recovery.resolveLinuxPackageInstallInstructions(recoveryFor({ version: '9.9.9' })) + ).resolves.toEqual({ ok: false, reason: 'missing' }) + }) + + it('reports missing when the recovery package type does not match', async () => { + await writePackage('orca.deb') + capture() + await expect( + recovery.resolveLinuxPackageInstallInstructions(recoveryFor({ packageType: 'rpm' })) + ).resolves.toEqual({ ok: false, reason: 'missing' }) + }) + + it('reports missing when the package was deleted', async () => { + const filePath = await writePackage('orca.deb') + capture() + await fsp.rm(filePath) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'missing' + }) + }) + + it('propagates a package-manager discovery failure', async () => { + await writePackage('orca.deb') + capture() + buildCommandMock.mockReturnValue({ ok: false, reason: 'no-sudo' }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'no-sudo' + }) + buildCommandMock.mockReturnValue({ ok: false, reason: 'no-package-manager' }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'no-package-manager' + }) + }) +}) + +describePosix('digest validation', () => { + it('rejects a package whose contents changed', async () => { + const filePath = await writePackage('orca.deb') + capture() + await fsp.writeFile(filePath, 'tampered payload') + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'hash-mismatch' + }) + }) + + it('rejects a well-formed digest that belongs to another file', async () => { + await writePackage('orca.deb') + capture({ + files: [ + { url: 'orca.deb', sha512: createHash('sha512').update('other payload').digest('base64') } + ] + }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'hash-mismatch' + }) + }) + + it('never hashes a package that a malformed digest failed to arm', async () => { + await writePackage('orca.deb') + capture({ files: [{ url: 'orca.deb', sha512: 'not-a-digest' }] }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'missing' + }) + expect(hashPasses.count).toBe(0) + }) + + it.runIf(process.getuid?.() !== 0)('reports read-failed for an unreadable package', async () => { + const filePath = await writePackage('orca.deb') + capture() + await fsp.chmod(filePath, 0o000) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'read-failed' + }) + await fsp.chmod(filePath, 0o644) + }) +}) + +describePosix('cache containment', () => { + it('rejects a path that traverses out of the cache', async () => { + const filePath = path.join(outsideDir, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: path.join(downloadDir, '..', '..', '..', 'outside', 'orca.deb') }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a path outside the cache root', async () => { + const filePath = path.join(outsideDir, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects the cache root itself', async () => { + const rootAsPackage = path.join(tempRoot, 'cache.deb') + await fsp.mkdir(rootAsPackage) + vi.stubEnv('XDG_CACHE_HOME', rootAsPackage) + capture({ downloadedFile: rootAsPackage }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a directory in place of the package', async () => { + await fsp.mkdir(path.join(downloadDir, 'orca.deb')) + capture() + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a symlink to a real package inside the cache', async () => { + await writePackage('real.deb') + const linkPath = path.join(downloadDir, 'orca.deb') + await fsp.symlink(path.join(downloadDir, 'real.deb'), linkPath) + capture() + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a package whose parent symlink escapes the cache', async () => { + await fsp.writeFile(path.join(outsideDir, 'orca.deb'), PAYLOAD) + await fsp.symlink(outsideDir, path.join(cacheRoot, 'escape')) + capture({ downloadedFile: path.join(cacheRoot, 'escape', 'orca.deb') }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a subdirectory of the pending directory', async () => { + const nested = path.join(downloadDir, 'nested') + await fsp.mkdir(nested) + const filePath = path.join(nested, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('uses the home cache when XDG_CACHE_HOME is unset', async () => { + // Why: the fallback is the only reason an unset XDG_CACHE_HOME still finds the real download. + const homeCache = path.join(tempRoot, 'home') + const homeDownloadDir = path.join(homeCache, '.cache', 'orca-updater', 'pending') + await fsp.mkdir(homeDownloadDir, { recursive: true }) + const filePath = path.join(homeDownloadDir, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + vi.stubEnv('XDG_CACHE_HOME', '') + vi.spyOn(os, 'homedir').mockReturnValue(homeCache) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: true, + command: 'installed command', + packageFileName: 'orca.deb' + }) + }) +}) + +// electron-updater builds `downloadedFile` from the cache's own writable update-info.json without +// calling basename, so these pin the accepted shape to the one directory it actually downloads into. +// Defence in depth only — a same-uid process can create its own `pending` directory, and per the +// design's trust model it can already overwrite the real cached package. The load-bearing check is the +// cache-root anchor covered by the `cache containment` describe above. +describePosix('pending-directory anchoring', () => { + it('rejects a package in an attacker-owned directory under the cache root', async () => { + const evilDir = path.join(cacheRoot, 'evil') + await fsp.mkdir(evilDir) + const filePath = path.join(evilDir, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a package in the updater directory itself', async () => { + const filePath = path.join(updaterDir, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a pending directory buried deeper than one level under the cache root', async () => { + const deepPending = path.join(cacheRoot, 'evil', 'nested', 'pending') + await fsp.mkdir(deepPending, { recursive: true }) + const filePath = path.join(deepPending, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('rejects a pending directory that is a symlink out of the cache', async () => { + await fsp.writeFile(path.join(outsideDir, 'orca.deb'), PAYLOAD) + const fakeUpdaterDir = path.join(cacheRoot, 'orca-updater-2') + await fsp.mkdir(fakeUpdaterDir) + await fsp.symlink(outsideDir, path.join(fakeUpdaterDir, 'pending')) + capture({ downloadedFile: path.join(fakeUpdaterDir, 'pending', 'orca.deb') }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'not-regular' + }) + }) + + it('accepts any updater directory name that holds the pending directory', async () => { + // The cache directory name comes from the app, so only its position is fixed. + const otherPending = path.join(cacheRoot, 'orca-updater-next', 'pending') + await fsp.mkdir(otherPending, { recursive: true }) + const filePath = path.join(otherPending, 'orca.deb') + await fsp.writeFile(filePath, PAYLOAD) + capture({ downloadedFile: filePath }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: true, + command: 'installed command', + packageFileName: 'orca.deb' + }) + }) + + it('accepts a pending directory reached through a symlink that stays in the cache', async () => { + await writePackage('orca.deb') + await fsp.symlink(updaterDir, path.join(cacheRoot, 'link-to-updater')) + capture({ downloadedFile: path.join(cacheRoot, 'link-to-updater', 'pending', 'orca.deb') }) + await expect(recovery.resolveLinuxPackageInstallInstructions(recoveryFor())).resolves.toEqual({ + ok: true, + command: 'installed command', + packageFileName: 'orca.deb' + }) + }) +}) + +describePosix('validation coalescing', () => { + it('performs one hash pass for concurrent requests', async () => { + await writePackage('orca.deb') + capture() + const [first, second] = await Promise.all([ + recovery.resolveLinuxPackageInstallInstructions(recoveryFor()), + recovery.revealLinuxPackage(recoveryFor()) + ]) + expect(first.ok).toBe(true) + expect(second.ok).toBe(true) + expect(hashPasses.count).toBe(1) + }) + + it('revalidates once the in-flight pass settles', async () => { + await writePackage('orca.deb') + capture() + await recovery.resolveLinuxPackageInstallInstructions(recoveryFor()) + await recovery.resolveLinuxPackageInstallInstructions(recoveryFor()) + expect(hashPasses.count).toBe(2) + }) + + it('does not reuse an in-flight pass for a different artifact', async () => { + await writePackage('orca.deb') + await writePackage('orca-next.deb') + capture() + const first = recovery.resolveLinuxPackageInstallInstructions(recoveryFor()) + capture({ + version: '1.2.4', + downloadedFile: path.join(downloadDir, 'orca-next.deb'), + files: [{ url: 'orca-next.deb', sha512: SHA512 }] + }) + const second = recovery.resolveLinuxPackageInstallInstructions( + recoveryFor({ version: '1.2.4' }) + ) + await Promise.all([first, second]) + expect(hashPasses.count).toBe(2) + }) +}) + +describePosix('revealLinuxPackage', () => { + it('reveals a verified package on the machine that owns it', async () => { + const filePath = await writePackage('orca.deb') + capture() + await expect(recovery.revealLinuxPackage(recoveryFor())).resolves.toEqual({ ok: true }) + expect(showItemInFolderMock).toHaveBeenCalledWith(filePath) + }) + + it('does not reveal a package that fails validation', async () => { + const filePath = await writePackage('orca.deb') + capture() + await fsp.writeFile(filePath, 'tampered payload') + await expect(recovery.revealLinuxPackage(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'hash-mismatch' + }) + expect(showItemInFolderMock).not.toHaveBeenCalled() + }) + + it('reports read-failed when the desktop file manager throws', async () => { + await writePackage('orca.deb') + capture() + showItemInFolderMock.mockImplementation(() => { + throw new Error('no file manager available') + }) + await expect(recovery.revealLinuxPackage(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'read-failed' + }) + }) + + it('does not reveal anything without a retained artifact', async () => { + await expect(recovery.revealLinuxPackage(recoveryFor())).resolves.toEqual({ + ok: false, + reason: 'missing' + }) + expect(showItemInFolderMock).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/linux-package-update-recovery.ts b/src/main/linux-package-update-recovery.ts new file mode 100644 index 00000000000..83aca03cb3f --- /dev/null +++ b/src/main/linux-package-update-recovery.ts @@ -0,0 +1,309 @@ +import { createHash, timingSafeEqual } from 'node:crypto' +import { createReadStream } from 'node:fs' +import fsp from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { shell } from 'electron' +import type { LinuxPackageInstallRecovery, LinuxRootPackageType } from '../shared/types' +import { getLinuxRootPackageType } from './linux-update-package-type' +import { buildLinuxPackageInstallCommand } from './linux-package-install-command' + +const SHA512_BYTE_LENGTH = 64 +// electron-updater downloads into //pending; nothing else is trusted. +const PENDING_DIRECTORY_NAME = 'pending' + +export type LinuxPackageArtifact = { + packageType: LinuxRootPackageType + version: string + path: string + sha512: string +} + +export type LinuxPackageRecoveryUnavailableReason = + | 'missing' + | 'not-regular' + | 'hash-mismatch' + | 'no-sudo' + | 'no-package-manager' + | 'invalid-package-path' + | 'read-failed' + +export type LinuxPackageInstructionsResult = + | { ok: true; command: string; packageFileName: string } + | { ok: false; reason: LinuxPackageRecoveryUnavailableReason } + +export type LinuxPackageRevealResult = + | { ok: true } + | { ok: false; reason: LinuxPackageRecoveryUnavailableReason } + +type ValidationResult = + | { ok: true; artifact: LinuxPackageArtifact } + | { ok: false; reason: 'missing' | 'not-regular' | 'hash-mismatch' | 'read-failed' } + +let trackedArtifact: LinuxPackageArtifact | null = null +// Why: the renderer debounces clicks, but the IPC boundary must not allow parallel hashing of a 160 MB package. +let inFlightValidation: { key: string; promise: Promise } | null = null + +export function getTrackedLinuxPackageArtifact(): LinuxPackageArtifact | null { + return trackedArtifact +} + +export function clearTrackedLinuxPackageArtifact(): void { + trackedArtifact = null +} + +/** Clears the artifact only when a different version demonstrably takes over the update cycle. */ +export function clearTrackedLinuxPackageArtifactForOtherVersion(version: unknown): void { + if (!trackedArtifact) { + return + } + // Why: an unknown/empty version is not evidence of another cycle and must not destroy recovery. + if (typeof version !== 'string' || version.length === 0) { + return + } + if (version === trackedArtifact.version) { + return + } + trackedArtifact = null +} + +/** + * Mirrors electron-updater's cache-name rule: resolve the manifest URL against a dummy base, decode + * the pathname, require the package extension, and match the basename of the downloaded file. + * A malformed encoding or an ambiguous file/hash pairing disables cached-package recovery rather + * than guessing a digest. + */ +function resolveExpectedSha512( + files: unknown, + downloadedFile: string, + packageType: LinuxRootPackageType +): string | null { + if (!Array.isArray(files)) { + return null + } + const targetName = path.basename(downloadedFile) + const extension = `.${packageType}` + let resolved: string | null = null + for (const entry of files) { + const url = (entry as { url?: unknown })?.url + if (typeof url !== 'string' || url.length === 0) { + continue + } + let pathname: string + try { + pathname = decodeURIComponent(new URL(url, 'http://update-file-name.invalid/').pathname) + } catch { + return null + } + if (!pathname.toLowerCase().endsWith(extension)) { + continue + } + if (path.posix.basename(pathname) !== targetName) { + continue + } + const sha512 = (entry as { sha512?: unknown })?.sha512 + if (typeof sha512 !== 'string' || sha512.length === 0) { + return null + } + if (resolved !== null && resolved !== sha512) { + return null + } + resolved = sha512 + } + return resolved +} + +/** + * Retains the verified download so a failed root-package install stays recoverable without paying + * for the 160 MB transfer again. Only the in-memory event metadata is trusted for the digest. + */ +export function captureLinuxPackageArtifact(event: unknown): void { + const packageType = getLinuxRootPackageType() + if (!packageType) { + return + } + const downloadedFile = (event as { downloadedFile?: unknown })?.downloadedFile + const version = (event as { version?: unknown })?.version + if (typeof downloadedFile !== 'string' || !path.isAbsolute(downloadedFile)) { + return + } + if (!downloadedFile.toLowerCase().endsWith(`.${packageType}`)) { + return + } + if (typeof version !== 'string' || version.length === 0) { + return + } + const sha512 = resolveExpectedSha512( + (event as { files?: unknown })?.files, + downloadedFile, + packageType + ) + // Why: a malformed digest can never validate. Arming recovery on it would send the user to the + // alarming "no longer matches the verified release" path for what is a release-metadata problem. + if (!sha512 || !decodeExpectedDigest(sha512)) { + // Why: an unresolvable digest only means THIS event cannot arm recovery. A previously retained + // artifact carries its own digest and is revalidated on every use, so dropping it would force a + // needless 160 MB redownload of a file that is still on disk and still verifiable. + return + } + trackedArtifact = { packageType, version, path: downloadedFile, sha512 } +} + +function isInsideDirectory(root: string, target: string): boolean { + const relative = path.relative(root, target) + return relative.length > 0 && !relative.startsWith('..') && !path.isAbsolute(relative) +} + +/** + * The cache root electron-updater downloads into. Mirrors its own `getAppCacheDir()` rule, which on + * Linux resolves to the same directory Electron reports as the `cache` path. + */ +function getUpdaterCacheRoot(): string { + // Mirrors upstream exactly, including its lack of an absoluteness check — diverging here would put + // the real download outside the directory this module treats as the cache. + return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache') +} + +/** + * Rejects traversal and a symlinked parent that escapes the updater cache. + * + * The security boundary is the cache-root anchor below: electron-updater builds `downloadedFile` from + * the `fileName` in the cache's own writable `update-info.json` without calling `basename`, so without + * it a manipulated entry could point at `/tmp` or `/dev/shm` where a DIFFERENT principal can win the + * swap race. The `//pending` shape check narrows the accepted paths to + * the one place electron-updater actually downloads into; it is defence in depth, not a boundary — a + * same-uid process can create its own `pending` directory, and per the design's trust model such a + * process can already overwrite the real cached package anyway. + */ +async function isContainedInCache(filePath: string): Promise { + const cacheRoot = path.resolve(getUpdaterCacheRoot()) + if (!isInsideDirectory(cacheRoot, path.resolve(filePath))) { + return false + } + const realCacheRoot = path.resolve(await fsp.realpath(cacheRoot)) + const realParent = path.resolve(await fsp.realpath(path.dirname(filePath))) + if (!isInsideDirectory(realCacheRoot, path.join(realParent, path.basename(filePath)))) { + return false + } + if (path.basename(realParent) !== PENDING_DIRECTORY_NAME) { + return false + } + // The updater cache directory sits directly under the cache root, so `pending` is exactly two down. + return path.dirname(path.dirname(realParent)) === realCacheRoot +} + +function decodeExpectedDigest(sha512: string): Buffer | null { + const trimmed = sha512.trim() + const decoded = Buffer.from(trimmed, 'base64') + if (decoded.byteLength !== SHA512_BYTE_LENGTH) { + return null + } + // Why: Buffer.from silently drops invalid base64 characters; round-tripping rejects malformed input. + // The round-trip emits standard base64, so a URL-safe digest would be rejected — electron-updater's + // latest-linux.yml is standard base64, and failing closed on an unrecognized encoding is correct. + return decoded.toString('base64') === trimmed ? decoded : null +} + +function streamSha512(filePath: string): Promise { + return new Promise((resolve, reject) => { + const hash = createHash('sha512') + const stream = createReadStream(filePath) + stream.on('error', reject) + stream.on('data', (chunk) => hash.update(chunk)) + stream.on('end', () => resolve(hash.digest())) + }) +} + +async function validateArtifact(artifact: LinuxPackageArtifact): Promise { + const expectedDigest = decodeExpectedDigest(artifact.sha512) + if (!expectedDigest) { + return { ok: false, reason: 'hash-mismatch' } + } + try { + if (!(await isContainedInCache(artifact.path))) { + return { ok: false, reason: 'not-regular' } + } + const stats = await fsp.lstat(artifact.path) + if (stats.isSymbolicLink() || !stats.isFile()) { + return { ok: false, reason: 'not-regular' } + } + const actualDigest = await streamSha512(artifact.path) + if ( + actualDigest.byteLength !== expectedDigest.byteLength || + !timingSafeEqual(actualDigest, expectedDigest) + ) { + return { ok: false, reason: 'hash-mismatch' } + } + return { ok: true, artifact } + } catch (error) { + const code = (error as NodeJS.ErrnoException)?.code + return { ok: false, reason: code === 'ENOENT' ? 'missing' : 'read-failed' } + } +} + +/** + * Revalidates the retained package against the digest captured from the release metadata. This is + * an integrity check against that HTTPS metadata, not a package signature and not a privilege + * boundary — a same-user process can still replace the file after this returns. + */ +async function validateTrackedArtifact( + recovery: LinuxPackageInstallRecovery +): Promise { + const artifact = trackedArtifact + if ( + !artifact || + artifact.version !== recovery.version || + artifact.packageType !== recovery.packageType + ) { + return { ok: false, reason: 'missing' } + } + const key = `${artifact.packageType}:${artifact.version}:${artifact.path}:${artifact.sha512}` + if (inFlightValidation?.key === key) { + return inFlightValidation.promise + } + const promise = validateArtifact(artifact).finally(() => { + if (inFlightValidation?.key === key) { + inFlightValidation = null + } + }) + inFlightValidation = { key, promise } + return promise +} + +export async function resolveLinuxPackageInstallInstructions( + recovery: LinuxPackageInstallRecovery +): Promise { + const validation = await validateTrackedArtifact(recovery) + if (!validation.ok) { + return validation + } + const { artifact } = validation + const command = buildLinuxPackageInstallCommand(artifact.packageType, artifact.path) + if (!command.ok) { + return command + } + return { + ok: true, + command: command.command, + packageFileName: path.basename(artifact.path) + } +} + +export async function revealLinuxPackage( + recovery: LinuxPackageInstallRecovery +): Promise { + const validation = await validateTrackedArtifact(recovery) + if (!validation.ok) { + return validation + } + // Why: this cache path must not travel through the workspace shell:openPath API, whose execution + // host can be an SSH or WSL machine rather than the one that owns the installed package. + try { + shell.showItemInFolder(validation.artifact.path) + } catch { + // Why: every other failure in this module reports through {ok:false}; a raw throw here would + // reject the IPC with an unredacted message and skip the lifecycle record. + return { ok: false, reason: 'read-failed' } + } + return { ok: true } +} diff --git a/src/main/linux-update-package-type.test.ts b/src/main/linux-update-package-type.test.ts new file mode 100644 index 00000000000..2a2858c2c68 --- /dev/null +++ b/src/main/linux-update-package-type.test.ts @@ -0,0 +1,181 @@ +import fsp from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const { appMock } = vi.hoisted(() => ({ appMock: { isPackaged: true } })) + +vi.mock('electron', () => ({ app: appMock })) + +const originalPlatform = process.platform +const originalResourcesPath = process.resourcesPath as string | undefined + +let resourcesDir: string + +function setPlatform(platform: string): void { + Object.defineProperty(process, 'platform', { configurable: true, value: platform }) +} + +function setResourcesPath(value: unknown): void { + Object.defineProperty(process, 'resourcesPath', { configurable: true, value }) +} + +async function writeMarker(contents: string): Promise { + await fsp.writeFile(path.join(resourcesDir, 'package-type'), contents, 'utf8') +} + +async function loadPackageType(): Promise<() => 'deb' | 'rpm' | null> { + const module = await import('./linux-update-package-type') + return module.getLinuxRootPackageType +} + +beforeEach(async () => { + vi.resetModules() + vi.spyOn(console, 'warn').mockImplementation(() => {}) + appMock.isPackaged = true + setPlatform('linux') + resourcesDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'orca-package-type-')) + setResourcesPath(resourcesDir) +}) + +afterEach(async () => { + vi.restoreAllMocks() + setPlatform(originalPlatform) + setResourcesPath(originalResourcesPath) + await fsp.rm(resourcesDir, { recursive: true, force: true }) +}) + +describe('getLinuxRootPackageType', () => { + it('reads a deb marker', async () => { + await writeMarker('deb') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBe('deb') + }) + + it('reads an rpm marker', async () => { + await writeMarker('rpm') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBe('rpm') + }) + + it('trims surrounding whitespace', async () => { + await writeMarker('\n rpm \t\n') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBe('rpm') + }) + + it('treats the AppImage marker as not a root package', async () => { + await writeMarker('AppImage') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('treats an unknown marker value as not a root package', async () => { + await writeMarker('snap') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('treats a pacman marker as a recognized but unsupported target', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + await writeMarker('pacman') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + expect(warn).not.toHaveBeenCalled() + }) + + it('rejects a marker that only differs by case', async () => { + await writeMarker('DEB') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('returns null when the marker is missing', async () => { + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('returns null when the marker is unreadable', async () => { + // A directory in the marker's place makes readFileSync fail with EISDIR. + await fsp.mkdir(path.join(resourcesDir, 'package-type')) + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('returns null when resourcesPath is unavailable', async () => { + setResourcesPath(undefined) + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('returns null when resourcesPath is empty', async () => { + setResourcesPath('') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('ignores a readable marker in an unpackaged dev run', async () => { + await writeMarker('deb') + appMock.isPackaged = false + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('ignores a readable marker off Linux', async () => { + await writeMarker('deb') + setPlatform('darwin') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('caches the resolved type for the process lifetime', async () => { + await writeMarker('deb') + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBe('deb') + await writeMarker('rpm') + expect(getLinuxRootPackageType()).toBe('deb') + }) + + it('caches a resolved null so a later marker is not picked up', async () => { + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + await writeMarker('deb') + expect(getLinuxRootPackageType()).toBeNull() + }) + + it('warns about an unknown marker value', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + await writeMarker('snap') + const getLinuxRootPackageType = await loadPackageType() + getLinuxRootPackageType() + expect(warn).toHaveBeenCalledTimes(1) + expect(warn.mock.calls[0][0]).toContain('marker is not deb or rpm') + }) + + it('reads the marker once and warns once per process', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + // A directory in place of the marker is readable-but-unusable, which is the case worth reporting. + await fsp.mkdir(path.join(resourcesDir, 'package-type')) + const getLinuxRootPackageType = await loadPackageType() + getLinuxRootPackageType() + expect(getLinuxRootPackageType()).toBeNull() + expect(warn).toHaveBeenCalledTimes(1) + expect(warn.mock.calls[0][0]).toContain('marker unreadable') + }) + + // Why: AppImage ships no marker at all, so the normal case must stay silent. + it('stays silent when no marker is present', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const getLinuxRootPackageType = await loadPackageType() + expect(getLinuxRootPackageType()).toBeNull() + expect(warn).not.toHaveBeenCalled() + }) + + it('does not warn in a dev run', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + appMock.isPackaged = false + const getLinuxRootPackageType = await loadPackageType() + getLinuxRootPackageType() + expect(warn).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/linux-update-package-type.ts b/src/main/linux-update-package-type.ts new file mode 100644 index 00000000000..c8af66649a5 --- /dev/null +++ b/src/main/linux-update-package-type.ts @@ -0,0 +1,57 @@ +import { readFileSync } from 'node:fs' +import path from 'node:path' +import { app } from 'electron' +import type { LinuxRootPackageType } from '../shared/types' + +export type { LinuxRootPackageType } + +// Why: `undefined` means "not resolved yet"; `null` is a resolved "not a root package". +let cachedPackageType: LinuxRootPackageType | null | undefined + +// Bounded by construction: the marker is read at most once per process. +function warnMarkerUnusable(detail: string): void { + console.warn(`[updater] linux package-type marker unusable: ${detail}`) +} + +function readPackageTypeMarker(): LinuxRootPackageType | null { + if (process.platform !== 'linux' || !app.isPackaged) { + return null + } + const resourcesPath = process.resourcesPath + if (typeof resourcesPath !== 'string' || resourcesPath.length === 0) { + warnMarkerUnusable('resourcesPath unavailable') + return null + } + let raw: string + try { + raw = readFileSync(path.join(resourcesPath, 'package-type'), 'utf8') + } catch (error) { + // Why: AppImage legitimately ships no marker, so only an unreadable one is worth reporting. + if ((error as NodeJS.ErrnoException)?.code !== 'ENOENT') { + warnMarkerUnusable('marker unreadable') + } + return null + } + const value = raw.trim() + if (value === 'deb' || value === 'rpm') { + return value + } + // Why: electron-updater also supports pacman, but this recovery path covers deb/rpm only — a + // recognized marker is a deliberate scope cut, not a broken install. + if (value !== 'pacman') { + warnMarkerUnusable('marker is not deb or rpm') + } + return null +} + +/** + * The installed Linux package format, or null when this build does not install through a + * root package. Reads only the packaged marker `electron-updater` itself uses — never distro + * files, executable paths, or available package managers. + */ +export function getLinuxRootPackageType(): LinuxRootPackageType | null { + if (cachedPackageType === undefined) { + cachedPackageType = readPackageTypeMarker() + } + return cachedPackageType +} diff --git a/src/main/persistence.ts b/src/main/persistence.ts index 40660eb8a1c..077d9b871a7 100644 --- a/src/main/persistence.ts +++ b/src/main/persistence.ts @@ -7291,11 +7291,13 @@ export class Store { return this.flushCurrentStateAsync(false, undefined, false).catch(() => {}) } - flushPendingOrThrowAsync(options: { signal?: AbortSignal } = {}): Promise { + flushPendingOrThrowAsync( + options: { signal?: AbortSignal; drainToStableGeneration?: boolean } = {} + ): Promise { if (this.writesFrozen || this.quitFlushStarted) { return Promise.reject(new Error('Cannot flush while persistence is finalized')) } - return this.flushCurrentStateAsync(false, options.signal) + return this.flushCurrentStateAsync(false, options.signal, options.drainToStableGeneration) } // Async twin of flushOrThrow: durable state only. Active-view and GitHub sidecars are diff --git a/src/main/plugins/plugin-content-safety.test.ts b/src/main/plugins/plugin-content-safety.test.ts index eedeb42ef9f..af907f4a4ab 100644 --- a/src/main/plugins/plugin-content-safety.test.ts +++ b/src/main/plugins/plugin-content-safety.test.ts @@ -2,6 +2,7 @@ import { mkdtemp, mkdir, rm, symlink, truncate, writeFile } from 'node:fs/promis import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' +import { disposeWatcherProcess } from '../ipc/parcel-watcher-process' import { fingerprintPluginConsent } from '../../shared/plugins/plugin-consent-fingerprint' import { pluginManifestSchema, type PluginManifest } from '../../shared/plugins/plugin-manifest' import { @@ -43,6 +44,9 @@ function manifest(overrides: ManifestOverrides = {}): PluginManifest { afterEach(async () => { vi.restoreAllMocks() + // Why: PluginService may still be releasing in-process Parcel watches; drop + // the shared vitest watcher state before deleting roots those watches own. + disposeWatcherProcess() await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true }))) }) diff --git a/src/main/plugins/plugin-dev-watcher.test.ts b/src/main/plugins/plugin-dev-watcher.test.ts index 77996fe3bd8..33bd0050625 100644 --- a/src/main/plugins/plugin-dev-watcher.test.ts +++ b/src/main/plugins/plugin-dev-watcher.test.ts @@ -47,6 +47,22 @@ describe('PluginDevWatcher', () => { await vi.waitFor(() => expect(unsubscribe).toHaveBeenCalledOnce()) }) + it('contains unsubscribe rejections so dispose cannot fail the host process', async () => { + const unsubscribe = vi + .fn() + .mockRejectedValue(new Error('Unable to remove watcher: Invalid argument')) + const subscribePath = vi.fn(async () => ({ unsubscribe })) + const devWatcher = new PluginDevWatcher(subscribePath) + devWatcher.start(['/plugins/demo'], vi.fn()) + await vi.waitFor(() => expect(subscribePath).toHaveBeenCalledOnce()) + + expect(() => devWatcher.dispose()).not.toThrow() + await vi.waitFor(() => expect(unsubscribe).toHaveBeenCalledOnce()) + // Why: give the rejected promise a turn so an uncaught rejection would surface. + await Promise.resolve() + await Promise.resolve() + }) + it('does not spin refreshes when a missing path cannot be subscribed', async () => { vi.useFakeTimers() const subscribePath = vi.fn().mockRejectedValue(new Error('missing path')) diff --git a/src/main/plugins/plugin-dev-watcher.ts b/src/main/plugins/plugin-dev-watcher.ts index ea77def417f..c6aefa12699 100644 --- a/src/main/plugins/plugin-dev-watcher.ts +++ b/src/main/plugins/plugin-dev-watcher.ts @@ -20,6 +20,13 @@ const subscribePluginPath: SubscribePluginPath = (path, onEvent, onInterruption) } ) +// Why: Parcel unsubscribe rejects when the watch root is already gone (common +// in tests that rm temp dirs). Fire-and-forget callers must not leave that as +// an unhandled rejection that fails the Vitest process. +function releaseSubscription(subscription: WatcherProcessSubscription): void { + void subscription.unsubscribe().catch(() => undefined) +} + /** Owns debounced manifest/panel refresh watchers for mutable dev plugins. */ export class PluginDevWatcher { private readonly subscriptions: WatcherProcessSubscription[] = [] @@ -40,7 +47,7 @@ export class PluginDevWatcher { failedBeforeReady = true if (subscription) { this.removeSubscription(subscription) - void subscription.unsubscribe() + releaseSubscription(subscription) } onWatcherError?.() this.scheduleRefresh(refresh) @@ -65,7 +72,7 @@ export class PluginDevWatcher { .then((created) => { subscription = created if (generation !== this.generation || failedBeforeReady) { - void created.unsubscribe() + releaseSubscription(created) return } this.subscriptions.push(created) @@ -85,7 +92,7 @@ export class PluginDevWatcher { this.refreshTimer = null } for (const subscription of this.subscriptions.splice(0)) { - void subscription.unsubscribe() + releaseSubscription(subscription) } } diff --git a/src/main/providers/local-pty-provider.test.ts b/src/main/providers/local-pty-provider.test.ts index 5f90d22b64e..e1c62e9f3cb 100644 --- a/src/main/providers/local-pty-provider.test.ts +++ b/src/main/providers/local-pty-provider.test.ts @@ -224,6 +224,25 @@ describe('LocalPtyProvider', () => { expect(typeof result.id).toBe('string') }) + it('expands variables in PATH before spawning a Windows shell', async () => { + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + await provider.spawn({ + cols: 80, + rows: 24, + cwd: 'C:\\repo', + env: { + ORCA_AGENT_TEAMS_TEAM_ID: 'team-test', + ORCA_PATH_ROOT: 'C:\\Users\\orca\\AppData\\Local', + PATH: '%orca_path_root%\\agy\\bin;C:\\Windows' + } + }) + + expect(spawnMock.mock.calls.at(-1)?.[2].env.PATH).toBe( + 'C:\\Users\\orca\\AppData\\Local\\agy\\bin;C:\\Windows' + ) + }) + it('reattaches to an existing caller-supplied session id without spawning', async () => { const first = await provider.spawn({ cols: 80, rows: 24, sessionId: 'serve-session-1' }) spawnMock.mockClear() @@ -239,6 +258,55 @@ describe('LocalPtyProvider', () => { expect(spawnMock).not.toHaveBeenCalled() }) + it('attaches only to an existing stable session', async () => { + await provider.spawn({ cols: 80, rows: 24, sessionId: 'stable-pane-session' }) + spawnMock.mockClear() + + const result = await provider.spawn({ + cols: 120, + rows: 40, + sessionId: 'stable-pane-session', + attachOnly: true + }) + + expect(result).toMatchObject({ id: 'stable-pane-session', isReattach: true }) + expect(spawnMock).not.toHaveBeenCalled() + }) + + it('does not create when an attach-only stable session is absent', async () => { + await expect( + provider.spawn({ + cols: 80, + rows: 24, + sessionId: 'missing-stable-pane-session', + attachOnly: true + }) + ).rejects.toThrow('Session not found: missing-stable-pane-session') + expect(spawnMock).not.toHaveBeenCalled() + }) + + it('attaches only to an existing numeric provider session', async () => { + const first = await provider.spawn({ cols: 80, rows: 24 }) + spawnMock.mockClear() + + const result = await provider.spawn({ + cols: 120, + rows: 40, + sessionId: first.id, + attachOnly: true + }) + + expect(result).toMatchObject({ id: first.id, isReattach: true }) + expect(spawnMock).not.toHaveBeenCalled() + }) + + it('does not create when a numeric attach-only provider session is absent', async () => { + await expect( + provider.spawn({ cols: 80, rows: 24, sessionId: '404', attachOnly: true }) + ).rejects.toThrow('Session not found: 404') + expect(spawnMock).not.toHaveBeenCalled() + }) + it('keeps a native UNC session native on a conflicting WSL reattach', async () => { Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) const first = await provider.spawn({ @@ -737,6 +805,31 @@ describe('LocalPtyProvider', () => { expect(spawnCall[2].env.ORCA_SHELL_READY_MARKER).toBe('0') }) + it('promotes the agent-teams shim onto the Windows `Path` spelling', async () => { + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + provider.configure({ + buildSpawnEnv: (_id, env) => { + // Why: attribution collapses Windows PATH onto `Path` and prepends its own shim dir. + delete env.PATH + env.Path = `/tmp/orca-attribution:${env.Path ?? ''}` + return env + } + }) + + await provider.spawn({ + cols: 80, + rows: 24, + env: { + Path: '/tmp/orca-agent-teams-bin:/usr/bin', + ORCA_AGENT_TEAMS_TEAM_ID: 'team-test' + } + }) + + const spawnEnv = spawnMock.mock.calls.at(-1)![2].env + expect(Object.keys(spawnEnv).filter((key) => /^path$/i.test(key))).toEqual(['Path']) + expect(spawnEnv.Path.split(':')[0]).toBe('/tmp/orca-agent-teams-bin') + }) + it('does not pass a Windows Codex home into WSL terminals', async () => { Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) provider.configure({ diff --git a/src/main/providers/local-pty-provider.ts b/src/main/providers/local-pty-provider.ts index 39a00c823d7..d43158482c0 100644 --- a/src/main/providers/local-pty-provider.ts +++ b/src/main/providers/local-pty-provider.ts @@ -38,6 +38,7 @@ import type { ShellReadySignal } from './local-pty-shell-ready' import { removeInheritedNoColor } from '../pty/terminal-color-env' import { removeAppImageRuntimeEnv } from '../pty/appimage-terminal-env' import { stripInheritedBuildModeEnv } from '../pty/build-mode-env' +import { resolvePathEnvKey } from '../pty/windows-environment-path' import { isHostCodexHomeForWsl, isWslCodexHomeForHost } from '../pty/codex-home-wsl-env' import { addWslEnvKeys } from '../wsl-env' import { @@ -65,6 +66,14 @@ import { PhysicalExitTracker } from '../../shared/physical-exit-tracker' import { mergeGitConfigEnvProtocol } from '../../shared/git-credential-prompt-env' import { PtyStartupIngress, type PtyIngressEmission } from '../../shared/pty-startup-ingress' import { resolvePtyOwnerBackend } from '../../shared/pty-owner-backend' +import { + createPtySlaveEchoProbe, + readPtySlavePath +} from '../../shared/pty-slave-line-discipline-echo' +import { + expandWindowsEnvironmentVariables, + expandWindowsPathEnvironmentVariables +} from '../../shared/windows-environment-expansion' const PANE_IDENTITY_ENV_KEYS = [ 'ORCA_PANE_KEY', @@ -158,12 +167,18 @@ function promoteAgentTeamsShimPath( if (!env.ORCA_AGENT_TEAMS_TEAM_ID || !requestedPath) { return } - const shimDir = requestedPath.split(delimiter)[0] + const normalizedRequestedPath = + process.platform === 'win32' + ? expandWindowsEnvironmentVariables(requestedPath, env) + : requestedPath + const pathDelimiter = process.platform === 'win32' ? ';' : delimiter + const shimDir = normalizedRequestedPath.split(pathDelimiter)[0] if (!shimDir) { return } - const currentParts = env.PATH?.split(delimiter).filter(Boolean) ?? [] - env.PATH = [shimDir, ...currentParts.filter((part) => part !== shimDir)].join(delimiter) + const pathKey = resolvePathEnvKey(env, process.platform) + const currentParts = env[pathKey]?.split(pathDelimiter).filter(Boolean) ?? [] + env[pathKey] = [shimDir, ...currentParts.filter((part) => part !== shimDir)].join(pathDelimiter) } /** @@ -360,9 +375,12 @@ function cancelAllPendingLocalPtySpawns(): void { /** * Normalizes renderer session ids that should be reused for local PTY reattach. */ -function normalizeLocalCallerSessionId(sessionId: string | undefined): string | null { +function normalizeLocalCallerSessionId( + sessionId: string | undefined, + allowNumeric = false +): string | null { const requested = sessionId?.trim() - if (!requested || /^\d+$/.test(requested)) { + if (!requested || (!allowNumeric && /^\d+$/.test(requested))) { return null } return requested @@ -516,7 +534,7 @@ export class LocalPtyProvider implements IPtyProvider { * Windows launches can pre-deliver startup commands in argv, so the stdin fallback only runs when needed. */ async spawn(args: PtySpawnOptions): Promise { - const reattachId = normalizeLocalCallerSessionId(args.sessionId) + const reattachId = normalizeLocalCallerSessionId(args.sessionId, args.attachOnly === true) if (reattachId) { const pendingShutdown = ptyShutdownOperations.get(reattachId) if (pendingShutdown) { @@ -527,6 +545,9 @@ export class LocalPtyProvider implements IPtyProvider { return existing } } + if (args.attachOnly) { + throw new Error(`Session not found: ${args.sessionId ?? ''}`) + } const id = allocatePtyId(reattachId ?? undefined) const incarnationId = randomUUID() @@ -789,7 +810,12 @@ export class LocalPtyProvider implements IPtyProvider { shellReadyLaunch = args.command ? shellLaunch : null } } - promoteAgentTeamsShimPath(finalEnv, args.env?.PATH) + const requestedEnv = args.env + expandWindowsPathEnvironmentVariables(finalEnv) + promoteAgentTeamsShimPath( + finalEnv, + requestedEnv ? requestedEnv[resolvePathEnvKey(requestedEnv, process.platform)] : undefined + ) // Why: worktree-scoped HISTFILE — without it worktrees share one global history (terminal-history-scope-design §7–§10). const worktreeId = args.worktreeId @@ -900,6 +926,7 @@ export class LocalPtyProvider implements IPtyProvider { ) } } + const startupEchoProbe = createPtySlaveEchoProbe(readPtySlavePath(proc)) const startupIngress = new PtyStartupIngress({ ...(args.startupIngress ? { intent: args.startupIngress } : {}), ownerBackend: resolvePtyOwnerBackend({ @@ -908,7 +935,8 @@ export class LocalPtyProvider implements IPtyProvider { wslDistro: spawnedWslDistro }), write: (data) => proc.write(data), - onEmission: emitIngressData + onEmission: emitIngressData, + ...(startupEchoProbe ? { echoProbe: startupEchoProbe } : {}) }) startupIngressByPty.set(id, startupIngress) diff --git a/src/main/providers/pty-provider-contract.ts b/src/main/providers/pty-provider-contract.ts index f305f1e85b7..b766b11497d 100644 --- a/src/main/providers/pty-provider-contract.ts +++ b/src/main/providers/pty-provider-contract.ts @@ -62,6 +62,8 @@ export type PtySpawnOptions = { * Existing-session attach paths must stay false so recovery checks do not * replace the daemon out from under a still-live PTY. */ isNewSession?: boolean + /** Attach the named session atomically or fail without creating a process. */ + attachOnly?: boolean /** Why: allows the renderer to request a specific shell for a single new * terminal tab (e.g. "open this tab in WSL" from the "+" submenu) without * changing the user's persistent default shell setting. Only consulted on @@ -95,6 +97,10 @@ export type { PtyProcessInfo, PtySpawnResult } type PtyProbeOptions = { signal?: AbortSignal } export type IPtyProvider = { + /** Fresh local spawns currently route to an in-process, non-persistent fallback. */ + readonly routesFreshSpawnsToLocalProvider?: true + /** Re-probes a degraded durable host before main commits to fallback spawn semantics. */ + recoverFreshSpawnRouting?: () => Promise spawn(opts: PtySpawnOptions): Promise /** Whether this spawn target can append the Git guard after its final env merge. */ supportsGitCredentialGuardHost?: (sessionId?: string) => boolean diff --git a/src/main/pty/windows-environment-path.test.ts b/src/main/pty/windows-environment-path.test.ts index 69b502cdaf5..d639ee604ce 100644 --- a/src/main/pty/windows-environment-path.test.ts +++ b/src/main/pty/windows-environment-path.test.ts @@ -15,7 +15,8 @@ import { mergePersistedWindowsPath, mergePersistedWindowsPathAsync, readPersistedWindowsPathSegments, - readPersistedWindowsPathSegmentsAsync + readPersistedWindowsPathSegmentsAsync, + resolvePathEnvKey } from './windows-environment-path' type ExecCallback = (error: Error | null, stdout: string, stderr: string) => void @@ -242,6 +243,18 @@ describe('readPersistedWindowsPathSegments', () => { }) describe('mergePersistedWindowsPath', () => { + it('expands variables already present in the inherited PATH', () => { + const execFileSync = vi.fn().mockReturnValue(' Path REG_SZ \r\n') + const env = { + ORCA_PATH_ROOT: 'C:\\Users\\orca\\AppData\\Local', + Path: '%orca_path_root%\\agy\\bin;C:\\Windows' + } + + mergePersistedWindowsPath(env, { platform: 'win32', execFileSync, env }) + + expect(env.Path).toBe('C:\\Users\\orca\\AppData\\Local\\agy\\bin;C:\\Windows') + }) + it('appends missing persisted segments without reordering the inherited PATH', () => { const execFileSync = vi .fn() @@ -297,4 +310,53 @@ describe('mergePersistedWindowsPath', () => { expect(env).toEqual({ Path: 'C:\\Inherited;C:\\Machine;C:\\User' }) }) + + it('reads the live host spelling when a path-less env inherits duplicate keys', () => { + const execFileSync = vi + .fn() + .mockReturnValueOnce(' Path REG_SZ C:\\Machine\r\n') + .mockReturnValueOnce(' Path REG_SZ C:\\User\r\n') + const env: Record = {} + + mergePersistedWindowsPath(env, { + platform: 'win32', + execFileSync, + env: { ROOT: 'C:\\Root', Path: '%ROOT%\\Live', PATH: 'C:\\Shadowed' } + }) + + expect(env).toEqual({ Path: 'C:\\Root\\Live;C:\\Machine;C:\\User' }) + }) +}) + +describe('resolvePathEnvKey', () => { + it('uses whichever Windows spelling is present on the env', () => { + expect(resolvePathEnvKey({ Path: 'C:\\Windows' }, 'win32')).toBe('Path') + expect(resolvePathEnvKey({ PATH: 'C:\\Windows' }, 'win32')).toBe('PATH') + expect(resolvePathEnvKey({ path: 'C:\\Windows' }, 'win32')).toBe('path') + expect(resolvePathEnvKey({ PaTh: 'C:\\Windows' }, 'win32')).toBe('PaTh') + }) + + // Why: Win32 returns the first case-insensitive match in the block, so a dual-cased env is + // resolved by position; picking by casing would target the spelling the child never sees. + it('resolves a dual-cased Windows env by block order, not casing', () => { + expect(resolvePathEnvKey({ PATH: 'C:\\Live', Path: 'C:\\Shadowed' }, 'win32')).toBe('PATH') + expect(resolvePathEnvKey({ Path: 'C:\\Live', PATH: 'C:\\Shadowed' }, 'win32')).toBe('Path') + }) + + it('skips a path key explicitly set to undefined', () => { + expect(resolvePathEnvKey({ PATH: undefined, Path: 'C:\\Windows' }, 'win32')).toBe('Path') + }) + + it('falls back to the host block spelling for a Windows env with no path key', () => { + // Why: a sparse patch that guesses wrong leaves the daemon's own merge holding both keys. + expect(resolvePathEnvKey({}, 'win32', { PATH: 'C:\\Windows' })).toBe('PATH') + expect(resolvePathEnvKey({}, 'win32', { Path: 'C:\\Windows' })).toBe('Path') + expect(resolvePathEnvKey({}, 'win32', { Path: 'C:\\Live', PATH: 'C:\\Shadowed' })).toBe('Path') + expect(resolvePathEnvKey({}, 'win32', {})).toBe('Path') + }) + + it('always resolves `PATH` off Windows so a POSIX `Path` variable is untouched', () => { + expect(resolvePathEnvKey({ Path: '/decoy' }, 'linux')).toBe('PATH') + expect(resolvePathEnvKey({ Path: '/decoy', PATH: '/usr/bin' }, 'darwin')).toBe('PATH') + }) }) diff --git a/src/main/pty/windows-environment-path.ts b/src/main/pty/windows-environment-path.ts index df0b53d3476..36032da9aec 100644 --- a/src/main/pty/windows-environment-path.ts +++ b/src/main/pty/windows-environment-path.ts @@ -1,4 +1,8 @@ import { execFile, execFileSync } from 'node:child_process' +import { + expandWindowsEnvironmentVariables, + expandWindowsPathEnvironmentVariables +} from '../../shared/windows-environment-expansion' import { getRegExePath } from '../win32-utils' type ExecFile = typeof execFile @@ -44,14 +48,6 @@ function parseRegistryPathValue(output: string, valueName: string): string | nul return null } -function expandWindowsEnvironmentVariables(value: string, env: NodeJS.ProcessEnv): string { - return value.replace(/%([^%]+)%/g, (match, rawName: string) => { - const name = rawName.toLowerCase() - const envKey = Object.keys(env).find((key) => key.toLowerCase() === name) - return envKey && env[envKey] ? env[envKey] : match - }) -} - function getPathDelimiter(platform: NodeJS.Platform): string { return platform === 'win32' ? ';' : ':' } @@ -240,15 +236,43 @@ export function __resetPersistedWindowsPathCacheForTests(): void { pendingPersistedWindowsPathRefresh = undefined } +/** Resolves the first PATH key a Windows child reads from an env block. */ +export function resolvePathEnvKey( + env: NodeJS.ProcessEnv | Record, + platform: NodeJS.Platform, + hostEnv: NodeJS.ProcessEnv = process.env +): string { + if (platform !== 'win32') { + return 'PATH' + } + // Why: the daemon receives a sparse env patch and re-merges its own block underneath it; + // matching the block's spelling stops that merge from resurrecting the other one. + return firstWindowsPathEnvKey(env) ?? firstWindowsPathEnvKey(hostEnv) ?? 'Path' +} + +// Why: Win32 resolves the first case-insensitive key, and object order preserves block order. +function firstWindowsPathEnvKey( + env: NodeJS.ProcessEnv | Record +): string | undefined { + for (const key of Object.keys(env)) { + if (key.toLowerCase() === 'path' && env[key] !== undefined) { + return key + } + } + return undefined +} + function mergeWindowsPathSegments( env: NodeJS.ProcessEnv, persistedSegments: string[], platform: NodeJS.Platform, sourceEnv: NodeJS.ProcessEnv ): void { - const pathKey = env.Path !== undefined ? 'Path' : env.PATH !== undefined ? 'PATH' : 'Path' + expandWindowsPathEnvironmentVariables(env, platform) + const pathKey = resolvePathEnvKey(env, platform, sourceEnv) const pathDelimiter = getPathDelimiter(platform) - const currentPath = env[pathKey] ?? sourceEnv.PATH ?? sourceEnv.Path ?? '' + const currentPath = + env[pathKey] ?? expandWindowsEnvironmentVariables(sourceEnv[pathKey] ?? '', sourceEnv) const currentSegments = splitPathSegments(currentPath, pathDelimiter) const existing = new Set(currentSegments.map((segment) => segment.toLowerCase())) const missing = persistedSegments.filter((segment) => { diff --git a/src/main/rate-limits/codex-fetcher-auth-errors.test.ts b/src/main/rate-limits/codex-fetcher-auth-errors.test.ts index 5f5944191c0..f482d2594b3 100644 --- a/src/main/rate-limits/codex-fetcher-auth-errors.test.ts +++ b/src/main/rate-limits/codex-fetcher-auth-errors.test.ts @@ -34,13 +34,24 @@ function makeRpcChild() { const child = new EventEmitter() as EventEmitter & { stdout: EventEmitter stderr: EventEmitter - stdin: { write: ReturnType } + stdin: EventEmitter & { write: ReturnType; end: ReturnType } kill: ReturnType + exitCode: number | null } child.stdout = new EventEmitter() child.stderr = new EventEmitter() - child.stdin = { write: vi.fn() } - child.kill = vi.fn() + // Why: like the real app-server, the fake dies on stdin EOF or a signal — + // the graceful shutdown path resolves only once the child reports exit. + const exitNow = (): void => { + child.exitCode = 0 + child.emit('exit', 0, null) + } + child.stdin = Object.assign(new EventEmitter(), { write: vi.fn(), end: vi.fn(exitNow) }) + child.exitCode = null + child.kill = vi.fn(() => { + exitNow() + return true + }) return child } diff --git a/src/main/rate-limits/codex-fetcher-probe-shutdown.test.ts b/src/main/rate-limits/codex-fetcher-probe-shutdown.test.ts new file mode 100644 index 00000000000..db0c4a7f5ed --- /dev/null +++ b/src/main/rate-limits/codex-fetcher-probe-shutdown.test.ts @@ -0,0 +1,383 @@ +import { EventEmitter } from 'node:events' +import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest' + +const { childSpawnMock, readFileMock, resolveCodexCommandMock, ptySpawnMock } = vi.hoisted(() => ({ + childSpawnMock: vi.fn(), + readFileMock: vi.fn(), + resolveCodexCommandMock: vi.fn(), + ptySpawnMock: vi.fn() +})) + +vi.mock('node:child_process', () => ({ + spawn: childSpawnMock +})) + +vi.mock('node:fs/promises', () => ({ + readFile: readFileMock +})) + +vi.mock('../codex-cli/command', () => ({ + resolveCodexCommand: resolveCodexCommandMock +})) + +vi.mock('node-pty', () => ({ + spawn: ptySpawnMock +})) + +// Auth gate is covered by codex-auth-presence.test.ts; these tests assume a signed-in Codex. +vi.mock('./codex-auth-presence', () => ({ + probeCodexAuthPresence: vi.fn(() => 'present') +})) + +import { fetchCodexRateLimits } from './codex-fetcher' +import { probeCodexAuthPresence } from './codex-auth-presence' + +function makeRpcChild() { + const child = new EventEmitter() as EventEmitter & { + stdout: EventEmitter + stderr: EventEmitter + stdin: EventEmitter & { write: ReturnType; end: ReturnType } + kill: ReturnType + exitCode: number | null + } + child.stdout = new EventEmitter() + child.stderr = new EventEmitter() + // Why: like the real app-server, the fake dies on stdin EOF or a signal — + // the graceful shutdown path resolves only once the child reports exit. + const exitNow = (): void => { + child.exitCode = 0 + child.emit('exit', 0, null) + } + child.stdin = Object.assign(new EventEmitter(), { write: vi.fn(), end: vi.fn(exitNow) }) + child.exitCode = null + child.kill = vi.fn(() => { + exitNow() + return true + }) + return child +} + +function respondToRpcRateLimitRead( + rpcChild: ReturnType, + rateLimits: unknown +): void { + rpcChild.stdin.write.mockImplementation((line: string) => { + const msg = JSON.parse(line) as { id?: number; method?: string } + if (msg.method === 'initialize') { + setTimeout(() => { + rpcChild.stdout.emit( + 'data', + Buffer.from(`${JSON.stringify({ jsonrpc: '2.0', id: msg.id, result: {} })}\n`) + ) + }, 0) + } + if (msg.method === 'account/rateLimits/read') { + setTimeout(() => { + rpcChild.stdout.emit( + 'data', + Buffer.from(`${JSON.stringify({ jsonrpc: '2.0', id: msg.id, result: { rateLimits } })}\n`) + ) + }, 0) + } + }) +} + +describe('fetchCodexRateLimits probe shutdown', () => { + beforeEach(() => { + vi.useFakeTimers() + vi.clearAllMocks() + resolveCodexCommandMock.mockReturnValue('codex') + vi.mocked(probeCodexAuthPresence).mockResolvedValue('present') + readFileMock.mockRejectedValue(new Error('no auth fixture')) + vi.stubGlobal('fetch', vi.fn()) + }) + + afterEach(() => { + vi.unstubAllGlobals() + }) + + it('gives a cold app-server the full boot budget before any deadline fires', async () => { + const rpcChild = makeRpcChild() + childSpawnMock.mockReturnValue(rpcChild) + rpcChild.stdin.write.mockImplementation((line: string) => { + const msg = JSON.parse(line) as { id?: number; method?: string } + if (msg.method === 'initialize') { + // Why: cold starts (auth refresh included) are documented at 10-25s; + // the old 10s deadline killed them mid-auth. + setTimeout(() => { + rpcChild.stdout.emit( + 'data', + Buffer.from(`${JSON.stringify({ jsonrpc: '2.0', id: msg.id, result: {} })}\n`) + ) + }, 20_000) + } + if (msg.method === 'account/rateLimits/read') { + setTimeout(() => { + rpcChild.stdout.emit( + 'data', + Buffer.from( + `${JSON.stringify({ + jsonrpc: '2.0', + id: msg.id, + result: { + rateLimits: { primary: { usedPercent: 3 }, secondary: { usedPercent: 4 } } + } + })}\n` + ) + ) + }, 0) + } + }) + + const resultPromise = fetchCodexRateLimits({ allowPtyFallback: false }) + await vi.advanceTimersByTimeAsync(19_999) + expect(rpcChild.kill).not.toHaveBeenCalled() + + await vi.advanceTimersByTimeAsync(2) + await expect(resultPromise).resolves.toMatchObject({ + status: 'ok', + session: { usedPercent: 3 }, + weekly: { usedPercent: 4 } + }) + }) + + it('arms the read deadline after initialize and drains SIGTERM before SIGKILL', async () => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'darwin' }) + const rpcChild = makeRpcChild() + // Stubborn child: it ignores stdin EOF, survives SIGTERM, dies on SIGKILL. + rpcChild.stdin.end = vi.fn() + rpcChild.kill = vi.fn((signal?: string) => { + if (signal === 'SIGKILL') { + rpcChild.exitCode = 0 + rpcChild.emit('exit', 0, null) + } + return true + }) + childSpawnMock.mockReturnValue(rpcChild) + rpcChild.stdin.write.mockImplementation((line: string) => { + const msg = JSON.parse(line) as { id?: number; method?: string } + if (msg.method === 'initialize') { + setTimeout(() => { + rpcChild.stdout.emit( + 'data', + Buffer.from(`${JSON.stringify({ jsonrpc: '2.0', id: msg.id, result: {} })}\n`) + ) + }, 0) + } + // The rate-limits read never answers, so the request deadline expires. + }) + + try { + const resultPromise = fetchCodexRateLimits({ allowPtyFallback: false }) + await vi.advanceTimersByTimeAsync(0) + await vi.advanceTimersByTimeAsync(9_999) + expect(rpcChild.kill).not.toHaveBeenCalled() + + await vi.advanceTimersByTimeAsync(1) + expect(rpcChild.stdin.end).toHaveBeenCalledTimes(1) + expect(rpcChild.kill).toHaveBeenCalledWith('SIGTERM') + expect(rpcChild.kill).not.toHaveBeenCalledWith('SIGKILL') + + await vi.advanceTimersByTimeAsync(5_000) + expect(rpcChild.kill).toHaveBeenCalledWith('SIGKILL') + await expect(resultPromise).resolves.toMatchObject({ + status: 'error', + error: 'RPC timeout' + }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('does not spawn a second probe for the same home while one is still running', async () => { + const firstChild = makeRpcChild() + const secondChild = makeRpcChild() + childSpawnMock.mockReturnValueOnce(firstChild).mockReturnValueOnce(secondChild) + respondToRpcRateLimitRead(secondChild, { + primary: { usedPercent: 3 }, + secondary: { usedPercent: 4 } + }) + + const first = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-a' + }) + await vi.advanceTimersByTimeAsync(0) + const second = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-a' + }) + await vi.advanceTimersByTimeAsync(0) + expect(childSpawnMock).toHaveBeenCalledTimes(1) + + firstChild.emit('close') + await vi.advanceTimersByTimeAsync(1) + await vi.advanceTimersByTimeAsync(1) + await vi.advanceTimersByTimeAsync(1) + expect(childSpawnMock).toHaveBeenCalledTimes(2) + await expect(second).resolves.toMatchObject({ status: 'ok' }) + await first + }) + + it('keeps the home lock through child errors until the failed probe exits', async () => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'darwin' }) + const firstChild = makeRpcChild() + firstChild.stdin.end = vi.fn() + firstChild.kill = vi.fn((signal?: string) => { + if (signal === 'SIGKILL') { + firstChild.exitCode = 1 + firstChild.emit('exit', 1, 'SIGKILL') + } + return true + }) + const secondChild = makeRpcChild() + childSpawnMock.mockReturnValueOnce(firstChild).mockReturnValueOnce(secondChild) + respondToRpcRateLimitRead(secondChild, { + primary: { usedPercent: 3 }, + secondary: { usedPercent: 4 } + }) + + try { + const first = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-error' + }) + await vi.advanceTimersByTimeAsync(0) + firstChild.emit('error', new Error('stdio failed')) + const second = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-error' + }) + await vi.advanceTimersByTimeAsync(0) + + expect(firstChild.kill).toHaveBeenCalledWith('SIGTERM') + expect(childSpawnMock).toHaveBeenCalledTimes(1) + await vi.advanceTimersByTimeAsync(5_000) + expect(firstChild.kill).toHaveBeenCalledWith('SIGKILL') + expect(childSpawnMock).toHaveBeenCalledTimes(2) + await vi.advanceTimersByTimeAsync(1) + await vi.advanceTimersByTimeAsync(1) + await expect(first).resolves.toMatchObject({ status: 'error', error: 'stdio failed' }) + await expect(second).resolves.toMatchObject({ status: 'ok' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it.each([ + { failAt: 1, phase: 'initial request' }, + { failAt: 2, phase: 'initialized notification' }, + { failAt: 3, phase: 'rate-limit request' } + ])('keeps the home lock when the $phase stdin write throws', async ({ failAt, phase }) => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'darwin' }) + const firstChild = makeRpcChild() + let writeCount = 0 + firstChild.stdin.write.mockImplementation((line: string) => { + writeCount += 1 + if (writeCount === failAt) { + throw new Error(`${phase} stdin failed`) + } + const message = JSON.parse(line) as { id?: number; method?: string } + if (message.method === 'initialize') { + setTimeout(() => { + firstChild.stdout.emit( + 'data', + Buffer.from(`${JSON.stringify({ jsonrpc: '2.0', id: message.id, result: {} })}\n`) + ) + }, 0) + } + }) + firstChild.stdin.end = vi.fn() + firstChild.kill = vi.fn((signal?: string) => { + if (signal === 'SIGKILL') { + firstChild.exitCode = 1 + firstChild.emit('exit', 1, 'SIGKILL') + } + return true + }) + const secondChild = makeRpcChild() + childSpawnMock.mockReturnValueOnce(firstChild).mockReturnValueOnce(secondChild) + respondToRpcRateLimitRead(secondChild, { + primary: { usedPercent: 3 }, + secondary: { usedPercent: 4 } + }) + const home = `/managed/home-stdin-error-${failAt}` + + try { + const first = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: home + }) + await vi.advanceTimersByTimeAsync(0) + expect(firstChild.kill).toHaveBeenCalledWith('SIGTERM') + + const second = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: home + }) + await vi.advanceTimersByTimeAsync(4_999) + expect(childSpawnMock).toHaveBeenCalledTimes(1) + + await vi.advanceTimersByTimeAsync(1) + expect(firstChild.kill).toHaveBeenCalledWith('SIGKILL') + await vi.advanceTimersByTimeAsync(1) + expect(childSpawnMock).toHaveBeenCalledTimes(2) + await vi.advanceTimersByTimeAsync(1) + await expect(first).resolves.toMatchObject({ + status: 'error', + error: `${phase} stdin failed` + }) + await expect(second).resolves.toMatchObject({ status: 'ok' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('observes asynchronous stdin failures and keeps the lock until the probe exits', async () => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'darwin' }) + const firstChild = makeRpcChild() + firstChild.stdin.end = vi.fn() + firstChild.kill = vi.fn((signal?: string) => { + if (signal === 'SIGKILL') { + firstChild.exitCode = 1 + firstChild.emit('exit', 1, 'SIGKILL') + } + return true + }) + const secondChild = makeRpcChild() + childSpawnMock.mockReturnValueOnce(firstChild).mockReturnValueOnce(secondChild) + respondToRpcRateLimitRead(secondChild, { + primary: { usedPercent: 3 }, + secondary: { usedPercent: 4 } + }) + + try { + const first = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-async-stdin-error' + }) + await vi.advanceTimersByTimeAsync(0) + firstChild.stdin.emit('error', Object.assign(new Error('write EPIPE'), { code: 'EPIPE' })) + const second = fetchCodexRateLimits({ + allowPtyFallback: false, + codexHomePath: '/managed/home-async-stdin-error' + }) + + await vi.advanceTimersByTimeAsync(4_999) + expect(childSpawnMock).toHaveBeenCalledTimes(1) + await vi.advanceTimersByTimeAsync(1) + expect(firstChild.kill).toHaveBeenCalledWith('SIGKILL') + await vi.advanceTimersByTimeAsync(1) + expect(childSpawnMock).toHaveBeenCalledTimes(2) + await vi.advanceTimersByTimeAsync(1) + await expect(first).resolves.toMatchObject({ status: 'error', error: 'write EPIPE' }) + await expect(second).resolves.toMatchObject({ status: 'ok' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) +}) diff --git a/src/main/rate-limits/codex-fetcher-session-supplement.test.ts b/src/main/rate-limits/codex-fetcher-session-supplement.test.ts index 9bef59e96bd..232bfc9a83d 100644 --- a/src/main/rate-limits/codex-fetcher-session-supplement.test.ts +++ b/src/main/rate-limits/codex-fetcher-session-supplement.test.ts @@ -20,13 +20,25 @@ function makeRpcChild(rateLimitResetCredits?: unknown) { const child = new EventEmitter() as EventEmitter & { stdout: EventEmitter stderr: EventEmitter - stdin: { write: ReturnType } + stdin: EventEmitter & { write: ReturnType; end: ReturnType } kill: ReturnType + exitCode: number | null } child.stdout = new EventEmitter() child.stderr = new EventEmitter() - child.kill = vi.fn() - child.stdin = { + child.exitCode = null + // Why: like the real app-server, the fake dies on stdin EOF or a signal — + // the graceful shutdown path resolves only once the child reports exit. + const exitNow = (): void => { + child.exitCode = 0 + child.emit('exit', 0, null) + } + child.kill = vi.fn(() => { + exitNow() + return true + }) + child.stdin = Object.assign(new EventEmitter(), { + end: vi.fn(exitNow), write: vi.fn((line: string) => { const message = JSON.parse(line) as { id?: number; method?: string } if (message.method === 'initialize') { @@ -57,7 +69,7 @@ function makeRpcChild(rateLimitResetCredits?: unknown) { }, 0) } }) - } + }) return child } diff --git a/src/main/rate-limits/codex-fetcher.test.ts b/src/main/rate-limits/codex-fetcher.test.ts index 11057a1fc81..aedd386563a 100644 --- a/src/main/rate-limits/codex-fetcher.test.ts +++ b/src/main/rate-limits/codex-fetcher.test.ts @@ -43,13 +43,25 @@ function makeRpcChild() { const child = new EventEmitter() as EventEmitter & { stdout: EventEmitter stderr: EventEmitter - stdin: { write: ReturnType } + stdin: EventEmitter & { write: ReturnType; end: ReturnType } kill: ReturnType + exitCode: number | null } child.stdout = new EventEmitter() child.stderr = new EventEmitter() - child.stdin = { write: vi.fn() } - child.kill = vi.fn() + // Why: like the real app-server, the fake dies on stdin EOF or a signal — + // the graceful shutdown path resolves only once the child reports exit. + const exitNow = (): void => { + child.exitCode = 0 + child.emit('exit', 0, null) + child.emit('close', 0, null) + } + child.stdin = Object.assign(new EventEmitter(), { write: vi.fn(), end: vi.fn(exitNow) }) + child.exitCode = null + child.kill = vi.fn(() => { + exitNow() + return true + }) return child } @@ -325,6 +337,7 @@ describe('fetchCodexRateLimits', () => { weekly: null, status: 'error' }) + expect(rpcChild.stdin.listenerCount('error')).toBe(0) expect(ptySpawnMock).not.toHaveBeenCalled() }) @@ -333,7 +346,8 @@ describe('fetchCodexRateLimits', () => { childSpawnMock.mockReturnValue(rpcChild) const resultPromise = fetchCodexRateLimits({ allowPtyFallback: false }) - await vi.advanceTimersByTimeAsync(10_000) + // Why: without an initialize response only the 30s boot deadline fires. + await vi.advanceTimersByTimeAsync(30_000) await expect(resultPromise).resolves.toMatchObject({ provider: 'codex', diff --git a/src/main/rate-limits/codex-fetcher.ts b/src/main/rate-limits/codex-fetcher.ts index 9173d192038..50c97ff5da7 100644 --- a/src/main/rate-limits/codex-fetcher.ts +++ b/src/main/rate-limits/codex-fetcher.ts @@ -36,9 +36,19 @@ import { createAuthFilesystemOperation, type SharedAuthFilesystemOperation } from './auth-filesystem-operation' +import { terminateCodexProbeChild } from './codex-probe-termination' +import { + resolveCodexHomeProcessLockKey, + withCodexHomeProcessLock +} from '../codex-cli/codex-home-process-lock' const RPC_TIMEOUT_MS = 10_000 const WSL_RPC_TIMEOUT_MS = 25_000 +// Why: cold app-server starts (fresh token refresh included) are documented at +// 10-25s; the request deadline is armed only after initialize responds, so +// these boot budgets are what protect a slow cold start from a mid-auth kill. +const RPC_INIT_TIMEOUT_MS = 30_000 +const WSL_RPC_INIT_TIMEOUT_MS = 40_000 const PTY_TIMEOUT_MS = 15_000 // Why: codex ≥0.145 renders a '›' composer with placeholder text after it, so a // prompt-anchored send can never fire; nudge /status after a short boot grace. @@ -619,7 +629,8 @@ async function fetchViaRpc(options?: FetchCodexRateLimitsOptions): Promise resolve(result), + () => resolve(result) + ) + return } resolve(result) } @@ -676,19 +693,25 @@ async function fetchViaRpc(options?: FetchCodexRateLimitsOptions): Promise { - settle( - { - provider: 'codex', - session: null, - weekly: null, - updatedAt: Date.now(), - error: 'RPC timeout', - status: 'error' - }, - { kill: true } - ) - }, rpcTimeoutMs) + function armRpcDeadline(deadlineMs: number): void { + if (timeout) { + clearTimeout(timeout) + } + timeout = setTimeout(() => { + settle( + { + provider: 'codex', + session: null, + weekly: null, + updatedAt: Date.now(), + error: 'RPC timeout', + status: 'error' + }, + { kill: true } + ) + }, deadlineMs) + } + armRpcDeadline(initTimeoutMs) function sendRpc(method: string, params?: unknown): number { const id = ++rpcId @@ -696,12 +719,28 @@ async function fetchViaRpc(options?: FetchCodexRateLimitsOptions): Promise fetchViaRpc(options)) if (options?.signal?.aborted) { return abortedCodexRateLimitResult() } @@ -1238,7 +1294,7 @@ export async function fetchCodexRateLimits( if (options?.signal?.aborted) { return abortedCodexRateLimitResult() } - const ptyResult = await fetchViaPty(options) + const ptyResult = await withCodexHomeProcessLock(homeLockKey, () => fetchViaPty(options)) if (options?.signal?.aborted) { return abortedCodexRateLimitResult() } diff --git a/src/main/rate-limits/codex-probe-termination.test.ts b/src/main/rate-limits/codex-probe-termination.test.ts new file mode 100644 index 00000000000..4fb029e01a9 --- /dev/null +++ b/src/main/rate-limits/codex-probe-termination.test.ts @@ -0,0 +1,145 @@ +import { EventEmitter } from 'node:events' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { CODEX_PROBE_SHUTDOWN_DRAIN_MS, terminateCodexProbeChild } from './codex-probe-termination' + +function makeFakeChild() { + const emitter = new EventEmitter() + const child = { + pid: 4321, + exitCode: null as number | null, + signalCode: null as NodeJS.Signals | null, + stdin: { end: vi.fn() }, + kill: vi.fn((_signal?: NodeJS.Signals) => true), + on: emitter.on.bind(emitter), + once: emitter.once.bind(emitter), + off: emitter.off.bind(emitter), + exit(code = 0) { + child.exitCode = code + emitter.emit('exit') + }, + error() { + emitter.emit('error', new Error('signal delivery failed')) + } + } + return child +} + +describe('terminateCodexProbeChild', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('requests shutdown and never hard-kills a child that drains in time', async () => { + const child = makeFakeChild() + const done = terminateCodexProbeChild(child, { platform: 'darwin' }) + + expect(child.stdin.end).toHaveBeenCalledTimes(1) + expect(child.kill).toHaveBeenCalledWith('SIGTERM') + + await vi.advanceTimersByTimeAsync(CODEX_PROBE_SHUTDOWN_DRAIN_MS - 1) + child.exit() + await done + + expect(child.kill).toHaveBeenCalledTimes(1) + expect(child.kill).not.toHaveBeenCalledWith('SIGKILL') + }) + + it('escalates to SIGKILL only after the drain window elapses', async () => { + const child = makeFakeChild() + const done = terminateCodexProbeChild(child, { platform: 'linux' }) + + await vi.advanceTimersByTimeAsync(CODEX_PROBE_SHUTDOWN_DRAIN_MS) + expect(child.kill).toHaveBeenCalledWith('SIGKILL') + + child.exit() + await done + expect(child.kill.mock.calls.map((call) => call[0])).toEqual(['SIGTERM', 'SIGKILL']) + }) + + it('resolves within the hard-kill bound even if the child never reports exit', async () => { + const child = makeFakeChild() + let settled = false + const done = terminateCodexProbeChild(child, { platform: 'linux' }).then(() => { + settled = true + }) + + await vi.advanceTimersByTimeAsync(CODEX_PROBE_SHUTDOWN_DRAIN_MS + 1_000) + await done + expect(settled).toBe(true) + }) + + it('does not treat a child error as proof that the process exited', async () => { + const child = makeFakeChild() + let settled = false + const done = terminateCodexProbeChild(child, { platform: 'linux' }).then(() => { + settled = true + }) + + child.error() + await Promise.resolve() + expect(settled).toBe(false) + + child.exit() + await done + expect(settled).toBe(true) + }) + + it('sends no signal during the drain window on Windows where kill is always forceful', async () => { + const child = makeFakeChild() + const killWindowsProcessTree = vi.fn(async () => {}) + const done = terminateCodexProbeChild(child, { platform: 'win32', killWindowsProcessTree }) + + expect(child.stdin.end).toHaveBeenCalledTimes(1) + expect(child.kill).not.toHaveBeenCalled() + + await vi.advanceTimersByTimeAsync(CODEX_PROBE_SHUTDOWN_DRAIN_MS) + expect(killWindowsProcessTree).toHaveBeenCalledWith(child.pid) + expect(child.kill).toHaveBeenCalledTimes(1) + expect(child.kill).toHaveBeenCalledWith() + + child.exit() + await done + }) + + it('waits for the Windows descendant tree kill before releasing the probe', async () => { + const child = makeFakeChild() + let finishTreeKill!: () => void + const treeKill = new Promise((resolve) => { + finishTreeKill = resolve + }) + const killWindowsProcessTree = vi.fn(() => treeKill) + let settled = false + const done = terminateCodexProbeChild(child, { + platform: 'win32', + drainMs: 0, + killWindowsProcessTree + }).then(() => { + settled = true + }) + + await vi.advanceTimersByTimeAsync(0) + expect(killWindowsProcessTree).toHaveBeenCalledWith(child.pid) + child.exit() + await Promise.resolve() + expect(settled).toBe(false) + + finishTreeKill() + await done + expect(settled).toBe(true) + expect(child.kill).not.toHaveBeenCalled() + }) + + it('does nothing for a child that already exited', async () => { + const child = makeFakeChild() + child.exit() + + await terminateCodexProbeChild(child, { platform: 'darwin' }) + + expect(child.stdin.end).not.toHaveBeenCalled() + expect(child.kill).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/rate-limits/codex-probe-termination.ts b/src/main/rate-limits/codex-probe-termination.ts new file mode 100644 index 00000000000..e5a2f966542 --- /dev/null +++ b/src/main/rate-limits/codex-probe-termination.ts @@ -0,0 +1,111 @@ +import { terminateWindowsProcessTree, type WindowsTreeKiller } from '../windows-process-tree-kill' + +// Why: Codex OAuth uses rotating refresh tokens. Hard-killing a probe's +// app-server mid-refresh can strand auth.json between rotations and permanently +// invalidate the stored credential, so termination always requests shutdown +// first and only escalates after a bounded drain window. + +export const CODEX_PROBE_SHUTDOWN_DRAIN_MS = 5_000 +const HARD_KILL_EXIT_WAIT_MS = 1_000 + +export type TerminatableProbeChild = { + pid?: number + exitCode: number | null + signalCode?: NodeJS.Signals | null + kill: (signal?: NodeJS.Signals) => boolean + on: (event: 'error', listener: () => void) => unknown + once: (event: 'exit' | 'close' | 'error', listener: () => void) => unknown + off: (event: 'exit' | 'close' | 'error', listener: () => void) => unknown + stdin?: { end: () => void } | null +} + +export type TerminateCodexProbeOptions = { + drainMs?: number + hardKillWaitMs?: number + // Why: injectable so the Windows branch is testable from POSIX CI hosts. + platform?: NodeJS.Platform + killWindowsProcessTree?: WindowsTreeKiller +} + +function hasExited(child: TerminatableProbeChild): boolean { + return child.exitCode != null || child.signalCode != null +} + +function waitForExit(child: TerminatableProbeChild, timeoutMs: number): Promise { + if (hasExited(child)) { + return Promise.resolve(true) + } + return new Promise((resolve) => { + let timer: ReturnType | null = null + const settle = (exited: boolean): void => { + if (timer) { + clearTimeout(timer) + timer = null + } + child.off('exit', onGone) + child.off('close', onGone) + child.off('error', onError) + resolve(exited) + } + const onGone = (): void => settle(true) + const onError = (): void => { + // Keep ChildProcess errors observed, but only exit/close proves it is gone. + } + // Node emits 'close' after both exit and spawn failure. A later 'error' + // alone does not prove a successfully spawned child released auth.json. + child.once('exit', onGone) + child.once('close', onGone) + child.on('error', onError) + timer = setTimeout(() => settle(false), timeoutMs) + }) +} + +export async function terminateCodexProbeChild( + child: TerminatableProbeChild, + options?: TerminateCodexProbeOptions +): Promise { + if (hasExited(child)) { + return + } + const platform = options?.platform ?? process.platform + // Why: stdin EOF is the graceful stop for a stdio JSON-RPC server and the + // only non-forceful request Windows has; SIGTERM backs it up where signals + // are real (Node's kill() on Windows is always TerminateProcess). + try { + child.stdin?.end() + } catch { + // stdin may already be destroyed; the signal/kill path still applies. + } + if (platform !== 'win32') { + try { + child.kill('SIGTERM') + } catch { + // Already-exited children can race the kill; the exit wait handles it. + } + } + if (await waitForExit(child, options?.drainMs ?? CODEX_PROBE_SHUTDOWN_DRAIN_MS)) { + return + } + if (platform === 'win32' && child.pid) { + try { + // npm-installed Codex runs beneath cmd.exe; killing only that wrapper can + // leave app-server alive after the credential-home lock is released. + await (options?.killWindowsProcessTree ?? terminateWindowsProcessTree)(child.pid) + } catch { + // The direct-child fallback still applies if an injected killer rejects. + } + } + if (hasExited(child)) { + return + } + try { + if (platform === 'win32') { + child.kill() + } else { + child.kill('SIGKILL') + } + } catch { + // Already-exited children can race the kill; the exit wait handles it. + } + await waitForExit(child, options?.hardKillWaitMs ?? HARD_KILL_EXIT_WAIT_MS) +} diff --git a/src/main/rate-limits/service.test.ts b/src/main/rate-limits/service.test.ts index 245ebed42d2..dafa9a30ed0 100644 --- a/src/main/rate-limits/service.test.ts +++ b/src/main/rate-limits/service.test.ts @@ -1987,6 +1987,51 @@ describe('RateLimitService', () => { expect(service.getState().inactiveCodexAccounts).toEqual([]) }) + it('keeps the inactive Codex debounce across an account switch instead of re-probing', async () => { + const service = new RateLimitService() + service.setInactiveCodexAccountsResolver(() => [ + { id: 'account-b', managedHomePath: '/tmp/account-b/home' } + ]) + vi.mocked(fetchCodexRateLimits).mockImplementation(async () => okProvider('codex', 10)) + + await service.fetchInactiveCodexAccountsOnOpen() + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(1) + + // The switch triggers exactly one fetch: the newly active account's. + await service.refreshForCodexAccountChange('account-a') + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(2) + + // Why: re-opening the switcher inside the debounce window must not spawn + // codex in every inactive credential home again. + await service.fetchInactiveCodexAccountsOnOpen() + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(2) + }) + + it('staggers inactive Codex probes instead of bursting every account at once', async () => { + vi.useFakeTimers() + try { + const service = new RateLimitService() + service.setInactiveCodexAccountsResolver(() => [ + { id: 'account-a', managedHomePath: '/tmp/account-a/home' }, + { id: 'account-b', managedHomePath: '/tmp/account-b/home' } + ]) + vi.mocked(fetchCodexRateLimits).mockImplementation(async () => okProvider('codex', 5)) + + const fetchOnOpen = service.fetchInactiveCodexAccountsOnOpen() + await vi.advanceTimersByTimeAsync(0) + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(1) + + await vi.advanceTimersByTimeAsync(1_999) + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(1) + + await vi.advanceTimersByTimeAsync(1) + expect(fetchCodexRateLimits).toHaveBeenCalledTimes(2) + await fetchOnOpen + } finally { + vi.useRealTimers() + } + }) + it('preserves Gemini buckets through getState after fetch', async () => { const service = new RateLimitService() diff --git a/src/main/rate-limits/service.ts b/src/main/rate-limits/service.ts index 312aa2d4e9c..7cdb1e7bef9 100644 --- a/src/main/rate-limits/service.ts +++ b/src/main/rate-limits/service.ts @@ -90,6 +90,10 @@ const RATE_LIMITED_STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000 // Why: statusline posts arrive on every turn; skip renderer pushes for identical windows so streaming sessions don't spam state updates. const LIVE_CLAUDE_INGEST_DEDUPE_MS = 30 * 1000 const INACTIVE_FETCH_DEBOUNCE_MS = 60 * 1000 // 60 seconds — debounce fetch-on-open +// Why: each inactive Codex probe spawns a real codex process inside that +// account's live credential home; pace them out instead of bursting every +// account the moment the switcher opens. +const INACTIVE_CODEX_PROBE_STAGGER_MS = 2_000 const DEFERRED_STARTUP_ACTIVE_REFRESH_MS = 1000 // Why: inactive account arrays are derived from provider caches on demand in getState()/pushToRenderer(). @@ -132,6 +136,23 @@ function normalizeClaudeConfigDir(dir: string | null | undefined): string | null return trimmed || null } +function delayUnlessAborted(ms: number, signal: AbortSignal): Promise { + if (signal.aborted) { + return Promise.resolve() + } + return new Promise((resolve) => { + const onAbort = (): void => { + clearTimeout(timer) + resolve() + } + const timer = setTimeout(() => { + signal.removeEventListener('abort', onAbort) + resolve() + }, ms) + signal.addEventListener('abort', onAbort, { once: true }) + }) +} + function isSameUsageWindow( a: ProviderRateLimits['session'], b: ProviderRateLimits['session'] @@ -393,7 +414,10 @@ export class RateLimitService { this.activeFailureStreakByProvider.codex = 0 this.inactiveCodexAccountsGeneration += 1 this.pruneInactiveCodexState() - this.lastInactiveCodexFetchAt = 0 + // Why: the switch must NOT reset the inactive-fetch debounce — re-probing + // every inactive account per switch spawns codex in each credential home + // and endangers rotating refresh tokens; the switcher shows the cached + // snapshot (seeded above for the outgoing account) until the debounce ends. // Why: clear the old Codex view immediately, else the previous account's limits show under the newly selected identity until the next poll. this.updateState({ ...this.state, @@ -611,6 +635,7 @@ export class RateLimitService { } this.pushToRenderer() + let staggerNextProbe = false try { for (const account of accounts) { if ( @@ -625,6 +650,23 @@ export class RateLimitService { this.pushToRenderer() continue } + if (staggerNextProbe) { + await delayUnlessAborted(INACTIVE_CODEX_PROBE_STAGGER_MS, signal) + // Why: the account set can change while the stagger delay runs. + if ( + signal.aborted || + fetchGeneration !== this.inactiveCodexAccountsGeneration || + !this.isCurrentInactiveCodexAccount(account.id) + ) { + this.inactiveCodexFetching.delete(account.id) + if (!this.isCurrentInactiveCodexAccount(account.id)) { + this.inactiveCodexCache.delete(account.id) + } + this.pushToRenderer() + continue + } + } + staggerNextProbe = true try { // Why: point fetchCodexRateLimits at the managed home directly, avoiding materializing credentials into the shared runtime location. // Why: no PTY fallback — the switcher preview shouldn't spawn hidden PTYs per account (can crash ConPTY on Windows); RPC-only is enough. diff --git a/src/main/runtime/claude-agent-teams-service.test.ts b/src/main/runtime/claude-agent-teams-service.test.ts index f02d470fc8a..a41668932f0 100644 --- a/src/main/runtime/claude-agent-teams-service.test.ts +++ b/src/main/runtime/claude-agent-teams-service.test.ts @@ -248,4 +248,24 @@ describe('ClaudeAgentTeamsService', () => { ) ).resolves.toMatchObject({ ok: false, exitCode: 1 }) }) + + it('keeps the inherited Windows `Path` instead of minting a truncated `PATH`', () => { + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + try { + const launch = new ClaudeAgentTeamsService().createLaunchEnv({ + leaderHandle: 'leader-handle', + baseEnv: { Path: 'C:\\Windows\\system32' }, + shimDir: 'C:\\orca-shim', + shimBin: 'C:\\orca.exe' + }) + + expect(Object.keys(launch.env).filter((key) => /^path$/i.test(key))).toEqual(['Path']) + expect(launch.env.Path).toBe('C:\\orca-shim;C:\\Windows\\system32') + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + }) }) diff --git a/src/main/runtime/claude-agent-teams-service.ts b/src/main/runtime/claude-agent-teams-service.ts index 1da810e4a33..1b0199c6bd0 100644 --- a/src/main/runtime/claude-agent-teams-service.ts +++ b/src/main/runtime/claude-agent-teams-service.ts @@ -1,6 +1,7 @@ import { randomBytes, randomUUID } from 'node:crypto' import { splitTmuxCommand } from '../../shared/claude-agent-teams-tmux-compat' import { ClaudeAgentTeamsTmuxDispatcher } from './claude-agent-teams-tmux-dispatcher' +import { resolvePathEnvKey } from '../pty/windows-environment-path' import type { AgentTeam, AgentTeamsLaunchEnv, @@ -30,13 +31,15 @@ export class ClaudeAgentTeamsService { const teamId = `team-${randomUUID()}` const token = randomBytes(32).toString('base64url') const leaderPane = '%1' - const pathValue = [args.shimDir, args.baseEnv.PATH] + // Why: Windows callers pass an env spelt `Path`; reading `PATH` there truncated the launch PATH to just the shim dir. + const pathKey = resolvePathEnvKey(args.baseEnv, process.platform) + const pathValue = [args.shimDir, args.baseEnv[pathKey]] .filter(Boolean) .join(process.platform === 'win32' ? ';' : ':') const tmuxValue = `/tmp/orca-claude-agent-teams/${teamId},0,1` const env: Record = { CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1', - PATH: pathValue, + [pathKey]: pathValue, TMUX: tmuxValue, TMUX_PANE: leaderPane, TERM: 'screen-256color', diff --git a/src/main/runtime/graph-sync-payload-partition.test.ts b/src/main/runtime/graph-sync-payload-partition.test.ts new file mode 100644 index 00000000000..6533a53f9fb --- /dev/null +++ b/src/main/runtime/graph-sync-payload-partition.test.ts @@ -0,0 +1,264 @@ +/** + * The renderer withholds unchanged mobile-session snapshots from the graph + * payload. Main must treat those worktrees as live rather than pruning them as + * removed, and must ask for a republish of any it no longer holds. + */ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { + RuntimeMobileSessionTabsResult, + RuntimeMobileSessionTabsSnapshot, + RuntimeSyncWindowGraphResult +} from '../../shared/runtime-types' +import type { WorkspaceSessionState } from '../../shared/types' +import { OrcaRuntimeService } from './orca-runtime' + +const WT_A = 'repo-1::/tmp/worktree-a' +const WT_B = 'repo-1::/tmp/worktree-b' + +const storeBase = { + getRepo: () => ({ + id: 'repo-1', + path: '/tmp/repo', + displayName: 'repo', + badgeColor: 'blue', + addedAt: 1 + }), + getRepos: () => [storeBase.getRepo()], + addRepo: () => {}, + updateRepo: () => undefined as never, + getAllWorktreeMeta: () => ({}), + getWorktreeMeta: () => undefined, + getGitHubCache: () => ({ pr: {}, issue: {} }), + setWorktreeMeta: () => undefined as never, + removeWorktreeMeta: () => {}, + getSettings: () => ({ + workspaceDir: '/tmp/workspaces', + nestWorkspaces: false, + refreshLocalBaseRefOnWorktreeCreate: false, + branchPrefix: 'none', + branchPrefixCustom: '' + }) +} + +function makeSession(overrides: Partial = {}): WorkspaceSessionState { + return { + activeRepoId: 'repo-1', + activeWorktreeId: WT_A, + activeTabId: null, + tabsByWorktree: {}, + terminalLayoutsByTabId: {}, + ...overrides + } +} + +function makeTerminalTab(id: string, ptyId: string) { + return { + id, + ptyId, + worktreeId: WT_A, + title: `Terminal ${id}`, + customTitle: null, + color: null, + sortOrder: 0, + createdAt: 1 + } +} + +type RuntimeInternals = { + mobileSessionTabsByWorktree: Map +} + +function createRuntime() { + let session = makeSession() + const runtime = new OrcaRuntimeService({ + ...storeBase, + getWorkspaceSession: () => session, + setWorkspaceSession: (next: WorkspaceSessionState) => { + session = next + } + }) + const events: RuntimeMobileSessionTabsResult[] = [] + runtime.onMobileSessionTabsChanged((snapshot) => events.push(snapshot)) + const setSession = (next: WorkspaceSessionState): void => { + session = next + } + const sync = ( + mobileSessionTabs: RuntimeMobileSessionTabsSnapshot[], + unchangedMobileSessionWorktrees?: string[] + ): RuntimeSyncWindowGraphResult => + runtime.syncWindowGraph(1, { + tabs: [], + leaves: [], + mobileSessionTabs, + ...(unchangedMobileSessionWorktrees ? { unchangedMobileSessionWorktrees } : {}) + }) + return { runtime, events, sync, setSession, internals: runtime as unknown as RuntimeInternals } +} + +function makeSnapshot(worktree: string, version: number): RuntimeMobileSessionTabsSnapshot { + return { + worktree, + publicationEpoch: 'renderer:test-epoch', + snapshotVersion: version, + activeGroupId: 'group-1', + activeTabId: 'tab-1::leaf-1', + activeTabType: 'terminal', + tabs: [ + { + type: 'terminal', + id: 'tab-1::leaf-1', + parentTabId: 'tab-1', + leafId: 'leaf-1', + title: `Terminal ${worktree}`, + isActive: true + } + ] + } +} + +describe('graph-sync mobile payload partition', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('keeps a withheld worktree alive instead of pruning it as removed', () => { + const { events, sync, internals } = createRuntime() + sync([makeSnapshot(WT_A, 1), makeSnapshot(WT_B, 2)]) + vi.advanceTimersByTime(300) + const storedB = internals.mobileSessionTabsByWorktree.get(WT_B) + expect(storedB).toBeDefined() + events.length = 0 + + // A publishes a change; B is withheld as unchanged rather than omitted. + sync([makeSnapshot(WT_A, 3)], [WT_B]) + vi.advanceTimersByTime(300) + + expect(internals.mobileSessionTabsByWorktree.get(WT_B)).toBe(storedB) + expect(events.filter((event) => 'removed' in event && event.removed === true)).toEqual([]) + expect(events.map((event) => event.worktree)).toEqual([WT_A]) + }) + + it('still prunes a worktree the renderer omits from both lists', () => { + const { events, sync, internals } = createRuntime() + sync([makeSnapshot(WT_A, 1), makeSnapshot(WT_B, 2)]) + vi.advanceTimersByTime(300) + events.length = 0 + + sync([makeSnapshot(WT_A, 3)], []) + vi.advanceTimersByTime(300) + + expect(internals.mobileSessionTabsByWorktree.has(WT_B)).toBe(false) + const removed = events.filter((event) => 'removed' in event && event.removed === true) + expect(removed.map((event) => event.worktree)).toEqual([WT_B]) + }) + + it('asks for a republish of a withheld worktree it dropped, and accepts the resend', () => { + const { sync, internals } = createRuntime() + sync([makeSnapshot(WT_A, 1), makeSnapshot(WT_B, 2)]) + vi.advanceTimersByTime(300) + + // Main drops B on its own (worktree metadata removal) while the renderer + // still believes B is delivered. + internals.mobileSessionTabsByWorktree.delete(WT_B) + + const result = sync([], [WT_A, WT_B]) + vi.advanceTimersByTime(300) + expect(result.mobileSessionResyncWorktrees).toEqual([WT_B]) + expect(internals.mobileSessionTabsByWorktree.has(WT_A)).toBe(true) + + // The renderer republishes B at the SAME (epoch, version) it last sent. The + // accept gate must no longer treat that as an already-accepted no-op. + const resend = sync([makeSnapshot(WT_B, 2)], [WT_A]) + vi.advanceTimersByTime(300) + expect(resend.mobileSessionResyncWorktrees).toBeUndefined() + expect(internals.mobileSessionTabsByWorktree.get(WT_B)?.tabs).toEqual([ + expect.objectContaining({ parentTabId: 'tab-1' }) + ]) + }) + + it('asks for a republish when headless hydration masks a dropped renderer snapshot', () => { + const { sync, setSession, internals } = createRuntime() + setSession( + makeSession({ + tabsByWorktree: { [WT_A]: [makeTerminalTab('serve-tab', 'serve-pty-1')] } + }) + ) + sync([makeSnapshot(WT_A, 1)]) + internals.mobileSessionTabsByWorktree.delete(WT_A) + + const result = sync([], [WT_A]) + expect(result.mobileSessionResyncWorktrees).toEqual([WT_A]) + expect(internals.mobileSessionTabsByWorktree.get(WT_A)?.publicationEpoch).toMatch( + /^headless-hydrated:/ + ) + + const resend = sync([makeSnapshot(WT_A, 1)], []) + expect(resend.mobileSessionResyncWorktrees).toBeUndefined() + expect( + internals.mobileSessionTabsByWorktree + .get(WT_A) + ?.tabs.map((tab) => (tab.type === 'terminal' ? tab.parentTabId : tab.id)) + ).toEqual(['tab-1', 'serve-tab']) + }) + + it('requests the accepted revision again to prune a stale preserved tab', () => { + const { sync, setSession, internals } = createRuntime() + setSession( + makeSession({ + tabsByWorktree: { [WT_A]: [makeTerminalTab('serve-tab', 'serve-pty-1')] } + }) + ) + sync([makeSnapshot(WT_A, 1)]) + expect( + internals.mobileSessionTabsByWorktree + .get(WT_A) + ?.tabs.some((tab) => tab.type === 'terminal' && tab.parentTabId === 'serve-tab') + ).toBe(true) + + setSession(makeSession()) + const result = sync([], [WT_A]) + expect(result.mobileSessionResyncWorktrees).toEqual([WT_A]) + + sync([makeSnapshot(WT_A, 1)], []) + expect( + internals.mobileSessionTabsByWorktree + .get(WT_A) + ?.tabs.some((tab) => tab.type === 'terminal' && tab.parentTabId === 'serve-tab') + ).toBe(false) + }) + + it('does not request a renderer tab rejected by the retirement fence', () => { + const { sync, setSession, internals } = createRuntime() + setSession( + makeSession({ + terminalTopologyRevisionByRepoId: { 'repo-1': 1 } + }) + ) + + sync([makeSnapshot(WT_A, 1)]) + expect(internals.mobileSessionTabsByWorktree.get(WT_A)?.tabs).toEqual([]) + + expect(sync([], [WT_A]).mobileSessionResyncWorktrees).toBeUndefined() + expect(sync([], [WT_A]).mobileSessionResyncWorktrees).toBeUndefined() + }) + + it('leaves the legacy full-payload contract untouched when no list is sent', () => { + const { events, sync, internals } = createRuntime() + sync([makeSnapshot(WT_A, 1), makeSnapshot(WT_B, 2)]) + vi.advanceTimersByTime(300) + events.length = 0 + + // No unchangedMobileSessionWorktrees field at all: omission still prunes. + sync([makeSnapshot(WT_A, 3)]) + vi.advanceTimersByTime(300) + + expect(internals.mobileSessionTabsByWorktree.has(WT_B)).toBe(false) + expect( + events.filter((event) => 'removed' in event && event.removed === true).map((e) => e.worktree) + ).toEqual([WT_B]) + }) +}) diff --git a/src/main/runtime/missing-worktree-terminal-reconciliation.test.ts b/src/main/runtime/missing-worktree-terminal-reconciliation.test.ts index f218f3a2c4f..22cf484a13e 100644 --- a/src/main/runtime/missing-worktree-terminal-reconciliation.test.ts +++ b/src/main/runtime/missing-worktree-terminal-reconciliation.test.ts @@ -64,14 +64,23 @@ describe('stopMissingWorktreeTerminals', () => { const localProvider = createProvider([`${deletedId}@@local-session`]) const sshProvider = createProvider([`${deletedId}@@ssh-session`]) const getSshProvider = vi.fn(() => sshProvider) + const runtime = createRuntime() await stopMissingWorktreeTerminals({ ...localRepo, connectionId: 'ssh-1' }, [deletedId], [], { - runtime: createRuntime(), + runtime, getLocalProvider: () => localProvider, getSshProvider }) expect(getSshProvider).toHaveBeenCalledWith('ssh-1') + // The runtime graph holds both hosts' terminals under one id, so the sweep must fence to this one. + expect(runtime.stopTerminalsForWorktree).toHaveBeenCalledWith( + deletedId, + expect.objectContaining({ + resolvedWorktreeId: deletedId, + resolvedConnectionId: 'ssh-1' + }) + ) expect(sshProvider.shutdown).toHaveBeenCalledWith( `${deletedId}@@ssh-session`, expect.objectContaining({ immediate: true }) @@ -95,7 +104,12 @@ describe('stopMissingWorktreeTerminals', () => { ) expect(result).toEqual({ stoppedWorktreeIds: [deletedId] }) - expect(runtime.stopTerminalsForWorktree).toHaveBeenCalledWith(deletedId) + // The graph fallback still names the owning connection: this repo's inventory must not + // stop a same-id workspace's terminals on another host. + expect(runtime.stopTerminalsForWorktree).toHaveBeenCalledWith(deletedId, { + resolvedWorktreeId: deletedId, + resolvedConnectionId: 'ssh-1' + }) }) // Why: an agent cleaning up workspaces deletes many at once. Enumerating the diff --git a/src/main/runtime/missing-worktree-terminal-reconciliation.ts b/src/main/runtime/missing-worktree-terminal-reconciliation.ts index b25c4fc9f83..6c4f7f762a4 100644 --- a/src/main/runtime/missing-worktree-terminal-reconciliation.ts +++ b/src/main/runtime/missing-worktree-terminal-reconciliation.ts @@ -46,6 +46,18 @@ function withSharedProcessSnapshot(provider: IPtyProvider): IPtyProvider { }) } +// Why: `repoId::path` ids repeat across hosts, so a sweep driven by one repo's inventory +// must name its owner or it stops a same-id workspace's terminals on another host. +function hostFence( + repo: Repo, + worktreeId: string +): { resolvedWorktreeId: string; resolvedConnectionId?: string } { + return { + resolvedWorktreeId: worktreeId, + ...(repo.connectionId ? { resolvedConnectionId: repo.connectionId } : {}) + } +} + type MissingWorktreeTerminalReconciliationDeps = { runtime: OrcaRuntimeService getLocalProvider: () => IPtyProvider | null @@ -83,7 +95,7 @@ export async function stopMissingWorktreeTerminals( MISSING_WORKTREE_TEARDOWN_CONCURRENCY, async (worktreeId) => { try { - await deps.runtime.stopTerminalsForWorktree(worktreeId) + await deps.runtime.stopTerminalsForWorktree(worktreeId, hostFence(repo, worktreeId)) return worktreeId } catch { return null @@ -102,6 +114,7 @@ export async function stopMissingWorktreeTerminals( try { await killAllProcessesForWorktree(worktreeId, { runtime: deps.runtime, + ...hostFence(repo, worktreeId), localProvider: provider, onPtyStopped: deps.onPtyStopped, // Why: the shared process snapshot is only valid while nothing needs a diff --git a/src/main/runtime/network-exposure-guidance.ts b/src/main/runtime/network-exposure-guidance.ts new file mode 100644 index 00000000000..6819cda077c --- /dev/null +++ b/src/main/runtime/network-exposure-guidance.ts @@ -0,0 +1,5 @@ +// Why: shared between the runtime RPC server (createMobilePairingOffer) and the mobile IPC layer +// (getRuntimePairingUrl) so a failed pairing widen surfaces one consistent message. Kept in its own light +// module so the mobile IPC unit test can import the string without loading the full RPC/SSH module graph. +export const NETWORK_EXPOSURE_FAILED_GUIDANCE = + 'Could not expose the runtime to the network for pairing. The listener kept serving locally; retry, or choose an unused --port if the LAN bind was refused.' diff --git a/src/main/runtime/orca-runtime-files.test.ts b/src/main/runtime/orca-runtime-files.test.ts index 379372dd0ac..e1da3403d80 100644 --- a/src/main/runtime/orca-runtime-files.test.ts +++ b/src/main/runtime/orca-runtime-files.test.ts @@ -141,9 +141,11 @@ function mockLocalPathStats(entries: Record) { function createRuntimeFileCommands(options?: { path?: string + hostId?: string openFile?: ReturnType openDiff?: ReturnType resolveRuntimeFileTarget?: ReturnType + resolveKnownWorkspaceFileTarget?: ReturnType resolveRuntimeGitTarget?: ReturnType resolveTerminalCwd?: ReturnType resolveTerminalContext?: ReturnType @@ -157,7 +159,8 @@ function createRuntimeFileCommands(options?: { const worktree = { id: 'wt-1', repoId: 'repo-1', - path + path, + ...(options?.hostId ? { hostId: options.hostId } : {}) } const commands = new RuntimeFileCommands({ getRuntimeId: () => 'runtime-1', @@ -169,6 +172,9 @@ function createRuntimeFileCommands(options?: { worktree, connectionId: store.getRepo(worktree.repoId)?.connectionId })), + ...(options?.resolveKnownWorkspaceFileTarget + ? { resolveKnownWorkspaceFileTarget: options.resolveKnownWorkspaceFileTarget } + : {}), resolveTerminalCwd: options?.resolveTerminalCwd ?? vi.fn(() => path), resolveTerminalContext: options?.resolveTerminalContext ?? @@ -882,6 +888,194 @@ describe('RuntimeFileCommands', () => { }) }) + it('resolves an absolute path through a known sibling workspace', async () => { + const sibling = { + id: 'wt-2', + repoId: 'repo-2', + path: '/sibling', + git: { + path: '/sibling', + head: '', + branch: '', + isBare: false, + isMainWorktree: true + } + } + const resolveKnownWorkspaceFileTarget = vi.fn(async () => ({ + worktree: sibling, + relativePath: 'docs/readme.md' + })) + const { commands } = createRuntimeFileCommands({ + path: '/repo', + resolveKnownWorkspaceFileTarget + }) + statAsFile() + + const result = await commands.resolveTerminalPath('id:wt-1', '/sibling/docs/readme.md') + + expect(resolveKnownWorkspaceFileTarget).toHaveBeenCalledWith( + '/sibling/docs/readme.md', + 'local' + ) + expect(result).toEqual({ + worktree: 'wt-2', + relativePath: 'docs/readme.md', + absolutePath: '/sibling/docs/readme.md', + exists: true, + isDirectory: false, + openTarget: { + kind: 'worktree-file', + provider: 'local', + relativePath: 'docs/readme.md', + absolutePath: '/sibling/docs/readme.md' + } + }) + }) + + it('resolves an exact local sibling workspace root as a directory without a grant', async () => { + const sibling = { + id: 'wt-2', + repoId: 'repo-2', + path: '/sibling', + git: { + path: '/sibling', + head: '', + branch: '', + isBare: false, + isMainWorktree: true + } + } + const resolveKnownWorkspaceFileTarget = vi.fn(async () => ({ + worktree: sibling, + relativePath: '' + })) + const hasRecentTerminalOutputPath = vi.fn(() => true) + const { commands } = createRuntimeFileCommands({ + path: '/repo', + resolveKnownWorkspaceFileTarget, + hasRecentTerminalOutputPath + }) + resolveAuthorizedPathMock.mockImplementation(async (p: string) => p) + statMock.mockResolvedValue({ isDirectory: () => true }) + + const result = await resolveTerminalArtifactPath(commands, '/sibling') + + expect(resolveKnownWorkspaceFileTarget).toHaveBeenCalledWith('/sibling', 'local') + expect(result).toEqual({ + worktree: 'wt-2', + relativePath: '', + absolutePath: '/sibling', + exists: true, + isDirectory: true, + openTarget: undefined + }) + expect(hasRecentTerminalOutputPath).not.toHaveBeenCalled() + }) + + it('stats a sibling SSH workspace through its owning provider', async () => { + const sibling = { + id: 'wt-2', + repoId: 'repo-2', + path: '/sibling', + hostId: 'ssh:ssh-1', + git: { + path: '/sibling', + head: '', + branch: '', + isBare: false, + isMainWorktree: true + } + } + const resolveKnownWorkspaceFileTarget = vi.fn(async () => ({ + worktree: sibling, + connectionId: 'ssh-1', + relativePath: 'docs/readme.md' + })) + const { commands, store } = createRuntimeFileCommands({ + path: '/repo', + resolveKnownWorkspaceFileTarget + }) + store.getRepo.mockReturnValue({ connectionId: 'ssh-1' }) + const remoteStat = vi.fn().mockResolvedValue({ type: 'file', size: 12, mtime: 3 }) + vi.mocked(getSshFilesystemProvider).mockReturnValue({ stat: remoteStat } as never) + + const result = await commands.resolveTerminalPath('id:wt-1', '/sibling/docs/readme.md') + + expect(resolveKnownWorkspaceFileTarget).toHaveBeenCalledWith( + '/sibling/docs/readme.md', + 'ssh:ssh-1' + ) + expect(remoteStat).toHaveBeenCalledWith('/sibling/docs/readme.md') + expect(statMock).not.toHaveBeenCalled() + expect(result).toMatchObject({ + worktree: 'wt-2', + relativePath: 'docs/readme.md', + exists: true, + openTarget: { provider: 'ssh' } + }) + }) + + it('stats an exact SSH sibling root as a directory through its owning provider', async () => { + const sibling = { + id: 'wt-2', + repoId: 'repo-2', + path: '/sibling', + hostId: 'ssh:ssh-1', + git: { + path: '/sibling', + head: '', + branch: '', + isBare: false, + isMainWorktree: true + } + } + const resolveKnownWorkspaceFileTarget = vi.fn(async () => ({ + worktree: sibling, + connectionId: 'ssh-1', + relativePath: '' + })) + const hasRecentTerminalOutputPath = vi.fn(() => true) + const { commands, store } = createRuntimeFileCommands({ + path: '/repo', + resolveKnownWorkspaceFileTarget, + hasRecentTerminalOutputPath + }) + store.getRepo.mockReturnValue({ connectionId: 'ssh-1' }) + const remoteStat = vi.fn().mockResolvedValue({ type: 'directory', size: 0, mtime: 3 }) + vi.mocked(getSshFilesystemProvider).mockReturnValue({ stat: remoteStat } as never) + + const result = await resolveTerminalArtifactPath(commands, '/sibling') + + expect(resolveKnownWorkspaceFileTarget).toHaveBeenCalledWith('/sibling', 'ssh:ssh-1') + expect(remoteStat).toHaveBeenCalledWith('/sibling') + expect(statMock).not.toHaveBeenCalled() + expect(result).toEqual({ + worktree: 'wt-2', + relativePath: '', + absolutePath: '/sibling', + exists: true, + isDirectory: true, + openTarget: undefined + }) + expect(hasRecentTerminalOutputPath).not.toHaveBeenCalled() + }) + + it('scopes sibling lookup to the selected worktree execution host', async () => { + const resolveKnownWorkspaceFileTarget = vi.fn(async () => null) + const { commands } = createRuntimeFileCommands({ + path: '/repo-a', + hostId: 'runtime:env-a', + resolveKnownWorkspaceFileTarget + }) + + await commands.resolveTerminalPath('id:wt-1', '/repo-b/docs/readme.md') + + expect(resolveKnownWorkspaceFileTarget).toHaveBeenCalledWith( + '/repo-b/docs/readme.md', + 'runtime:env-a' + ) + }) + it('resolves a relative path against the provided cwd', async () => { const { commands } = createRuntimeFileCommands({ path: '/repo' }) statAsFile() @@ -950,14 +1144,44 @@ describe('RuntimeFileCommands', () => { expect(result).toMatchObject({ relativePath: 'docs/readme.md', exists: true }) }) - it('reports a directory', async () => { + it('reports directories including the workspace root', async () => { const { commands } = createRuntimeFileCommands({ path: '/repo' }) resolveAuthorizedPathMock.mockImplementation(async (p: string) => p) statMock.mockResolvedValue({ isDirectory: () => true }) - const result = await commands.resolveTerminalPath('id:wt-1', '/repo/src') + const nestedResult = await commands.resolveTerminalPath('id:wt-1', '/repo/src') + const rootResult = await commands.resolveTerminalPath('id:wt-1', '/repo') - expect(result).toMatchObject({ relativePath: 'src', isDirectory: true, exists: true }) + expect(nestedResult).toMatchObject({ relativePath: 'src', isDirectory: true, exists: true }) + expect(rootResult).toMatchObject({ + relativePath: '', + isDirectory: true, + exists: true, + openTarget: undefined + }) + }) + + it('keeps an exact selected nested root instead of resolving it to a parent workspace', async () => { + const resolveKnownWorkspaceFileTarget = vi.fn(async () => ({ + worktree: { id: 'wt-parent', repoId: 'repo-parent', path: '/repo' }, + relativePath: 'nested' + })) + const { commands } = createRuntimeFileCommands({ + path: '/repo/nested', + resolveKnownWorkspaceFileTarget + }) + resolveAuthorizedPathMock.mockImplementation(async (p: string) => p) + statMock.mockResolvedValue({ isDirectory: () => true }) + + const result = await commands.resolveTerminalPath('id:wt-1', '/repo/nested') + + expect(resolveKnownWorkspaceFileTarget).not.toHaveBeenCalled() + expect(result).toMatchObject({ + worktree: 'wt-1', + relativePath: '', + isDirectory: true, + openTarget: undefined + }) }) it('returns an absolute open target for an existing local temp path outside the worktree', async () => { diff --git a/src/main/runtime/orca-runtime-files.ts b/src/main/runtime/orca-runtime-files.ts index 1ea6769ff4c..08f18da2de0 100644 --- a/src/main/runtime/orca-runtime-files.ts +++ b/src/main/runtime/orca-runtime-files.ts @@ -87,7 +87,7 @@ import { } from './runtime-mobile-file-path-search' import { beginWatcherInstall } from '../ipc/watcher-removal-gate' import { assertSshMutationExpectation } from '../ssh/ssh-connection-generation' -import { toSshExecutionHostId } from '../../shared/execution-host' +import { toSshExecutionHostId, type ExecutionHostId } from '../../shared/execution-host' import { renameLocalPathSerializedByDestination } from '../destination-serialized-local-rename' const MOBILE_FILE_LIST_LIMIT = 5000 @@ -490,11 +490,24 @@ export type ResolvedRuntimeFileTarget = { connectionId?: string } +export function getRuntimeFileTargetExecutionHostId( + target: ResolvedRuntimeFileTarget +): ExecutionHostId { + return ( + target.worktree.hostId ?? + (target.connectionId ? toSshExecutionHostId(target.connectionId) : 'local') + ) +} + export type RuntimeFileCommandHost = { getRuntimeId(): string requireStore(): Store resolveWorktreeSelector(selector: string): Promise resolveRuntimeFileTarget(selector: string): Promise + resolveKnownWorkspaceFileTarget?( + absolutePath: string, + executionHostId: ExecutionHostId + ): Promise<(ResolvedRuntimeFileTarget & { relativePath: string }) | null> resolveTerminalCwd?(terminalHandle: string): string | null | Promise resolveTerminalContext?( terminalHandle: string @@ -744,15 +757,28 @@ export class RuntimeFileCommands { terminalFileUriHostname }) const relativePath = relativePathInsideRoot(worktree.path, absolutePath) + const knownWorkspaceTarget = + relativePath === null + ? await this.host.resolveKnownWorkspaceFileTarget?.( + absolutePath, + getRuntimeFileTargetExecutionHostId(target) + ) + : null + const ownedWorktree = knownWorkspaceTarget?.worktree ?? worktree + const ownedConnectionId = knownWorkspaceTarget?.connectionId ?? connectionId + const ownedRelativePath = knownWorkspaceTarget?.relativePath ?? relativePath try { - if (relativePath !== null && relativePath !== '' && isSafeMobileRelativePath(relativePath)) { - const stats = connectionId - ? await this.statRemoteTerminalPath(absolutePath, connectionId) + if ( + ownedRelativePath !== null && + (ownedRelativePath === '' || isSafeMobileRelativePath(ownedRelativePath)) + ) { + const stats = ownedConnectionId + ? await this.statRemoteTerminalPath(absolutePath, ownedConnectionId) : await stat(await resolveAuthorizedPath(absolutePath, store)) return { - worktree: worktree.id, - relativePath, + worktree: ownedWorktree.id, + relativePath: ownedRelativePath, absolutePath, exists: true, isDirectory: stats.isDirectory(), @@ -760,8 +786,8 @@ export class RuntimeFileCommands { ? undefined : { kind: 'worktree-file', - provider: connectionId ? 'ssh' : 'local', - relativePath, + provider: ownedConnectionId ? 'ssh' : 'local', + relativePath: ownedRelativePath, absolutePath } } @@ -832,9 +858,14 @@ export class RuntimeFileCommands { // Report genuine not-found as missing; let transport/permission errors surface so remote taps aren't all reported missing. if ( isENOENT(error) || - (connectionId && RuntimeFileCommands.isRemoteNotFoundErrorMessage(error)) + (ownedConnectionId && RuntimeFileCommands.isRemoteNotFoundErrorMessage(error)) ) { - return { ...empty, relativePath, absolutePath } + return { + ...empty, + worktree: ownedWorktree.id, + relativePath: ownedRelativePath, + absolutePath + } } throw error } diff --git a/src/main/runtime/orca-runtime.test.ts b/src/main/runtime/orca-runtime.test.ts index c91d324c109..722acf67937 100644 --- a/src/main/runtime/orca-runtime.test.ts +++ b/src/main/runtime/orca-runtime.test.ts @@ -51,6 +51,7 @@ import { hasHooksFile, loadHooks, parseOrcaYaml, + resolveSetupRunnerShell, runHook, shouldRunSetupForCreate } from '../hooks' @@ -466,6 +467,7 @@ vi.mock('../hooks', () => ({ ORCA_WORKTREE_PATH: worktreePath }), loadHooks: vi.fn().mockReturnValue(null), + resolveSetupRunnerShell: vi.fn().mockReturnValue(undefined), runHook: vi.fn().mockResolvedValue({ success: true, output: '' }), shouldRunSetupForCreate: vi .fn() @@ -683,6 +685,7 @@ function resetRuntimeTestMocks(): void { vi.mocked(getEffectiveHooksFromConfig).mockReset() vi.mocked(getDefaultTabsLaunch).mockReset() vi.mocked(loadHooks).mockReset() + vi.mocked(resolveSetupRunnerShell).mockReset() vi.mocked(hasHooksFile).mockReset() vi.mocked(parseOrcaYaml).mockReset() vi.mocked(runHook).mockReset() @@ -692,6 +695,7 @@ function resetRuntimeTestMocks(): void { vi.mocked(getEffectiveHooksFromConfig).mockReturnValue(null) vi.mocked(getDefaultTabsLaunch).mockReturnValue(undefined) vi.mocked(loadHooks).mockReturnValue(null) + vi.mocked(resolveSetupRunnerShell).mockReturnValue(undefined) vi.mocked(hasHooksFile).mockReturnValue(false) vi.mocked(parseOrcaYaml).mockReturnValue(null) computeWorktreePathMock.mockReset() @@ -3939,7 +3943,9 @@ describe('OrcaRuntimeService', () => { displayName: 'Folder', badgeColor: 'blue', addedAt: 1, - kind: 'folder' as const + kind: 'folder' as const, + // removeManagedWorktree executes inside this selected runtime, where PTYs are local ids. + executionHostId: 'runtime:env-1' as const } const rootWorktreeId = 'folder-repo::/workspace/folder' const rootPriorWorktreeIds = ['folder-repo::/workspace/old-folder'] @@ -5919,6 +5925,66 @@ describe('OrcaRuntimeService', () => { expect(deleteWorktreeHistoryDirMock).toHaveBeenCalledWith(`${TEST_REPO_ID}::/remote/feature`) }) + // Regression: `repoId::path` ids repeat across hosts, so the SSH delete's runtime sweep used to + // stop the same-id local workspace's terminals too. + it('leaves a same-id local terminal running when the SSH copy is removed', async () => { + const remoteRepo = { + id: TEST_REPO_ID, + path: '/remote/repo', + displayName: 'repo', + badgeColor: 'blue', + addedAt: 1, + connectionId: 'ssh-1' + } + const remoteStore = { ...store, getRepos: () => [remoteRepo], getRepo: () => remoteRepo } + const gitProvider = { + listWorktrees: vi.fn().mockResolvedValue([ + { + path: '/remote/repo', + head: 'main', + branch: 'refs/heads/main', + isBare: false, + isMainWorktree: true + }, + { + path: '/remote/feature', + head: 'abc', + branch: 'feature/foo', + isBare: false, + isMainWorktree: false + } + ]), + removeWorktree: vi.fn().mockResolvedValue(undefined) + } + registerSshGitProvider('ssh-1', gitProvider as never) + const ptyProvider = { + listProcesses: vi.fn().mockResolvedValue([]), + shutdown: vi.fn().mockResolvedValue(undefined) + } + const runtime = new OrcaRuntimeService(remoteStore as never, undefined, { + getSshProvider: () => ptyProvider as never + }) + const stopAndWait = vi.fn(async () => true) + runtime.setPtyController({ + write: () => true, + kill: vi.fn(() => true), + stopAndWait, + getForegroundProcess: async () => null + }) + syncSinglePty(runtime, null) + runtime.registerPty('pty-remote', `${TEST_REPO_ID}::/remote/feature`, 'ssh-1') + runtime.registerPty('pty-local-same-id', `${TEST_REPO_ID}::/remote/feature`, null) + + try { + await runtime.removeManagedWorktree('path:/remote/feature', true, false) + } finally { + unregisterSshGitProvider('ssh-1') + } + + expect(stopAndWait).toHaveBeenCalledWith('pty-remote', expect.anything()) + expect(stopAndWait).not.toHaveBeenCalledWith('pty-local-same-id', expect.anything()) + }) + it('rejects SSH-backed runtime removal of the main worktree before provider deletion', async () => { const remoteStore = { ...store, @@ -10845,6 +10911,62 @@ describe('OrcaRuntimeService', () => { }) }) + it('does not treat a restored-unconfirmed hook row as live terminal status', async () => { + const leafId = '11111111-1111-4111-8111-111111111111' + const paneKey = makePaneKey('tab-1', leafId) + const runtime = new OrcaRuntimeService(store, undefined, { + getAgentStatusSnapshot: () => [ + { + paneKey, + state: 'waiting', + prompt: '', + agentType: 'codex', + connectionId: null, + receivedAt: Date.now(), + stateStartedAt: Date.now(), + tabId: 'tab-1', + worktreeId: TEST_WORKTREE_ID, + restoredUnconfirmed: true + } + ] + }) + runtime.setPtyController({ + spawn: vi.fn().mockResolvedValue({ id: 'pty-1' }), + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { + tabs: [ + { + tabId: 'tab-1', + worktreeId: TEST_WORKTREE_ID, + title: 'repo terminal', + activeLeafId: leafId, + layout: null + } + ], + leaves: [ + { + tabId: 'tab-1', + worktreeId: TEST_WORKTREE_ID, + leafId, + paneRuntimeId: 1, + ptyId: 'pty-1' + } + ] + }) + + const [terminal] = (await runtime.listTerminals()).terminals + + await expect(runtime.getTerminalAgentStatus(terminal.handle)).resolves.toEqual({ + handle: terminal.handle, + isRunningAgent: false, + status: null + }) + }) + it('does not let stale wait text override a fresh explicit working state', async () => { const leafId = '11111111-1111-4111-8111-111111111111' const paneKey = makePaneKey('tab-1', leafId) @@ -12550,6 +12672,253 @@ describe('OrcaRuntimeService', () => { ) }) + // Why: `cursor` on PATH is the Cursor desktop launcher; only `cursor-agent` is + // the CLI Orca can host (issue #11926). + it('launches the configured agent CLI for a startupAgent id, not the raw id', async () => { + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtimeStore = { + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {}, + agentDefaultArgs: { cursor: '--force' }, + agentDefaultEnv: { cursor: { CURSOR_PROFILE: 'captured' } } + }) + } + const runtime = new OrcaRuntimeService(runtimeStore) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + startupAgent: 'cursor', + title: 'worker' + }) + + const spawnCall = spawn.mock.calls[0]?.[0] as + | { command?: string; launchAgent?: string; env?: Record } + | undefined + expect(spawnCall?.command).toBe("cursor-agent '--force'") + expect(spawnCall?.launchAgent).toBe('cursor') + expect(spawnCall?.env).toMatchObject({ CURSOR_PROFILE: 'captured' }) + expect(markCursorWorkspaceTrustedMock).toHaveBeenCalledWith(TEST_WORKTREE_PATH) + }) + + it('resolves a startupAgent to the CLI binary on Windows, where `cursor` is the IDE', async () => { + setPlatform('win32') + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtimeStore = { + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + terminalWindowsShell: 'cmd.exe', + agentCmdOverrides: {}, + // Why: pin the arg here rather than inherit the shared yolo default, so + // this test tracks Windows quoting and not an unrelated default's value. + agentDefaultArgs: { cursor: '--force' }, + agentDefaultEnv: {} + }) + } + const runtime = new OrcaRuntimeService(runtimeStore) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { startupAgent: 'cursor' }) + + const spawnCall = spawn.mock.calls[0]?.[0] as { command?: string } | undefined + // Why: assert the cmd.exe double quoting too — a platform-insensitive prefix + // match would pass on any OS and prove nothing about the reported platform. + expect(spawnCall?.command).toBe('cursor-agent "--force"') + }) + + // Why: claude-agent-teams is the only agent whose launcher name varies by + // platform (launchCmdByPlatform), so it is what proves resolution is + // platform-aware rather than a fixed string. + it.each([ + { platform: 'win32' as const, expected: 'orca.cmd claude-teams' }, + { platform: 'linux' as const, expected: 'orca-ide claude-teams' }, + { platform: 'darwin' as const, expected: 'orca claude-teams' } + ])( + 'resolves a startupAgent through the $platform launcher name', + async ({ platform, expected }) => { + setPlatform(platform) + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {}, + agentDefaultArgs: { 'claude-agent-teams': '' }, + agentDefaultEnv: {} + }) + }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + startupAgent: 'claude-agent-teams' + }) + + const spawnCall = spawn.mock.calls[0]?.[0] as { command?: string } | undefined + expect(spawnCall?.command).toBe(expected) + } + ) + + // Why: a user who worked around this bug by pointing the override at their own + // cursor-agent path must keep that override once the id resolves properly. + it('honors an agentCmdOverrides entry for a startupAgent', async () => { + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: { cursor: 'cursor-agent --beta' }, + agentDefaultArgs: { cursor: '--force' }, + agentDefaultEnv: {} + }) + }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { startupAgent: 'cursor' }) + + const spawnCall = spawn.mock.calls[0]?.[0] as { command?: string } | undefined + expect(spawnCall?.command).toBe("cursor-agent --beta '--force'") + }) + + // Why: with no selector the launch is never resolved, so a dropped startupAgent + // would reach the renderer as a bare shell — the failure this option prevents. + it('rejects a startupAgent create with no workspace selector', async () => { + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {} + }) + }) + + await expect( + runtime.createTerminal(undefined, { startupAgent: 'cursor', rendererBacked: true }) + ).rejects.toThrow(/requires a workspace selector/) + }) + + // Why: folder workspaces have no repo, so command sniffing skipped them entirely + // and spawned the bare string; an explicit agent must still resolve. + it('resolves a startupAgent in a repo-less folder workspace', async () => { + const folderPath = await mkdtemp(join(tmpdir(), 'orca-runtime-folder-startup-agent-')) + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const folderWorkspace = makeFolderWorkspace({ folderPath }) + const projectGroup = makeFolderProjectGroup({ parentPath: folderPath }) + const runtime = new OrcaRuntimeService({ + ...createFolderWorkspaceRuntimeStore(folderWorkspace, projectGroup), + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {}, + agentDefaultArgs: { cursor: '--force' }, + agentDefaultEnv: {} + }) + } as never) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`id:${TEST_FOLDER_WORKSPACE_KEY}`, { startupAgent: 'cursor' }) + + const spawnCall = spawn.mock.calls[0]?.[0] as + | { command?: string; launchAgent?: string } + | undefined + expect(spawnCall?.command).toBe("cursor-agent '--force'") + expect(spawnCall?.launchAgent).toBe('cursor') + }) + + // Why: silently returning the caller's opts would spawn a bare shell that can + // only time out at agent readiness — the failure startupAgent exists to stop. + it('rejects a startupAgent create that also supplies its own launch', async () => { + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {} + }) + }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + for (const conflicting of [ + { env: { SOME_VAR: 'set' } }, + // Why: a raw command would be silently overwritten by the built launch. + { command: 'cursor-agent --resume' }, + // Why: resume identity paired with a freshly built launch is incoherent. + { resumeProviderSession: { key: 'session_id', id: 'prior-session' } as never }, + { launchAgent: 'cursor' as const }, + { launchConfig: { agentArgs: '', agentEnv: {} } as never }, + { startupCommandDelivery: 'provider' as never }, + { claudeAgentTeamsSourceCommand: 'claude' } + ]) { + await expect( + runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + startupAgent: 'cursor', + ...conflicting + }) + ).rejects.toThrow(/cannot combine/) + } + expect(spawn).not.toHaveBeenCalled() + }) + + it('rejects a startupAgent create for a disabled agent', async () => { + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtimeStore = { + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: ['cursor' as const], + agentCmdOverrides: {} + }) + } + const runtime = new OrcaRuntimeService(runtimeStore) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await expect( + runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { startupAgent: 'cursor' }) + ).rejects.toThrow(/disabled/) + expect(spawn).not.toHaveBeenCalled() + }) + it('quotes local Windows bare agent command defaults for cmd.exe terminal creates', async () => { setPlatform('win32') const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) @@ -15185,6 +15554,257 @@ describe('OrcaRuntimeService', () => { }) }) + it('coalesces concurrent focusTerminal navigations so only the latest full reveal runs', async () => { + // Instant reveals during createTerminal; switch to gated mock before focus storm. + const revealTerminalSession = vi.fn().mockResolvedValue({ tabId: 'tab-create' }) + const runtime = new OrcaRuntimeService(store) + runtime.setPtyController({ + spawn: vi + .fn() + .mockResolvedValueOnce({ id: 'pty-a' }) + .mockResolvedValueOnce({ id: 'pty-b' }) + .mockResolvedValueOnce({ id: 'pty-c' }), + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree: vi.fn(), + createTerminal: vi.fn(), + revealTerminalSession, + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { tabs: [], leaves: [] }) + const a = await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + title: 'a', + presentation: 'background' + }) + const b = await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + title: 'b', + presentation: 'background' + }) + const c = await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { + title: 'c', + presentation: 'background' + }) + + let releaseFirstReveal!: (value: { tabId: string }) => void + let firstRevealStarted = false + const firstRevealGate = new Promise<{ tabId: string }>((resolve) => { + releaseFirstReveal = resolve + }) + revealTerminalSession.mockReset() + revealTerminalSession.mockImplementation(() => { + if (!firstRevealStarted) { + firstRevealStarted = true + return firstRevealGate + } + return Promise.resolve({ tabId: 'tab-latest' }) + }) + + const pA = runtime.focusTerminal(a.handle) + await vi.waitFor(() => { + expect(firstRevealStarted).toBe(true) + }) + const pB = runtime.focusTerminal(b.handle) + const pC = runtime.focusTerminal(c.handle) + + // B is superseded while A is in flight — identity only, never navigated. + await expect(pB).resolves.toMatchObject({ + handle: b.handle, + navigated: false + }) + releaseFirstReveal({ tabId: 'tab-a' }) + // A may still complete reveal work, but if C superseded it, navigated is false. + const aResult = await pA + expect(aResult.handle).toBe(a.handle) + expect(aResult.navigated).toBe(false) + await expect(pC).resolves.toMatchObject({ + handle: c.handle, + tabId: 'tab-latest', + navigated: true + }) + + // B must never have started a reveal; only A and/or C. + const revealedPtyIds = revealTerminalSession.mock.calls.map( + (call) => (call[1] as { ptyId?: string }).ptyId + ) + expect(revealedPtyIds).not.toContain('pty-b') + expect(revealedPtyIds.at(-1)).toBe('pty-c') + }) + + it('reports a queued PTY focus as not navigated when its notifier disappears', async () => { + const runtime = new OrcaRuntimeService(store) + runtime.setPtyController({ + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.registerPty('pty-a', TEST_WORKTREE_ID) + runtime.registerPty('pty-b', TEST_WORKTREE_ID) + const terminals = (await runtime.listTerminals()).terminals + const terminalA = terminals.find((terminal) => terminal.ptyId === 'pty-a') + const terminalB = terminals.find((terminal) => terminal.ptyId === 'pty-b') + expect(terminalA).toBeDefined() + expect(terminalB).toBeDefined() + + let releaseReveal!: (value: { tabId: string }) => void + const revealGate = new Promise<{ tabId: string }>((resolve) => { + releaseReveal = resolve + }) + const revealTerminalSession = vi + .fn() + .mockImplementationOnce(() => revealGate) + .mockResolvedValue({ tabId: 'tab-b' }) + runtime.setNotifier({ revealTerminalSession } as never) + + const first = runtime.focusTerminal(terminalA!.handle) + await vi.waitFor(() => expect(revealTerminalSession).toHaveBeenCalledOnce()) + const queued = runtime.focusTerminal(terminalB!.handle) + runtime.setNotifier(null) + releaseReveal({ tabId: 'tab-a' }) + + await expect(first).resolves.toMatchObject({ handle: terminalA!.handle, navigated: false }) + await expect(queued).resolves.toMatchObject({ handle: terminalB!.handle, navigated: false }) + expect(revealTerminalSession).toHaveBeenCalledOnce() + }) + + it('reports an in-flight PTY focus as not navigated when its notifier disappears', async () => { + const runtime = new OrcaRuntimeService(store) + runtime.setPtyController({ + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.registerPty('pty-a', TEST_WORKTREE_ID) + const terminal = (await runtime.listTerminals()).terminals.find( + (candidate) => candidate.ptyId === 'pty-a' + ) + expect(terminal).toBeDefined() + + let releaseReveal!: (value: { tabId: string }) => void + const revealTerminalSession = vi.fn( + () => + new Promise<{ tabId: string }>((resolve) => { + releaseReveal = resolve + }) + ) + runtime.setNotifier({ revealTerminalSession } as never) + + const focus = runtime.focusTerminal(terminal!.handle) + await vi.waitFor(() => expect(revealTerminalSession).toHaveBeenCalledOnce()) + runtime.setNotifier(null) + releaseReveal({ tabId: 'tab-a' }) + + await expect(focus).resolves.toMatchObject({ + handle: terminal!.handle, + tabId: 'tab-a', + navigated: false + }) + }) + + it('does not invoke a stale graph-leaf focus notifier after queued PTY work', async () => { + const runtime = new OrcaRuntimeService(store) + runtime.setPtyController({ + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { + tabs: [ + { + tabId: 'tab-leaf', + worktreeId: TEST_WORKTREE_ID, + title: 'Starting terminal', + activeLeafId: HEADLESS_LEAF_ID, + layout: null + } + ], + leaves: [ + { + tabId: 'tab-leaf', + worktreeId: TEST_WORKTREE_ID, + leafId: HEADLESS_LEAF_ID, + paneRuntimeId: 1, + ptyId: null + } + ] + }) + const leafTerminal = (await runtime.listTerminals()).terminals.find( + (terminal) => terminal.tabId === 'tab-leaf' + ) + runtime.registerPty('pty-a', TEST_WORKTREE_ID) + const ptyTerminal = (await runtime.listTerminals()).terminals.find( + (terminal) => terminal.ptyId === 'pty-a' + ) + expect(ptyTerminal).toBeDefined() + expect(leafTerminal).toBeDefined() + + let releaseReveal!: (value: { tabId: string }) => void + const revealGate = new Promise<{ tabId: string }>((resolve) => { + releaseReveal = resolve + }) + const focusTerminal = vi.fn() + const revealTerminalSession = vi.fn(() => revealGate) + runtime.setNotifier({ + revealTerminalSession, + focusTerminal + } as never) + + const first = runtime.focusTerminal(ptyTerminal!.handle) + await vi.waitFor(() => expect(revealTerminalSession).toHaveBeenCalledOnce()) + const queued = runtime.focusTerminal(leafTerminal!.handle) + runtime.setNotifier(null) + releaseReveal({ tabId: 'tab-a' }) + + await expect(first).resolves.toMatchObject({ handle: ptyTerminal!.handle, navigated: false }) + await expect(queued).resolves.toMatchObject({ handle: leafTerminal!.handle, navigated: false }) + expect(focusTerminal).not.toHaveBeenCalled() + }) + + it('reports graph-leaf focus as not navigated without a host notifier', async () => { + const runtime = new OrcaRuntimeService(store) + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { + tabs: [ + { + tabId: 'tab-leaf', + worktreeId: TEST_WORKTREE_ID, + title: 'Starting terminal', + activeLeafId: HEADLESS_LEAF_ID, + layout: null + } + ], + leaves: [ + { + tabId: 'tab-leaf', + worktreeId: TEST_WORKTREE_ID, + leafId: HEADLESS_LEAF_ID, + paneRuntimeId: 1, + ptyId: null + } + ] + }) + const [terminal] = (await runtime.listTerminals()).terminals + + await expect(runtime.focusTerminal(terminal.handle)).resolves.toEqual({ + handle: terminal.handle, + tabId: 'tab-leaf', + worktreeId: TEST_WORKTREE_ID, + navigated: false + }) + }) + it('clears terminal scrollback through the PTY controller and headless buffer', async () => { const clearBuffer = vi.fn().mockResolvedValue(undefined) const runtime = new OrcaRuntimeService(store) @@ -22562,6 +23182,109 @@ describe('OrcaRuntimeService', () => { expect(result.tabs[0]).not.toHaveProperty('launchAgent') }) + it('preserves host metadata when terminal.create adopts a stable pane owner', async () => { + const adoptStablePane = vi.fn().mockResolvedValue(null) + const spawn = vi.fn(async (opts: { adoptedStablePane?: { owner: { handle?: string } } }) => + opts.adoptedStablePane + ? { + id: 'pty-stable-owner', + isReattach: true, + stablePaneOwner: { + handle: opts.adoptedStablePane.owner.handle!, + tabId: 'stable-owner-tab', + leafId: HEADLESS_LEAF_ID + } + } + : { id: 'pty-stable-owner' } + ) + const runtimeStore = { + ...store, + getSettings: () => ({ + ...store.getSettings(), + claudeAgentTeamsMode: 'in-process' as const + }) + } + const runtime = new OrcaRuntimeService(runtimeStore) + runtime.setPtyController({ + adoptStablePane, + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + const first = await runtime.createTerminal(`id:${TEST_WORKTREE_ID}`, { + tabId: 'stable-owner-tab', + leafId: HEADLESS_LEAF_ID, + title: 'Original owner', + launchAgent: 'claude' + }) + adoptStablePane.mockResolvedValueOnce({ + result: { id: 'pty-stable-owner', isReattach: true }, + owner: { + handle: first.handle, + tabId: 'stable-owner-tab', + leafId: HEADLESS_LEAF_ID, + ptyId: 'pty-stable-owner' + } + }) + + const adopted = await runtime.createTerminal(`id:${TEST_WORKTREE_ID}`, { + tabId: 'stable-owner-tab', + leafId: HEADLESS_LEAF_ID, + title: 'Replacement intent', + command: "claude 'replacement'", + launchAgent: 'claude' + }) + const listed = await runtime.listMobileSessionTabs(`id:${TEST_WORKTREE_ID}`) + + expect(adopted).toMatchObject({ + handle: first.handle, + ptyId: 'pty-stable-owner', + title: 'Original owner', + isReattach: true + }) + expect(listed.tabs).toEqual([ + expect.objectContaining({ + parentTabId: 'stable-owner-tab', + title: 'Original owner', + launchAgent: 'claude' + }) + ]) + expect(spawn.mock.calls[1]?.[0]).toMatchObject({ + command: "claude 'replacement'", + adoptedStablePane: expect.anything() + }) + expect(spawn.mock.calls[1]?.[0]).not.toMatchObject({ + command: expect.stringContaining('--teammate-mode') + }) + }) + + it('releases a stable-pane claim when creation aborts before provider spawn', async () => { + const releaseClaim = vi.fn() + const spawn = vi.fn() + const runtime = new OrcaRuntimeService(store) + runtime.setPtyController({ + claimStablePaneCreate: vi.fn(() => releaseClaim), + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + const abort = new AbortController() + abort.abort() + + await expect( + runtime.createTerminal(`id:${TEST_WORKTREE_ID}`, { + tabId: 'aborted-stable-pane', + leafId: HEADLESS_LEAF_ID, + signal: abort.signal + }) + ).rejects.toThrow('client_disconnected') + + expect(spawn).not.toHaveBeenCalled() + expect(releaseClaim).toHaveBeenCalledOnce() + }) + it('publishes the hook provider session on a headless mobile tab so native chat can address the transcript', async () => { const paneKey = makePaneKey('claude-tab', HEADLESS_LEAF_ID) const providerSession = { @@ -24529,6 +25252,7 @@ describe('OrcaRuntimeService', () => { persistHostSessionBinding: true }) ) + expect(spawn.mock.calls[0]?.[0]).not.toHaveProperty('isNewSession') expect(activated.tabs).toEqual([ expect.objectContaining({ id: `host-tab::${HEADLESS_LEAF_ID}`, @@ -24599,6 +25323,7 @@ describe('OrcaRuntimeService', () => { tabId: 'host-tab', leafId: HEADLESS_LEAF_ID, sessionId: expect.stringMatching(/^serve-/), + isNewSession: true, persistHostSessionBinding: true }) ) @@ -26042,7 +26767,8 @@ describe('OrcaRuntimeService', () => { await expect(runtime.focusTerminal(laptopTerminal.handle)).resolves.toEqual({ handle: laptopTerminal.handle, tabId: 'laptop-tab', - worktreeId: TEST_WORKTREE_ID + worktreeId: TEST_WORKTREE_ID, + navigated: false }) await expect(runtime.closeTerminal(laptopTerminal.handle)).resolves.toEqual({ handle: laptopTerminal.handle, @@ -30953,6 +31679,125 @@ describe('OrcaRuntimeService', () => { } }) + it('delivers the agent launch command when a create settles over a bare renderer PTY', async () => { + vi.useFakeTimers() + try { + const leafId = '77777777-7777-4777-8777-777777777777' + const write = vi.fn((_ptyId: string, _data: string) => true) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {} + }) + } as never) + runtime.setPtyController({ + spawn: vi.fn(), + write, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier(createMobileCreateTestNotifier(vi.fn())) + const webContents = { send: vi.fn() } + const send = vi.fn((_channel: string, payload: { requestId: string }) => { + // Why: the pane spawned before its startup queue landed (the #7587 + // renderer-stall class), so no spawn command is recorded for the PTY. + runtime.registerPty('pty-bare', TEST_WORKTREE_ID, null, { tabId: 'tab-bare', leafId }) + ipcMain.emit( + 'terminal:tabCreateReply', + { sender: webContents }, + { requestId: payload.requestId, tabId: 'tab-bare', title: 'Terminal' } + ) + }) + webContents.send = send + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { tabs: [], leaves: [] }) + electronMocks.BrowserWindow.fromId.mockReturnValue({ + isDestroyed: () => false, + webContents + }) + + const create = runtime.createMobileSessionTerminal(`id:${TEST_WORKTREE_ID}`, { + agent: 'codex', + activate: true + }) + await vi.waitFor(() => expect(send).toHaveBeenCalledTimes(1)) + await vi.advanceTimersByTimeAsync(50) + const result = await create + + expect(result.tab).toMatchObject({ + type: 'terminal', + parentTabId: 'tab-bare', + leafId, + status: 'ready' + }) + // Why: the adopted PTY never launched codex, so the settle must type the + // launch command (Enter as its own write) instead of succeeding silently. + expect(write).toHaveBeenCalledTimes(2) + expect(write.mock.calls[0][0]).toBe('pty-bare') + expect(String(write.mock.calls[0][1])).toMatch(/codex/) + expect(write.mock.calls[1]).toEqual(['pty-bare', '\r']) + } finally { + vi.useRealTimers() + } + }) + + it('does not re-deliver the agent launch command when the adopted renderer PTY spawned with one', async () => { + vi.useFakeTimers() + try { + const leafId = '88888888-8888-4888-8888-888888888888' + const write = vi.fn((_ptyId: string, _data: string) => true) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: {} + }) + } as never) + runtime.setPtyController({ + spawn: vi.fn(), + write, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier(createMobileCreateTestNotifier(vi.fn())) + const webContents = { send: vi.fn() } + const send = vi.fn((_channel: string, payload: { requestId: string }) => { + // Why: mirrors the spawn IPC handler — a command-carrying spawn records + // its launch command right after registering the PTY. + runtime.registerPty('pty-carried', TEST_WORKTREE_ID, null, { tabId: 'tab-carried', leafId }) + runtime.noteTerminalSpawnCommand('pty-carried', 'codex') + ipcMain.emit( + 'terminal:tabCreateReply', + { sender: webContents }, + { requestId: payload.requestId, tabId: 'tab-carried', title: 'Terminal' } + ) + }) + webContents.send = send + runtime.attachWindow(1) + runtime.syncWindowGraph(1, { tabs: [], leaves: [] }) + electronMocks.BrowserWindow.fromId.mockReturnValue({ + isDestroyed: () => false, + webContents + }) + + const create = runtime.createMobileSessionTerminal(`id:${TEST_WORKTREE_ID}`, { + agent: 'codex', + activate: true + }) + await vi.waitFor(() => expect(send).toHaveBeenCalledTimes(1)) + await vi.advanceTimersByTimeAsync(50) + const result = await create + + expect(result.tab).toMatchObject({ type: 'terminal', parentTabId: 'tab-carried' }) + expect(write).not.toHaveBeenCalled() + } finally { + vi.useRealTimers() + } + }) + it('keeps a mobile-created terminal alive when the renderer snapshot is rejected by the version guard', async () => { vi.useFakeTimers() try { @@ -33712,6 +34557,31 @@ describe('OrcaRuntimeService', () => { expect(kill).not.toHaveBeenCalled() }) + it('stops only the owning connection when one worktree id lives on two hosts', async () => { + const runtime = new OrcaRuntimeService(store) + const kill = vi.fn(() => true) + runtime.setPtyController({ + write: () => true, + kill, + stopAndWait: vi.fn(async () => true), + getForegroundProcess: async () => null + }) + syncSinglePty(runtime, null) + // The store keeps one `repoId::path` per host, so deleting the SSH copy must leave the + // local copy's terminals running — the fence the destructive removal paths now supply. + runtime.registerPty('pty-ssh', TEST_WORKTREE_ID, 'ssh-1') + runtime.registerPty('pty-local', TEST_WORKTREE_ID, null) + + await expect( + runtime.stopTerminalsForWorktree(TEST_WORKTREE_ID, { + resolvedWorktreeId: TEST_WORKTREE_ID, + resolvedConnectionId: 'ssh-1' + }) + ).resolves.toEqual({ stopped: 1 }) + expect(kill).toHaveBeenCalledWith('pty-ssh') + expect(kill).not.toHaveBeenCalledWith('pty-local') + }) + it('awaits physical PTY stop when destructive teardown supplies shared dedupe', async () => { const runtime = new OrcaRuntimeService(store) const physicalStop = makeDeferred() @@ -37074,6 +37944,7 @@ describe('OrcaRuntimeService', () => { handle === workerHandle ? { id: 'ctx-1', + run_id: 'run-1', task_id: 'task-1', assignee_handle: workerHandle, status: 'dispatched' @@ -37084,6 +37955,7 @@ describe('OrcaRuntimeService', () => { handle === workerHandle ? { id: 'ctx-done', + run_id: 'run-1', task_id: 'task-done', assignee_handle: workerHandle, status: 'completed', @@ -37093,14 +37965,16 @@ describe('OrcaRuntimeService', () => { ), getTask: vi.fn(() => ({ id: 'task-1', + run_id: 'run-1', task_title: 'Dispatch prompt work', display_name: 'Review dispatch prompts and make worker labels distinct', spec: 'Review dispatch prompts\n\nand make worker labels distinct', created_by_terminal_handle: coordinatorHandle })), - getActiveCoordinatorRun: vi.fn(() => ({ + getRun: vi.fn(() => ({ id: 'run-1', - coordinator_handle: coordinatorHandle + coordinator_handle: coordinatorHandle, + legacy: 0 })) } as never) runtime.attachWindow(1) @@ -37155,6 +38029,513 @@ describe('OrcaRuntimeService', () => { }) }) + it.each([ + ['fails closed when a modern dispatch owning Run is missing', 'run-missing', 'run-missing'], + ['fails closed when Task and Dispatch Runs disagree', 'run-dispatch', 'run-task'] + ])('%s', (_name, dispatchRunId, taskRunId) => { + const runtime = new OrcaRuntimeService(store) + const workerLeafId = '77777777-7777-4777-8777-777777777777' + const coordinatorLeafId = '88888888-8888-4888-8888-888888888888' + const workerPaneKey = makePaneKey('tab-worker', workerLeafId) + const workerHandle = runtime.preAllocateHandleForPty('pty-worker') + const coordinatorHandle = runtime.preAllocateHandleForPty('pty-coordinator') + const getActiveCoordinatorRun = vi.fn(() => ({ + id: 'run-legacy-unrelated', + coordinator_handle: coordinatorHandle + })) + runtime.setOrchestrationDb({ + getActiveDispatchForTerminal: vi.fn((handle: string) => + handle === workerHandle + ? { + id: 'ctx-missing-run', + run_id: dispatchRunId, + task_id: 'task-missing-run', + assignee_handle: workerHandle, + status: 'dispatched' + } + : undefined + ), + getLatestDispatchForTerminal: vi.fn(() => undefined), + getTask: vi.fn(() => ({ + id: 'task-missing-run', + run_id: taskRunId, + spec: 'modern task without proven Run', + created_by_terminal_handle: coordinatorHandle + })), + getRun: vi.fn(() => undefined), + getActiveCoordinatorRun + } as never) + runtime.attachWindow(1) + + const result = runtime.syncWindowGraph(1, { + tabs: [ + { + tabId: 'tab-worker', + worktreeId: TEST_WORKTREE_ID, + title: 'Worker', + activeLeafId: workerLeafId, + layout: null + }, + { + tabId: 'tab-coordinator', + worktreeId: TEST_WORKTREE_ID, + title: 'Coordinator', + activeLeafId: coordinatorLeafId, + layout: null + } + ], + leaves: [ + { + tabId: 'tab-worker', + worktreeId: TEST_WORKTREE_ID, + leafId: workerLeafId, + paneRuntimeId: 1, + ptyId: 'pty-worker', + paneTitle: null + }, + { + tabId: 'tab-coordinator', + worktreeId: TEST_WORKTREE_ID, + leafId: coordinatorLeafId, + paneRuntimeId: 2, + ptyId: 'pty-coordinator', + paneTitle: null + } + ] + }) + + expect(result.agentOrchestrationByPaneKey?.[workerPaneKey]).toEqual({ + taskId: 'task-missing-run', + dispatchId: 'ctx-missing-run', + dispatchStatus: 'dispatched', + taskTitle: 'modern task without proven Run', + displayName: 'modern task without proven Run' + }) + expect(getActiveCoordinatorRun).not.toHaveBeenCalled() + }) + + it('uses durable Run ownership before worktree-scoped legacy attribution', () => { + const childWorktreeId = `${TEST_REPO_ID}::${join(tmpdir(), 'workspaces', 'run-a-worker')}` + const folderWorktreeId = `${TEST_REPO_ID}::${join(tmpdir(), 'folder')}${FOLDER_WORKSPACE_INSTANCE_SEPARATOR}11111111-1111-4111-8111-111111111111` + const meta = store.getAllWorktreeMeta()[TEST_WORKTREE_ID] + const metaById = { + ...store.getAllWorktreeMeta(), + [childWorktreeId]: meta, + [folderWorktreeId]: meta + } + const runtime = new OrcaRuntimeService({ + ...store, + getAllWorktreeMeta: () => metaById, + getWorktreeMeta: (worktreeId: string) => metaById[worktreeId] + } as never) + const terminals = [ + { + name: 'coordinator-a', + worktreeId: TEST_WORKTREE_ID, + leafId: '11111111-1111-4111-8111-111111111111' + }, + { + name: 'coordinator-b', + worktreeId: TEST_WORKTREE_ID, + leafId: '22222222-2222-4222-8222-222222222222' + }, + { + name: 'worker-cross-worktree', + worktreeId: childWorktreeId, + leafId: '33333333-3333-4333-8333-333333333333' + }, + { + name: 'worker-same-worktree', + worktreeId: TEST_WORKTREE_ID, + leafId: '44444444-4444-4444-8444-444444444444' + }, + { + name: 'worker-folder', + worktreeId: folderWorktreeId, + leafId: '55555555-5555-4555-8555-555555555555' + }, + { + name: 'legacy-worker', + worktreeId: childWorktreeId, + leafId: '66666666-6666-4666-8666-666666666666' + } + ].map((terminal, index) => ({ + ...terminal, + tabId: `tab-${terminal.name}`, + ptyId: `pty-${terminal.name}`, + paneRuntimeId: index + 1 + })) + const terminalByName = Object.fromEntries( + terminals.map((terminal) => [terminal.name, terminal]) + ) + const handles = Object.fromEntries( + terminals.map((terminal) => [terminal.name, runtime.preAllocateHandleForPty(terminal.ptyId)]) + ) + const paneKey = (name: string): string => { + const terminal = terminalByName[name] + return makePaneKey(terminal.tabId, terminal.leafId) + } + const db = new OrchestrationDb(':memory:') + try { + const runA = db.createRun({ + objective: 'coordinate run A', + coordinatorHandle: handles['coordinator-a'], + coordinatorPaneKey: paneKey('coordinator-a') + }) + const runB = db.createRun({ + objective: 'coordinate run B', + coordinatorHandle: handles['coordinator-b'], + coordinatorPaneKey: paneKey('coordinator-b') + }) + const dispatches = Object.fromEntries( + [ + ['worker-cross-worktree', runA.id], + ['worker-same-worktree', runA.id], + ['worker-folder', runB.id] + ].map(([name, runId]) => { + const task = db.createTask({ spec: name, runId }) + return [name, db.createDispatchContext(task.id, handles[name], paneKey(name))] + }) + ) + const legacyTask = db.createTask({ spec: 'legacy worker' }) + const legacyDispatch = db.createDispatchContext( + legacyTask.id, + handles['legacy-worker'], + paneKey('legacy-worker') + ) + db.createCoordinatorRun({ + spec: 'unrelated legacy coordinator', + coordinatorHandle: handles['coordinator-b'] + }) + const getActiveCoordinatorRun = vi.spyOn(db, 'getActiveCoordinatorRun') + runtime.setOrchestrationDb(db) + runtime.attachWindow(1) + + const result = runtime.syncWindowGraph(1, { + tabs: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: terminal.worktreeId, + title: terminal.name, + activeLeafId: terminal.leafId, + layout: null + })), + leaves: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: terminal.worktreeId, + leafId: terminal.leafId, + paneRuntimeId: terminal.paneRuntimeId, + ptyId: terminal.ptyId, + paneTitle: null + })) + }) + + for (const [name, run, coordinator] of [ + ['worker-cross-worktree', runA, 'coordinator-a'], + ['worker-same-worktree', runA, 'coordinator-a'], + ['worker-folder', runB, 'coordinator-b'] + ] as const) { + expect(result.agentOrchestrationByPaneKey?.[paneKey(name)]).toMatchObject({ + taskId: dispatches[name].task_id, + dispatchId: dispatches[name].id, + dispatchStatus: 'dispatched', + parentTerminalHandle: handles[coordinator], + parentPaneKey: paneKey(coordinator), + coordinatorHandle: handles[coordinator], + orchestrationRunId: run.id + }) + } + const legacyContext = result.agentOrchestrationByPaneKey?.[paneKey('legacy-worker')] + expect(legacyContext).toMatchObject({ + taskId: legacyTask.id, + dispatchId: legacyDispatch.id, + dispatchStatus: 'dispatched' + }) + expect(legacyContext).not.toHaveProperty('parentTerminalHandle') + expect(legacyContext).not.toHaveProperty('coordinatorHandle') + expect(legacyContext).not.toHaveProperty('orchestrationRunId') + expect(getActiveCoordinatorRun).toHaveBeenCalledOnce() + } finally { + db.close() + } + }) + + it('uses the still-bound owning Run coordinator after a creator pane rebinds', () => { + const runtime = new OrcaRuntimeService(store) + const terminals = [ + { + name: 'coordinator', + leafId: '11111111-1111-4111-8111-111111111111' + }, + { + name: 'creator', + leafId: '22222222-2222-4222-8222-222222222222' + }, + { + name: 'worker', + leafId: '33333333-3333-4333-8333-333333333333' + }, + { + name: 'coordinator-created-worker', + leafId: '44444444-4444-4444-8444-444444444444' + } + ].map((terminal, index) => ({ + ...terminal, + tabId: `tab-${terminal.name}`, + ptyId: `pty-${terminal.name}`, + paneRuntimeId: index + 1 + })) + const terminalByName = Object.fromEntries( + terminals.map((terminal) => [terminal.name, terminal]) + ) + const handles = Object.fromEntries( + terminals.map((terminal) => [terminal.name, runtime.preAllocateHandleForPty(terminal.ptyId)]) + ) + const paneKey = (name: string): string => { + const terminal = terminalByName[name] + return makePaneKey(terminal.tabId, terminal.leafId) + } + const graph = () => ({ + tabs: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: TEST_WORKTREE_ID, + title: terminal.name, + activeLeafId: terminal.leafId, + layout: null + })), + leaves: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: TEST_WORKTREE_ID, + leafId: terminal.leafId, + paneRuntimeId: terminal.paneRuntimeId, + ptyId: terminal.ptyId, + paneTitle: null + })) + }) + const db = new OrchestrationDb(':memory:') + try { + runtime.setOrchestrationDb(db) + runtime.attachWindow(1) + runtime.syncWindowGraph(1, graph()) + const runA = db.createRun({ + objective: 'own the nested worker', + coordinatorHandle: handles.coordinator, + coordinatorPaneKey: paneKey('coordinator') + }) + const creatorAuthority = runtime.getOrchestrationDispatchAuthority(handles.creator) + const coordinatorAuthority = runtime.getOrchestrationDispatchAuthority(handles.coordinator) + expect(creatorAuthority?.processIncarnation).toBeTruthy() + expect(coordinatorAuthority?.processIncarnation).toBeTruthy() + const creatorTask = db.createTask({ spec: 'create nested work', runId: runA.id }) + db.createDispatchContext( + creatorTask.id, + handles.creator, + paneKey('creator'), + undefined, + creatorAuthority?.processIncarnation ?? undefined + ) + const workerTask = db.createTask({ + spec: 'nested work', + runId: runA.id, + createdByTerminalHandle: handles.creator, + createdByPaneKey: paneKey('creator'), + createdByProcessIncarnation: creatorAuthority?.processIncarnation ?? undefined, + createdByRunGeneration: runA.consumer_generation + }) + const workerDispatch = db.createDispatchContext( + workerTask.id, + handles.worker, + paneKey('worker') + ) + const coordinatorCreatedTask = db.createTask({ + spec: 'coordinator-created work', + runId: runA.id, + createdByTerminalHandle: handles.coordinator, + createdByPaneKey: paneKey('coordinator'), + createdByProcessIncarnation: coordinatorAuthority?.processIncarnation ?? undefined, + createdByRunGeneration: runA.consumer_generation + }) + const coordinatorCreatedDispatch = db.createDispatchContext( + coordinatorCreatedTask.id, + handles['coordinator-created-worker'], + paneKey('coordinator-created-worker') + ) + expect( + runtime.syncWindowGraph(1, graph()).agentOrchestrationByPaneKey?.[paneKey('worker')] + ).toMatchObject({ + parentTerminalHandle: handles.creator, + parentPaneKey: paneKey('creator'), + coordinatorHandle: handles.coordinator, + orchestrationRunId: runA.id + }) + + const oldCreatorPaneKey = paneKey('creator') + terminalByName.creator.tabId = 'tab-creator-reminted' + terminalByName.creator.ptyId = 'pty-creator-reminted' + const remintedCreatorHandle = runtime.preAllocateHandleForPty(terminalByName.creator.ptyId) + runtime.syncWindowGraph(1, graph()) + const runB = db.createRun({ + objective: 'rebind the creator pane', + coordinatorHandle: remintedCreatorHandle, + coordinatorPaneKey: paneKey('creator') + }) + const reboundContext = runtime.syncWindowGraph(1, graph()).agentOrchestrationByPaneKey?.[ + paneKey('worker') + ] + + expect(db.getRun(runA.id)).toMatchObject({ + coordinator_handle: handles.coordinator, + consumer_generation: 1 + }) + expect(oldCreatorPaneKey).not.toBe(paneKey('creator')) + expect(db.getRun(runB.id)).toMatchObject({ coordinator_handle: remintedCreatorHandle }) + expect(reboundContext).toMatchObject({ + taskId: workerTask.id, + dispatchId: workerDispatch.id, + dispatchStatus: 'dispatched', + parentTerminalHandle: handles.coordinator, + parentPaneKey: paneKey('coordinator'), + coordinatorHandle: handles.coordinator, + orchestrationRunId: runA.id + }) + + db.createRun({ + objective: 'rebind the original coordinator pane', + coordinatorHandle: handles.coordinator, + coordinatorPaneKey: paneKey('coordinator') + }) + const unboundContext = runtime.syncWindowGraph(1, graph()).agentOrchestrationByPaneKey?.[ + paneKey('coordinator-created-worker') + ] + + expect(db.getRun(runA.id)).toMatchObject({ + coordinator_handle: null, + coordinator_pane_key: null, + consumer_generation: 2 + }) + expect(unboundContext).toEqual({ + taskId: coordinatorCreatedTask.id, + dispatchId: coordinatorCreatedDispatch.id, + dispatchStatus: 'dispatched', + taskTitle: 'coordinator-created work', + displayName: 'coordinator-created work', + orchestrationRunId: runA.id + }) + } finally { + db.close() + } + }) + + it('queries each stable terminal handle once while publishing orchestration context', () => { + const runtime = new OrcaRuntimeService(store) + const terminals = Array.from({ length: 100 }, (_, index) => ({ + tabId: `tab-query-${index}`, + leafId: `00000000-0000-4000-8000-${String(index).padStart(12, '0')}`, + ptyId: `pty-query-${index}`, + paneRuntimeId: index + 1 + })) + const handles = terminals.map((terminal) => runtime.preAllocateHandleForPty(terminal.ptyId)) + const db = new OrchestrationDb(':memory:') + try { + const run = db.createRun({ + objective: 'query count oracle', + coordinatorHandle: handles[99], + coordinatorPaneKey: makePaneKey(terminals[99].tabId, terminals[99].leafId) + }) + const task = db.createTask({ spec: 'one dispatched terminal', runId: run.id }) + const dispatch = db.createDispatchContext( + task.id, + handles[0], + makePaneKey(terminals[0].tabId, terminals[0].leafId) + ) + const getActiveDispatchForTerminal = vi.spyOn(db, 'getActiveDispatchForTerminal') + const getLatestDispatchForTerminal = vi.spyOn(db, 'getLatestDispatchForTerminal') + const getTask = vi.spyOn(db, 'getTask') + const getRun = vi.spyOn(db, 'getRun') + const getActiveCoordinatorRun = vi.spyOn(db, 'getActiveCoordinatorRun') + runtime.setOrchestrationDb(db) + runtime.attachWindow(1) + + const graph = { + tabs: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: TEST_WORKTREE_ID, + title: terminal.tabId, + activeLeafId: terminal.leafId, + layout: null + })), + leaves: terminals.map((terminal) => ({ + tabId: terminal.tabId, + worktreeId: TEST_WORKTREE_ID, + leafId: terminal.leafId, + paneRuntimeId: terminal.paneRuntimeId, + ptyId: terminal.ptyId, + paneTitle: null + })) + } + runtime.syncWindowGraph(1, graph) + + const queryCounts = { + activeDispatch: getActiveDispatchForTerminal.mock.calls.length, + latestDispatch: getLatestDispatchForTerminal.mock.calls.length, + task: getTask.mock.calls.length, + run: getRun.mock.calls.length, + legacyCoordinator: getActiveCoordinatorRun.mock.calls.length + } + + db.completeDispatch(dispatch.id) + vi.useFakeTimers() + vi.setSystemTime(Date.now() + AGENT_STATUS_STALE_AFTER_MS + 5_000) + for (const query of [ + getActiveDispatchForTerminal, + getLatestDispatchForTerminal, + getTask, + getRun, + getActiveCoordinatorRun + ]) { + query.mockClear() + } + runtime.syncWindowGraph(1, graph) + + const historicalQueryCounts = { + activeDispatch: getActiveDispatchForTerminal.mock.calls.length, + latestDispatch: getLatestDispatchForTerminal.mock.calls.length, + task: getTask.mock.calls.length, + run: getRun.mock.calls.length, + legacyCoordinator: getActiveCoordinatorRun.mock.calls.length + } + expect({ + active: { + ...queryCounts, + total: Object.values(queryCounts).reduce((sum, n) => sum + n) + }, + historical: { + ...historicalQueryCounts, + total: Object.values(historicalQueryCounts).reduce((sum, n) => sum + n) + } + }).toEqual({ + active: { + activeDispatch: 100, + latestDispatch: 99, + task: 1, + run: 1, + legacyCoordinator: 0, + total: 201 + }, + historical: { + activeDispatch: 100, + latestDispatch: 100, + task: 0, + run: 0, + legacyCoordinator: 0, + total: 200 + } + }) + } finally { + vi.useRealTimers() + db.close() + } + }) + it('returns completed orchestration context for renderer-synced terminal leaves', () => { const runtime = new OrcaRuntimeService(store) const workerLeafId = '33333333-3333-4333-8333-333333333333' @@ -37169,6 +38550,7 @@ describe('OrcaRuntimeService', () => { handle === workerHandle ? { id: 'ctx-done', + run_id: 'run-1', task_id: 'task-done', assignee_handle: workerHandle, status: 'completed', @@ -37178,7 +38560,13 @@ describe('OrcaRuntimeService', () => { ), getTask: vi.fn(() => ({ id: 'task-done', + run_id: 'run-1', created_by_terminal_handle: coordinatorHandle + })), + getRun: vi.fn(() => ({ + id: 'run-1', + coordinator_handle: coordinatorHandle, + legacy: 0 })) } as never) runtime.attachWindow(1) @@ -37741,6 +39129,7 @@ describe('OrcaRuntimeService', () => { expect.objectContaining({ id: 'repo-1', path: '/tmp/repo' }), '/tmp/workspaces/runtime-hook-test', 'pnpm worktree:setup', + undefined, undefined ) expect(runHook).not.toHaveBeenCalled() @@ -37832,6 +39221,85 @@ describe('OrcaRuntimeService', () => { ) }) + it('passes the selected Windows setup shell into runtime runner generation', async () => { + setPlatform('win32') + const runtimeStore = { + ...store, + getSettings: () => ({ + ...store.getSettings(), + terminalWindowsShell: 'git-bash' + }) + } + const runtime = new OrcaRuntimeService(runtimeStore as never) + const activateWorktree = vi.fn() + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree, + createTerminal: vi.fn(), + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + runtime.attachWindow(1) + + computeWorktreePathMock.mockReturnValue('C:\\workspaces\\runtime-hook-activate') + ensurePathWithinWorkspaceMock.mockReturnValue('C:\\workspaces\\runtime-hook-activate') + vi.mocked(getEffectiveHooks).mockReturnValue({ + scripts: { + setup: 'pnpm worktree:setup' + } + }) + vi.mocked(resolveSetupRunnerShell).mockReturnValue({ family: 'posix' }) + vi.mocked(createSetupRunnerScript).mockReturnValue({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix' }, + envVars: { + ORCA_ROOT_PATH: 'C:\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspaces\\runtime-hook-activate' + } + }) + vi.mocked(listWorktrees).mockResolvedValueOnce([ + { + path: 'C:/workspaces/runtime-hook-activate', + head: 'def', + branch: 'runtime-hook-activate', + isBare: false, + isMainWorktree: false + } + ]) + + const result = await runtime.createManagedWorktree({ + repoSelector: 'id:repo-1', + name: 'runtime-hook-activate', + runHooks: true, + activate: true + }) + + expect(createSetupRunnerScript).toHaveBeenCalledWith( + expect.objectContaining({ id: 'repo-1', path: '/tmp/repo' }), + 'C:\\workspaces\\runtime-hook-activate', + 'pnpm worktree:setup', + undefined, + { family: 'posix' } + ) + expect(result.setup).toMatchObject({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix' } + }) + expect(activateWorktree).toHaveBeenCalledWith( + 'repo-1', + expect.any(String), + result.setup, + undefined, + undefined + ) + }) + it('follows normal setup policy for CLI-created worktrees without activating them', async () => { const runtime = new OrcaRuntimeService(store) const activateWorktree = vi.fn() @@ -37896,6 +39364,7 @@ describe('OrcaRuntimeService', () => { expect.objectContaining({ id: 'repo-1', path: '/tmp/repo' }), '/tmp/workspaces/runtime-hook-skip', 'pnpm worktree:setup', + undefined, undefined ) expect(runHook).not.toHaveBeenCalled() @@ -37949,6 +39418,224 @@ describe('OrcaRuntimeService', () => { }) }) + it('uses returned WSL setup shell metadata when runtime spawns setup', async () => { + setPlatform('win32') + const runtime = new OrcaRuntimeService(store) + const revealTerminalSession = vi.fn().mockResolvedValue({ tabId: 'tab-created-worktree' }) + const spawn = vi + .fn() + .mockResolvedValueOnce({ id: 'pty-primary' }) + .mockResolvedValueOnce({ id: 'pty-setup' }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree: vi.fn(), + createTerminal: vi.fn(), + revealTerminalSession, + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + runtime.attachWindow(1) + + computeWorktreePathMock.mockReturnValue('C:\\workspaces\\runtime-hook-wsl') + ensurePathWithinWorkspaceMock.mockReturnValue('C:\\workspaces\\runtime-hook-wsl') + vi.mocked(getEffectiveHooks).mockReturnValue({ + scripts: { + setup: 'pnpm worktree:setup' + } + }) + vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) + vi.mocked(createSetupRunnerScript).mockReturnValue({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix', executable: 'wsl.exe' }, + envVars: { + ORCA_ROOT_PATH: 'C:\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspaces\\runtime-hook-wsl' + } + }) + vi.mocked(listWorktrees).mockResolvedValue([ + { + path: 'C:/workspaces/runtime-hook-wsl', + head: 'def', + branch: 'runtime-hook-wsl', + isBare: false, + isMainWorktree: false + } + ]) + + const result = await runtime.createManagedWorktree({ + repoSelector: 'id:repo-1', + name: 'runtime-hook-wsl' + }) + + expect(result.setup).toBeUndefined() + await vi.waitFor(() => expect(spawn).toHaveBeenCalledTimes(2)) + expect(spawn).toHaveBeenNthCalledWith( + 2, + expect.objectContaining({ + command: 'bash /mnt/c/repo/.git/orca/setup-runner.sh', + env: expect.objectContaining({ + ORCA_ROOT_PATH: 'C:\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspaces\\runtime-hook-wsl', + ORCA_TAB_ID: expect.stringMatching(UUID_RE), + ORCA_PANE_KEY: expect.any(String), + ORCA_WORKTREE_ID: result.worktree.id + }), + worktreeId: result.worktree.id + }) + ) + }) + + it('uses the shell-aware setup runner for windowless creates without a startup command', async () => { + // Regression (C1): with no authoritative window and no startup command the + // create fell back to runHook, which hardcodes cmd.exe on Windows and so ran + // batch even when the configured terminal resolves to Git Bash. + setPlatform('win32') + const runtime = new OrcaRuntimeService(store) + const revealTerminalSession = vi.fn().mockResolvedValue({ tabId: 'tab-windowless' }) + const spawn = vi + .fn() + .mockResolvedValueOnce({ id: 'pty-primary' }) + .mockResolvedValueOnce({ id: 'pty-setup' }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree: vi.fn(), + createTerminal: vi.fn(), + revealTerminalSession, + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + // Deliberately no attachWindow: this is the windowless/CLI create path. + + computeWorktreePathMock.mockReturnValue('C:\\workspaces\\runtime-hook-windowless') + ensurePathWithinWorkspaceMock.mockReturnValue('C:\\workspaces\\runtime-hook-windowless') + vi.mocked(getEffectiveHooks).mockReturnValue({ + scripts: { + setup: 'pnpm worktree:setup' + } + }) + vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) + vi.mocked(resolveSetupRunnerShell).mockReturnValue({ family: 'posix' }) + vi.mocked(createSetupRunnerScript).mockReturnValue({ + runnerScriptPath: 'C:\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix' }, + envVars: { + ORCA_ROOT_PATH: 'C:\\repo', + ORCA_WORKTREE_PATH: 'C:\\workspaces\\runtime-hook-windowless' + } + }) + vi.mocked(listWorktrees).mockResolvedValue([ + { + path: 'C:/workspaces/runtime-hook-windowless', + head: 'def', + branch: 'runtime-hook-windowless', + isBare: false, + isMainWorktree: false + } + ]) + + const result = await runtime.createManagedWorktree({ + repoSelector: 'id:repo-1', + name: 'runtime-hook-windowless', + awaitTerminalProvisioning: true + }) + + expect(createSetupRunnerScript).toHaveBeenCalledWith( + expect.objectContaining({ id: 'repo-1' }), + 'C:\\workspaces\\runtime-hook-windowless', + 'pnpm worktree:setup', + undefined, + { family: 'posix' } + ) + expect(runHook).not.toHaveBeenCalled() + expect(result.setupReceipt).toMatchObject({ state: 'running' }) + await vi.waitFor(() => expect(spawn).toHaveBeenCalledTimes(2)) + expect(spawn).toHaveBeenNthCalledWith( + 2, + expect.objectContaining({ + command: 'bash /c/repo/.git/orca/setup-runner.sh', + worktreeId: result.worktree.id + }) + ) + }) + + it('reports the in-process setup hook as running when nothing can launch the runner', async () => { + // Regression (C1): the fire-and-forget hook is the last resort when there is + // no PTY controller; reporting spawn_failed made callers retry a live hook. + const runtime = new OrcaRuntimeService(store) + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree: vi.fn(), + createTerminal: vi.fn(), + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + + computeWorktreePathMock.mockReturnValue('/tmp/workspaces/runtime-hook-no-pty') + ensurePathWithinWorkspaceMock.mockReturnValue('/tmp/workspaces/runtime-hook-no-pty') + vi.mocked(getEffectiveHooks).mockReturnValue({ + scripts: { + setup: 'pnpm worktree:setup' + } + }) + vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) + vi.mocked(runHook).mockResolvedValue({ success: true, output: '' }) + vi.mocked(listWorktrees).mockResolvedValue([ + { + path: '/tmp/workspaces/runtime-hook-no-pty', + head: 'def', + branch: 'runtime-hook-no-pty', + isBare: false, + isMainWorktree: false + } + ]) + + const result = await runtime.createManagedWorktree({ + repoSelector: 'id:repo-1', + name: 'runtime-hook-no-pty', + awaitTerminalProvisioning: true + }) + + expect(createSetupRunnerScript).not.toHaveBeenCalled() + expect(runHook).toHaveBeenCalledWith( + 'setup', + '/tmp/workspaces/runtime-hook-no-pty', + expect.objectContaining({ id: 'repo-1' }), + '/tmp/workspaces/runtime-hook-no-pty', + undefined + ) + expect(result.setupReceipt).toMatchObject({ state: 'running' }) + }) + it('sequences setup before startup for opted-in local headless worktree creates', async () => { const waitRepo = { ...store.getRepo('repo-1')!, @@ -38001,7 +39688,8 @@ describe('OrcaRuntimeService', () => { }) vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) vi.mocked(createSetupRunnerScript).mockReturnValue({ - runnerScriptPath: '/tmp/repo/.git/orca/setup-runner.sh', + runnerScriptPath: 'C:\\tmp\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix', executable: 'wsl.exe' }, envVars: { ORCA_ROOT_PATH: '/tmp/repo', ORCA_WORKTREE_PATH: '/tmp/workspaces/runtime-headless-startup-setup' @@ -38038,6 +39726,8 @@ describe('OrcaRuntimeService', () => { const nonceMatch = startupCommand.match(/if \[ "\$seen" = ([0-9a-f-]+) \]/) expect(nonceMatch?.[1]).toBeTruthy() expect(startupCommand).toContain('exec claude') + expect(startupCommand).toContain('/mnt/c/tmp/repo/.git/orca/setup-runner.sh') + expect(setupCommand).toContain('bash /mnt/c/tmp/repo/.git/orca/setup-runner.sh') expect(setupCommand).toContain('printf') expect(setupCommand).toContain(`${nonceMatch![1]} "$status"`) expect(result.setup).toBeUndefined() @@ -38120,6 +39810,75 @@ describe('OrcaRuntimeService', () => { }) }) + it('observes setup completion through the launch shell the runner was written for', async () => { + const runtime = new OrcaRuntimeService(store) + const revealTerminalSession = vi.fn().mockResolvedValue({ tabId: 'tab-observed-wsl-shell' }) + const spawn = vi + .fn() + .mockResolvedValueOnce({ id: 'pty-observed-wsl-startup' }) + .mockResolvedValueOnce({ id: 'pty-observed-wsl-setup' }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + runtime.setNotifier({ + worktreesChanged: vi.fn(), + reposChanged: vi.fn(), + activateWorktree: vi.fn(), + createTerminal: vi.fn(), + revealTerminalSession, + splitTerminal: vi.fn(), + renameTerminal: vi.fn(), + focusTerminal: vi.fn(), + closeTerminal: vi.fn(), + sleepWorktree: vi.fn(), + terminalFitOverrideChanged: vi.fn(), + terminalDriverChanged: vi.fn() + }) + + computeWorktreePathMock.mockReturnValue('/tmp/workspaces/runtime-observed-wsl-shell') + ensurePathWithinWorkspaceMock.mockReturnValue('/tmp/workspaces/runtime-observed-wsl-shell') + vi.mocked(getEffectiveHooks).mockReturnValue({ + scripts: { + setup: 'pnpm worktree:setup' + } + }) + vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) + vi.mocked(createSetupRunnerScript).mockReturnValue({ + runnerScriptPath: 'C:\\tmp\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix', executable: 'wsl.exe' }, + envVars: { + ORCA_ROOT_PATH: '/tmp/repo', + ORCA_WORKTREE_PATH: '/tmp/workspaces/runtime-observed-wsl-shell' + } + }) + vi.mocked(listWorktrees).mockResolvedValue([ + { + path: '/tmp/workspaces/runtime-observed-wsl-shell', + head: 'def', + branch: 'runtime-observed-wsl-shell', + isBare: false, + isMainWorktree: false + } + ]) + + await runtime.createManagedWorktree({ + repoSelector: 'id:repo-1', + name: 'runtime-observed-wsl-shell', + setupDecision: 'run', + startup: { command: 'claude' }, + observeSetupCompletion: true, + awaitTerminalProvisioning: true + }) + + await vi.waitFor(() => expect(spawn).toHaveBeenCalledTimes(2)) + const setupCommand = (spawn.mock.calls[1]![0] as { command: string }).command + expect(setupCommand).toContain('bash /mnt/c/tmp/repo/.git/orca/setup-runner.sh') + expect(setupCommand).toContain('__ORCA_SETUP_COMPLETE__:') + }) + it('creates the first terminal for CLI-created worktrees without activating them', async () => { const runtime = new OrcaRuntimeService(store) const activateWorktree = vi.fn() @@ -39334,7 +41093,8 @@ describe('OrcaRuntimeService', () => { }) vi.mocked(shouldRunSetupForCreate).mockReturnValue(true) vi.mocked(createSetupRunnerScript).mockReturnValue({ - runnerScriptPath: '/tmp/repo/.git/orca/setup-runner.sh', + runnerScriptPath: 'C:\\tmp\\repo\\.git\\orca\\setup-runner.sh', + shell: { family: 'posix', executable: 'wsl.exe' }, envVars: { ORCA_ROOT_PATH: '/tmp/repo', ORCA_WORKTREE_PATH: '/tmp/workspaces/runtime-startup-setup-retry' @@ -39364,8 +41124,8 @@ describe('OrcaRuntimeService', () => { 'repo-1', expect.any(String), expect.objectContaining({ - runnerScriptPath: '/tmp/repo/.git/orca/setup-runner.sh', - command: expect.stringContaining('bash /tmp/repo/.git/orca/setup-runner.sh') + runnerScriptPath: 'C:\\tmp\\repo\\.git\\orca\\setup-runner.sh', + command: expect.stringContaining('bash /mnt/c/tmp/repo/.git/orca/setup-runner.sh') }), undefined, undefined diff --git a/src/main/runtime/orca-runtime.ts b/src/main/runtime/orca-runtime.ts index 8c75a00d579..849cfdc9c72 100644 --- a/src/main/runtime/orca-runtime.ts +++ b/src/main/runtime/orca-runtime.ts @@ -106,6 +106,7 @@ import { mkdir, readFile, readdir, rm, stat } from 'node:fs/promises' import { resolveWorktreeCreateBase } from '../worktree-create-base' import { resolveWorktreeAddBaseRef } from '../../shared/worktree-base-ref' import { OrchestrationDb } from './orchestration/db' +import { reconcileRequestedWorkerTerminalReleases } from './orchestration/worker-terminal-release-reconciliation' import { OrchestrationError } from './orchestration/orchestration-error' import { planLegacyWorkerTerminalRecovery, @@ -424,6 +425,7 @@ import { isPathInsideOrEqual, normalizeRuntimePathForComparison } from '../../shared/cross-platform-path' +import { findRuntimeWorkspaceFileOwner } from '../../shared/runtime-workspace-file-owner' import { resolveTerminalStartupCwd } from '../../shared/terminal-startup-cwd' import { isWslUncPath, parseWslUncPath } from '../../shared/wsl-paths' import { @@ -514,7 +516,7 @@ import { } from './workspace-session-terminal-membership-authority' import { RuntimeEmulatorCommands } from './orca-runtime-emulator' import type { EmulatorBridge } from '../emulator/emulator-bridge' -import { RuntimeFileCommands } from './orca-runtime-files' +import { getRuntimeFileTargetExecutionHostId, RuntimeFileCommands } from './orca-runtime-files' import { RuntimeGitCommands } from './orca-runtime-git' import { activateClientSessionTabSelection, @@ -527,6 +529,7 @@ import type { IFilesystemProvider, IPtyProvider, PtyProcessInfo, + PtySpawnResult, PtyTransientFact } from '../providers/types' import { ClaudeAgentTeamsService } from './claude-agent-teams-service' @@ -840,6 +843,7 @@ import { loadHooks, parseOrcaYaml, readIssueCommand, + resolveSetupRunnerShell, runHook, shouldRunSetupForCreate, writeIssueCommand @@ -948,6 +952,7 @@ import { createMobileSessionTabsNotifyCoalescer, type MobileSessionTabsNotifyCoalescer } from './mobile-session-tabs-notify-coalescer' +import { TerminalFocusNavigationCoalescer } from './terminal-focus-navigation-coalescer' import { getSshFilesystemProvider } from '../providers/ssh-filesystem-dispatch' import { assertFolderWorkspacePathUsable, @@ -1273,6 +1278,10 @@ type TerminalCreateOptions = { resumeProviderSession?: AgentProviderSessionMetadata launchToken?: string launchAgent?: TuiAgent + // Why: agent ids are not shell commands (`cursor` is the Cursor desktop app; its + // CLI is `cursor-agent`). Callers that know the agent name it here instead of + // guessing a command, and the runtime builds the configured launch. + startupAgent?: TuiAgent terminalColorQueryReplies?: TerminalOscColorQueryReplyColors viewMode?: 'terminal' | 'chat' startupCommandDelivery?: WorktreeStartupLaunch['startupCommandDelivery'] @@ -1289,6 +1298,7 @@ type TerminalCreateOptions = { tabId?: string leafId?: string sessionId?: string + isNewSession?: boolean preAllocatedHandle?: string persistHostSessionBinding?: boolean // Why: only the host-derived structured resume path may attach provider @@ -1525,6 +1535,32 @@ type HeadlessSeedMetadata = { } type RuntimePtyController = { + claimStablePaneCreate?(args: { + worktreeId: string + connectionId: string | null + tabId: string + leafId: string + }): () => void + adoptStablePane?(opts: { + cols: number + rows: number + cwd?: string + connectionId: string | null + worktreeId: string + preAllocatedHandle: string + tabId: string + leafId: string + }): Promise<{ + result: PtySpawnResult + owner: { + handle?: string + tabId: string + leafId: string + ptyId: string + incarnationId?: string + } + materialized?: true + } | null> spawn?(opts: { cols: number rows: number @@ -1543,6 +1579,7 @@ type RuntimePtyController = { tabId?: string leafId?: string sessionId?: string + isNewSession?: boolean persistHostSessionBinding?: boolean terminalColorQueryReplies?: { foreground?: string; background?: string } agentSessionEnsure?: { @@ -1552,10 +1589,22 @@ type RuntimePtyController = { agentSessionCreateOperationId?: string signal?: AbortSignal onPtySpawnCommitted?: () => void + adoptedStablePane?: { + result: PtySpawnResult + owner: { + handle?: string + tabId: string + leafId: string + ptyId: string + incarnationId?: string + } + materialized?: true + } }): Promise<{ id: string incarnationId?: PtyIncarnationId wslDistro?: string + stablePaneOwner?: { handle: string; tabId: string; leafId: string } agentSessionEnsure?: AgentSessionClaimedSpawnResult }> write(ptyId: string, data: string): boolean @@ -1958,8 +2007,15 @@ type PreservedBranchCleanupTarget = { pushTarget?: GitPushTarget } -function getRuntimeWorktreeRemovalOptionsKey(force: boolean, runHooks: boolean): string { - return `${force ? 'force' : 'normal'}:${runHooks ? 'run-hooks' : 'skip-hooks'}` +function getRuntimeWorktreeRemovalOptionsKey( + force: boolean, + runHooks: boolean, + allowUnverifiedPtyStop: boolean +): string { + // Why: a forced retry must not coalesce onto the in-flight attempt that just + // failed the PTY gate — it would inherit that failure instead of retrying. + const ptyKey = allowUnverifiedPtyStop ? 'allow-unverified-pty' : 'require-pty-stop' + return `${force ? 'force' : 'normal'}:${runHooks ? 'run-hooks' : 'skip-hooks'}:${ptyKey}` } function getRuntimeFolderWorkspaceRootId(repo: Repo): string { @@ -2637,6 +2693,13 @@ async function hasLocalWorktreeBaseRef( ) } +function getSetupRunnerCommandPlatformForLaunch( + setup: CreateWorktreeResult['setup'], + fallbackPlatform: 'windows' | 'posix' +): 'windows' | 'posix' { + return getSetupRunnerCommandPlatformForPath(setup?.runnerScriptPath ?? '', fallbackPlatform) +} + export class OrcaRuntimeService { private readonly runtimeId = randomUUID() private readonly startedAt = Date.now() @@ -2662,7 +2725,12 @@ export class OrcaRuntimeService { // resend (or stale) and is skipped without touching the stored entry. private acceptedRendererMobileSnapshotByWorktree = new Map< string, - { publicationEpoch: string; rendererVersion: number } + { + publicationEpoch: string + rendererVersion: number + rendererTabCount: number + rendererTabIdentityKeys: ReadonlySet + } >() private clientSessionTabSelections = new ClientSessionTabSelectionStore() // Why: idempotency map for mobile terminal creation — a retried create with the @@ -2704,6 +2772,9 @@ export class OrcaRuntimeService { paired: boolean selectIfNoActiveTab: boolean viewMode?: 'terminal' | 'chat' + /** Resolved agent launch command, kept so a settle over a bare renderer + * PTY can still deliver the launch instead of succeeding silently (STA-3214). */ + startupCommand?: string } >() private mobileSessionTabListeners = new Set<{ @@ -2725,6 +2796,12 @@ export class OrcaRuntimeService { createMobileSessionTabsNotifyCoalescer((worktreeId) => this.notifyMobileSessionTabsChangedNow(worktreeId) ) + // Why: concurrent host terminal.focus storms (CLI switch fan-out / bulk open) + // each await a full host reveal; only one terminal can be focused, so latest-wins + // single-flight bounds host work. Does not replace cheaper activation or + // reconnect-scan bounding for sequential soft freezes. + private readonly terminalFocusNavigationCoalescer = + new TerminalFocusNavigationCoalescer() private pendingMobileSessionPtyInventoryRefresh: Promise | null> | null = null private leaves = new Map() // Why: PTY output is a per-keystroke hot path. Looking up affected leaves by @@ -3302,17 +3379,25 @@ export class OrcaRuntimeService { private async stopPtysForDestructiveWorktreeRemoval( worktreeId: string, - connectionId?: string + options: { connectionId?: string; allowUnverifiedStop?: boolean } = {} ): Promise { + const { connectionId, allowUnverifiedStop } = options const provider = connectionId ? this.getSshProviderFn?.(connectionId) : this.getLocalProvider() if (!provider) { throw new Error(`PTY provider unavailable for worktree deletion: ${worktreeId}`) } const teardownResult = await killAllProcessesForWorktree(worktreeId, { runtime: this, + // Why: `repoId::path` ids repeat across hosts, so an unfenced sweep stops a same-id + // workspace's terminals on another connection (mirrors the IPC removal path). + resolvedWorktreeId: worktreeId, + ...(connectionId ? { resolvedConnectionId: connectionId } : {}), localProvider: provider, onPtyStopped: this.onPtyStopped ?? undefined, requirePhysicalStop: true, + // Why (#11960): set only by an explicit Force Delete, never by the ordinary + // confirmation — otherwise the gate would be off on the primary delete path. + ...(allowUnverifiedStop ? { allowUnverifiedStop: true } : {}), ...(connectionId ? { includeLocalRegistry: false } : {}) }) const total = @@ -4429,6 +4514,11 @@ export class OrcaRuntimeService { deferredDispatchIds: [...deferredDispatchIds] } this.updateLegacyWorkerTerminalRecoveryRetry(plan, deferredDispatchIds, options) + // Why: previously requested releases may only finish after the owning provider's terminals + // are rediscovered; this pass runs per scope (local and each reconnected provider). + void reconcileRequestedWorkerTerminalReleases(this).catch((error) => { + console.warn('[orchestration] worker terminal release reconciliation failed', { error }) + }) return result } @@ -5301,7 +5391,12 @@ export class OrcaRuntimeService { const previousLeaves = this.leaves this.tabs = new Map(graph.tabs.map((tab) => [tab.tabId, tab])) const lifecycleLeaves = this.reconcileMobileSessionRetirementFences(graph.leaves) - const changedMobileWorktrees = this.syncMobileSessionTabs(graph.mobileSessionTabs) + const mobileSessionResyncWorktrees = new Set() + const changedMobileWorktrees = this.syncMobileSessionTabs( + graph.mobileSessionTabs, + graph.unchangedMobileSessionWorktrees, + mobileSessionResyncWorktrees + ) const nextLeaves = new Map() const graphSyncedAt = this.nextTitleObservationSequence() @@ -5477,7 +5572,10 @@ export class OrcaRuntimeService { return { ...this.getStatus(), ...(agentOrchestrationByPaneKey ? { agentOrchestrationByPaneKey } : {}), - ...(nativeChatLaunchDraftResolutions.length > 0 ? { nativeChatLaunchDraftResolutions } : {}) + ...(nativeChatLaunchDraftResolutions.length > 0 ? { nativeChatLaunchDraftResolutions } : {}), + ...(mobileSessionResyncWorktrees.size > 0 + ? { mobileSessionResyncWorktrees: [...mobileSessionResyncWorktrees] } + : {}) } } @@ -8445,6 +8543,8 @@ export class OrcaRuntimeService { requireStore: () => this.requireStore(), resolveWorktreeSelector: (selector) => this.resolveWorktreeSelector(selector), resolveRuntimeFileTarget: (selector) => this.resolveRuntimeFileTarget(selector), + resolveKnownWorkspaceFileTarget: (absolutePath, connectionId) => + this.resolveKnownWorkspaceFileTarget(absolutePath, connectionId), resolveTerminalCwd: (terminalHandle) => this.resolveTerminalCwd(terminalHandle), resolveTerminalContext: (terminalHandle) => this.resolveTerminalContext(terminalHandle), resolveTerminalFileUriHostname: (terminalHandle) => @@ -8762,6 +8862,72 @@ export class OrcaRuntimeService { return { worktree, connectionId: repo?.connectionId ?? undefined } } + private async resolveKnownWorkspaceFileTarget( + absolutePath: string, + executionHostId: ExecutionHostId + ): Promise<{ + worktree: ResolvedWorktree + connectionId?: string + relativePath: string + } | null> { + const targets = new Map< + string, + { + worktree: ResolvedWorktree + connectionId?: string + executionHostId: ExecutionHostId + } + >() + for (const worktree of await this.listResolvedWorktrees()) { + if (!this.isRuntimeWorktreeVisible(worktree)) { + continue + } + const candidateConnectionId = this.store?.getRepo(worktree.repoId)?.connectionId ?? undefined + const target = { + worktree, + executionHostId: getRuntimeFileTargetExecutionHostId({ + worktree, + connectionId: candidateConnectionId + }), + ...(candidateConnectionId ? { connectionId: candidateConnectionId } : {}) + } + targets.set(`${target.executionHostId}\0${worktree.id}`, target) + } + for (const folderWorkspace of this.store?.getFolderWorkspaces?.() ?? []) { + try { + const candidateConnectionId = + this.resolveFolderWorkspaceConnectionId(folderWorkspace) ?? undefined + const worktree = this.folderWorkspaceToResolvedWorktree(folderWorkspace) + const target = { + worktree, + executionHostId: getRuntimeFileTargetExecutionHostId({ + worktree, + connectionId: candidateConnectionId + }), + ...(candidateConnectionId ? { connectionId: candidateConnectionId } : {}) + } + targets.set(`${target.executionHostId}\0${worktree.id}`, target) + } catch { + // An ambiguous folder workspace has no single filesystem authority. + } + } + + const owner = findRuntimeWorkspaceFileOwner( + [...targets.values()].map((target) => ({ + workspaceId: target.worktree.id, + rootPath: target.worktree.path, + executionHostId: target.executionHostId + })), + absolutePath, + executionHostId + ) + if (!owner) { + return null + } + const target = targets.get(`${owner.executionHostId}\0${owner.workspaceId}`) + return target ? { ...target, relativePath: owner.relativePath } : null + } + onMobileSessionTabsChanged( listener: (snapshot: RuntimeMobileSessionTabsResult) => void, clientNavigationId?: string @@ -15723,6 +15889,7 @@ export class OrcaRuntimeService { tabId: parsed?.tabId ?? record?.tabId ?? '', leafId: parsed?.leafId ?? record?.leafId ?? '', ptyId: record?.ptyId ?? null, + connected: pty?.connected === true, ...(worktreeId ? { worktreeId } : {}), ...this.getPtyExecutionHostMetadata(record?.ptyId ?? pty?.ptyId ?? null) } @@ -16241,9 +16408,10 @@ export class OrcaRuntimeService { const consider = ( state: AgentStatusEntry['state'] | undefined, - updatedAt: number | null | undefined + updatedAt: number | null | undefined, + restoredUnconfirmed = false ): void => { - if (!state) { + if (!state || restoredUnconfirmed) { return } if (typeof updatedAt !== 'number' || now - updatedAt > AGENT_STATUS_STALE_AFTER_MS) { @@ -16267,7 +16435,7 @@ export class OrcaRuntimeService { if (entry.terminalHandle !== handle && (!paneKey || entry.paneKey !== paneKey)) { continue } - consider(entry.state, entry.receivedAt) + consider(entry.state, entry.receivedAt, entry.restoredUnconfirmed) } return bestStatus ? { status: bestStatus, updatedAt: bestUpdatedAt } : null @@ -17082,6 +17250,7 @@ export class OrcaRuntimeService { interrupted: boolean stateStartedAt: number updatedAt: number + restoredUnconfirmed?: boolean } >() for (const snapshot of this.latestAgentStatusByPaneKey.values()) { @@ -17126,7 +17295,8 @@ export class OrcaRuntimeService { toolInput: entry.toolInput ?? null, interrupted: entry.interrupted ?? false, stateStartedAt: entry.stateStartedAt, - updatedAt: entry.receivedAt + updatedAt: entry.receivedAt, + ...(entry.restoredUnconfirmed ? { restoredUnconfirmed: true } : {}) }) } if (rowSources.size === 0) { @@ -17190,7 +17360,8 @@ export class OrcaRuntimeService { toolInput: src.toolInput, interrupted: src.interrupted, stateStartedAt: src.stateStartedAt, - updatedAt: src.updatedAt + updatedAt: src.updatedAt, + ...(src.restoredUnconfirmed ? { restoredUnconfirmed: true } : {}) } // Why: SSH/runtime projections can spell an equivalent path differently; // bucket by the canonical summary id so mobile keeps the agent activity. @@ -20566,13 +20737,18 @@ export class OrcaRuntimeService { ? buildObservedSetupCommand( args.setup.runnerScriptPath, args.setupCommandPlatform, - completionToken + completionToken, + args.setup.shell ) : null const setupCommand = args.wrappedSetupCommand ?? observedCommand?.command ?? - buildSetupRunnerCommand(args.setup.runnerScriptPath, args.setupCommandPlatform) + buildSetupRunnerCommand( + args.setup.runnerScriptPath, + args.setupCommandPlatform, + args.setup.shell + ) const setupEnv = { ...args.setup.envVars, ...observedCommand?.env } const shouldSplitSetup = primaryTerminalHandle && @@ -21507,17 +21683,27 @@ export class OrcaRuntimeService { : undefined } const shouldRunSetup = hooks?.scripts.setup && shouldRunSetupForCreate(repo, effectiveDecision) + // Why: the in-process hook uses a hardcoded cmd/bash shell, so it can only run + // when nothing downstream is able to launch the shell-aware runner script. + let didStartInProcessSetupHook = false if (shouldRunSetup && hooks?.scripts.setup) { - const shouldUseSetupRunner = this.authoritativeWindowId !== null || Boolean(effectiveStartup) + const shouldUseSetupRunner = + this.authoritativeWindowId !== null || + Boolean(effectiveStartup) || + Boolean(this.ptyController?.spawn) if (shouldUseSetupRunner) { try { // Why: setup+startup must share the terminal runner path even without - // a renderer window, so the startup shell can wait on setup completion. + // a renderer window, so the startup shell can wait on setup completion + // and windowless creates resolve the same Windows setup shell. + const runtimeTarget = this.getLocalGitExecutionOptionArgs(repo)[0] + // Why: both trailing args are optional — the shell is undefined off Windows. setup = createSetupRunnerScript( repo, worktreePath, hooks.scripts.setup, - this.getLocalGitExecutionOptionArgs(repo)[0] + runtimeTarget, + resolveSetupRunnerShell(settings) ) } catch (error) { // Why: the git worktree is already real at this point. If runner @@ -21526,6 +21712,7 @@ export class OrcaRuntimeService { console.error(`[hooks] Failed to prepare setup runner for ${worktreePath}:`, error) } } else { + didStartInProcessSetupHook = true void runHook( 'setup', worktreePath, @@ -21571,14 +21758,15 @@ export class OrcaRuntimeService { let sequencedStartup = effectiveStartup let wrappedSetupCommandStr: string | undefined if (effectiveStartup && setup?.waitForAgentStartup === true) { - const platform = getSetupRunnerCommandPlatformForPath( - setup.runnerScriptPath, + const platform = getSetupRunnerCommandPlatformForLaunch( + setup, process.platform === 'win32' ? 'windows' : 'posix' ) const sequenced = createSequencedSetupAgentCommands({ runnerScriptPath: setup.runnerScriptPath, startupCommand: effectiveStartup.command, - platform + platform, + shell: setup.shell }) sequencedStartup = { ...effectiveStartup, @@ -21650,11 +21838,7 @@ export class OrcaRuntimeService { ...(defaultTabs ? { defaultTabs } : {}), primaryTerminalHandle: startupTerminalHandle, hasStartupTerminal: didSpawnStartup, - setupCommandPlatform: setup - ? isWindowsAbsolutePathLike(setup.runnerScriptPath) - ? 'windows' - : 'posix' - : 'posix', + setupCommandPlatform: getSetupRunnerCommandPlatformForLaunch(setup, 'posix'), observeSetupCompletion: args.observeSetupCompletion, // Why: carry the wait-for-agent wrapped setup command (#6298) so the // Setup tab runs the same script the sequenced agent waits on. @@ -21705,11 +21889,7 @@ export class OrcaRuntimeService { ...(defaultTabs ? { defaultTabs } : {}), primaryTerminalHandle: startupTerminalHandle, hasStartupTerminal: didSpawnStartup, - setupCommandPlatform: setup - ? isWindowsAbsolutePathLike(setup.runnerScriptPath) - ? 'windows' - : 'posix' - : 'posix', + setupCommandPlatform: getSetupRunnerCommandPlatformForLaunch(setup, 'posix'), observeSetupCompletion: args.observeSetupCompletion, ...(wrappedSetupCommandStr ? { wrappedSetupCommand: wrappedSetupCommandStr } : {}), surfaceOwner: false @@ -21776,7 +21956,9 @@ export class OrcaRuntimeService { ? ('not_configured' as const) : effectiveDecision === 'skip' || !shouldRunSetup ? ('skipped' as const) - : didSpawnSetup + : // Why: the in-process hook is already executing, so reporting + // spawn_failed would strand callers that retry on it. + didSpawnSetup || didStartInProcessSetupHook ? ('running' as const) : ('spawn_failed' as const), ...(setupTerminalHandle ? { terminalHandle: setupTerminalHandle } : {}) @@ -21927,11 +22109,12 @@ export class OrcaRuntimeService { let sequencedStartup = args.startup let wrappedSetupCommandStr: string | undefined if (args.startup && result.setup?.waitForAgentStartup === true) { - const platform = getSetupRunnerCommandPlatformForPath(result.setup.runnerScriptPath, 'posix') + const platform = getSetupRunnerCommandPlatformForLaunch(result.setup, 'posix') const sequenced = createSequencedSetupAgentCommands({ runnerScriptPath: result.setup.runnerScriptPath, startupCommand: args.startup.command, - platform + platform, + shell: result.setup.shell }) sequencedStartup = { ...args.startup, @@ -21998,11 +22181,7 @@ export class OrcaRuntimeService { ...(result.defaultTabs ? { defaultTabs: result.defaultTabs } : {}), primaryTerminalHandle: startupTerminalHandle, hasStartupTerminal: didSpawnStartup, - setupCommandPlatform: result.setup - ? isWindowsAbsolutePathLike(result.setup.runnerScriptPath) - ? 'windows' - : 'posix' - : 'posix', + setupCommandPlatform: getSetupRunnerCommandPlatformForLaunch(result.setup, 'posix'), observeSetupCompletion: args.observeSetupCompletion, // Why: carry the wait-for-agent wrapped setup command (#6298) so the // remote Setup tab runs the same script the sequenced agent waits on. @@ -22058,11 +22237,7 @@ export class OrcaRuntimeService { ...(result.defaultTabs ? { defaultTabs: result.defaultTabs } : {}), primaryTerminalHandle: startupTerminalHandle, hasStartupTerminal: didSpawnStartup, - setupCommandPlatform: result.setup - ? isWindowsAbsolutePathLike(result.setup.runnerScriptPath) - ? 'windows' - : 'posix' - : 'posix', + setupCommandPlatform: getSetupRunnerCommandPlatformForLaunch(result.setup, 'posix'), observeSetupCompletion: args.observeSetupCompletion, ...(wrappedSetupCommandStr ? { wrappedSetupCommand: wrappedSetupCommandStr } : {}), surfaceOwner: false @@ -23118,6 +23293,7 @@ export class OrcaRuntimeService { store.removeWorktreeMeta(worktreeId) } this.mobileSessionTabsByWorktree.delete(worktreeId) + this.acceptedRendererMobileSnapshotByWorktree.delete(worktreeId) advertisedUrlWatcher.forgetWorktree(worktreeId) deleteWorktreeHistoryDir(worktreeId) this.closeHeadlessBrowserPagesForWorktree(worktreeId) @@ -23246,14 +23422,17 @@ export class OrcaRuntimeService { async removeManagedWorktree( worktreeSelector: string, force = false, - runHooks = false + runHooks = false, + // Why (#11960): only an explicit Force Delete waives PTY-stop proof; `force` + // alone is already set by the ordinary delete confirmation. + allowUnverifiedPtyStop = false ): Promise { if (!this.store) { throw new Error('runtime_unavailable') } const store = this.store const removalTarget = await this.resolveWorktreeRemovalTarget(worktreeSelector) - const optionsKey = getRuntimeWorktreeRemovalOptionsKey(force, runHooks) + const optionsKey = getRuntimeWorktreeRemovalOptionsKey(force, runHooks, allowUnverifiedPtyStop) const inFlightRemoval = this.removeManagedWorktreeInFlight.get(removalTarget.id) if (inFlightRemoval) { if (inFlightRemoval.optionsKey === optionsKey) { @@ -23332,14 +23511,28 @@ export class OrcaRuntimeService { 'Cannot delete the project root workspace. Remove the folder project instead.' ) } - const localProvider = this.getLocalProvider() - if (localProvider) { + // This service runs inside the selected runtime, so runtime-stamped repos use its + // local PTY namespace; only a direct SSH connection is external from here. + const folderConnectionId = repo.connectionId?.trim() || null + const folderSshPtyProvider = folderConnectionId + ? this.getSshProviderFn?.(folderConnectionId) + : undefined + const folderPtyProvider = folderSshPtyProvider ?? this.getLocalProvider() + if (folderPtyProvider) { // Why: folder workspace deletion has no Git removal phase where PTYs // would otherwise be swept; tear them down before hiding the workspace. await killAllProcessesForWorktree(removalTarget.id, { runtime: this, - localProvider, - onPtyStopped: this.onPtyStopped ?? undefined + resolvedWorktreeId: removalTarget.id, + ...(folderConnectionId ? { resolvedConnectionId: folderConnectionId } : {}), + localProvider: folderPtyProvider, + onPtyStopped: this.onPtyStopped ?? undefined, + ...(folderConnectionId + ? { + includeProviderInventory: Boolean(folderSshPtyProvider), + includeLocalRegistry: false + } + : {}) }).catch((err) => { console.warn(`[worktree-teardown] failed for ${removalTarget.id}:`, err) }) @@ -23412,10 +23605,10 @@ export class OrcaRuntimeService { ) let removalCompleted = false try { - await this.stopPtysForDestructiveWorktreeRemoval( - removalTarget.id, - repo.connectionId - ) + await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, { + connectionId: repo.connectionId, + allowUnverifiedStop: allowUnverifiedPtyStop + }) await fsProvider!.deletePath(removalTarget.path, true) removalCompleted = true } finally { @@ -23432,7 +23625,9 @@ export class OrcaRuntimeService { const removalGate = await this.acquireFileWatcherRemoval(removalTarget.path) let removalCompleted = false try { - await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id) + await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, { + allowUnverifiedStop: allowUnverifiedPtyStop + }) await removeLocalWorktreePath(removalTarget.path, localWorktreeGitOptions) removalCompleted = true } finally { @@ -23480,7 +23675,9 @@ export class OrcaRuntimeService { const removalGate = await this.acquireFileWatcherRemoval(removalTarget.path) let removalCompleted = false try { - await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id) + await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, { + allowUnverifiedStop: allowUnverifiedPtyStop + }) await removeLocalWorktreePath(removalTarget.path, localWorktreeGitOptions) removalCompleted = true } finally { @@ -23599,7 +23796,10 @@ export class OrcaRuntimeService { let rawRemovalResult: RemoveWorktreeResult | undefined let removalCompleted = false try { - await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, repo.connectionId) + await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, { + connectionId: repo.connectionId, + allowUnverifiedStop: allowUnverifiedPtyStop + }) rawRemovalResult = await (Object.keys(remoteRemoveOptions).length > 0 ? provider!.removeWorktree(canonicalWorktreePath, force, remoteRemoveOptions) : provider!.removeWorktree(canonicalWorktreePath, force)) @@ -23710,7 +23910,9 @@ export class OrcaRuntimeService { try { // Why: linked-path deletion is destructive too; PTYs must release every // handle before Windows or WSL filesystem cleanup starts. - await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id) + await this.stopPtysForDestructiveWorktreeRemoval(removalTarget.id, { + allowUnverifiedStop: allowUnverifiedPtyStop + }) if (linkedPaths.length > 0) { await removeWorktreeLinkedPaths(canonicalWorktreePath, linkedPaths) @@ -23872,33 +24074,49 @@ export class OrcaRuntimeService { ): Promise { // Why: raw shell commands like `codex exec` must remain user-authored shell. // Only unmanaged, repo-backed, bare agent launches get Settings defaults. - if ( - !opts.command || + const callerSuppliedLaunch = opts.env || opts.launchConfig || opts.launchAgent || opts.startupCommandDelivery || - opts.claudeAgentTeamsSourceCommand || - !workspace.repo || - !this.store - ) { + opts.claudeAgentTeamsSourceCommand + const store = this.store + if (opts.startupAgent) { + // Why: falling through unresolved would spawn a bare shell that can only time + // out waiting for an agent. A caller-supplied launch contradicts the agent: + // `command` would be overwritten, `resumeProviderSession` would pair resume + // identity with a fresh launch. + if (callerSuppliedLaunch || opts.command || opts.resumeProviderSession) { + throw new Error( + `startupAgent ${opts.startupAgent} cannot combine with a caller-supplied launch.` + ) + } + if (!store) { + throw new Error('runtime_unavailable') + } + } else if (callerSuppliedLaunch || !store || !opts.command || !workspace.repo) { return opts } - const settings = this.store.getSettings() + const settings = store.getSettings() const platform = this.getAgentLaunchPlatformForWorkspace(workspace) - const isRemote = repoIsRemote(workspace.repo) + const isRemote = workspace.repo ? repoIsRemote(workspace.repo) : Boolean(workspace.connectionId) const queuedShell = resolveLocalWindowsAgentStartupShell({ platform, isRemote, terminalWindowsShell: settings.terminalWindowsShell }) - const agent = resolveBareAgentLaunchCommand({ - command: opts.command, - settings, - platform, - isRemote - }) + if (opts.startupAgent && !isTuiAgentEnabled(opts.startupAgent, settings.disabledTuiAgents)) { + throw new Error(`Agent ${opts.startupAgent} is disabled. Choose an enabled agent.`) + } + const agent = + opts.startupAgent ?? + resolveBareAgentLaunchCommand({ + command: opts.command, + settings, + platform, + isRemote + }) if (!agent) { return opts } @@ -23915,6 +24133,11 @@ export class OrcaRuntimeService { allowEmptyPromptLaunch: true }) if (!startupPlan) { + // Why: an explicit agent that yields no plan would otherwise spawn a bare + // shell that never reaches agent readiness. + if (opts.startupAgent) { + throw new Error(`Could not build launch command for ${opts.startupAgent}.`) + } return opts } @@ -24315,6 +24538,11 @@ export class OrcaRuntimeService { worktreeSelector?: string, opts: TerminalCreateOptions = {} ): Promise { + if (opts.startupAgent && worktreeSelector === undefined) { + // Why: the launch is resolved against a workspace, so with no selector + // startupAgent is silently dropped and the terminal is a bare shell. + throw new Error(`startupAgent ${opts.startupAgent} requires a workspace selector.`) + } const presentation = resolveTerminalPresentation(opts) const requiresRendererFocus = opts.presentation === 'focused' || opts.focus === true const availableAuthoritativeWindow = this.getAvailableAuthoritativeWindow() @@ -24365,236 +24593,299 @@ export class OrcaRuntimeService { let tabId = canAdoptPaneIdentity ? (hintedTabId as string) : randomUUID() let leafId = canAdoptPaneIdentity ? (launchOpts.leafId as string) : randomUUID() let paneKey = makePaneKey(tabId, leafId) - const launchToken = launchOpts.launchConfig - ? (launchOpts.launchToken ?? randomUUID()) - : undefined - const baseEnv = { - ...launchOpts.env, - ...(launchToken ? { ORCA_AGENT_LAUNCH_TOKEN: launchToken } : {}) - } - const claudeAgentTeamsSourceCommand = - launchOpts.claudeAgentTeamsSourceCommand?.trim() || launchOpts.command?.trim() || undefined - const claudeAgentTeamsMode = this.store?.getSettings?.().claudeAgentTeamsMode - const effectiveClaudeAgentTeamsMode = inferCapturedClaudeAgentTeamsMode( - launchOpts.launchConfig, - claudeAgentTeamsSourceCommand, - claudeAgentTeamsMode - ) - const agentTeamsPlan = await buildClaudeAgentTeamsLaunchPlan({ - command: claudeAgentTeamsSourceCommand, - mode: effectiveClaudeAgentTeamsMode, - baseEnv: { - ...process.env, - ...baseEnv - }, - createTeamEnv: (shimDir, shimBin) => - this.claudeAgentTeams.createLaunchEnv({ - leaderHandle: preAllocatedHandle, - baseEnv: { - ...process.env, - ...baseEnv - }, - shimDir, - shimBin - }).env - }) - const sequencedStartupCommand = - agentTeamsPlan && - claudeAgentTeamsSourceCommand && - launchOpts.command && - claudeAgentTeamsSourceCommand !== launchOpts.command - ? agentTeamsPlan.command - : undefined - const effectiveLaunchConfig = - launchOpts.launchConfig && agentTeamsPlan - ? { - ...launchOpts.launchConfig, - agentCommand: launchOpts.launchConfig.agentCommand - ? effectiveClaudeAgentTeamsMode === 'in-process' || process.platform === 'win32' - ? addClaudeTeammateModeInProcess(launchOpts.launchConfig.agentCommand) - : addClaudeTeammateModeAuto(launchOpts.launchConfig.agentCommand) - : agentTeamsPlan.command, - agentEnv: { - ...launchOpts.launchConfig.agentEnv, - ...agentTeamsPlan.env - } - } - : launchOpts.launchConfig - // Why: setup/agent sequencing wraps the PTY launch in a wait shell before - // Claude Agent Teams runs. Preserve the direct Claude command separately - // so the wrapper can exec the teammate-mode variant after setup completes. - const env = this.buildTerminalWorkspaceEnv( - workspace, - { - ...baseEnv, - ...(sequencedStartupCommand - ? { [SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]: sequencedStartupCommand } - : {}) - }, - paneKey, - tabId, - agentTeamsPlan?.env - ) - const terminalColorQueryReplies = - launchOpts.terminalColorQueryReplies ?? getTerminalViewColorQueryReplyColors() - if (launchOpts.signal?.aborted) { - throw new Error('client_disconnected') - } - const result = await this.ptyController.spawn({ - cols: 120, - rows: 40, - cwd, - command: sequencedStartupCommand - ? launchOpts.command - : (agentTeamsPlan?.command ?? launchOpts.command), - launchAgent: launchOpts.launchAgent, - commandDelivery: 'provider', - startupCommandDelivery: launchOpts.startupCommandDelivery, - env, - envToDelete: mergeTerminalEnvDeletionKeys( - launchOpts.envToDelete, - agentTeamsPlan?.envToDelete - ), - resumeProviderSession: launchOpts.resumeProviderSession, - telemetry: launchOpts.telemetry, - connectionId: workspace.connectionId, + const claimedStablePaneCreate = this.ptyController.claimStablePaneCreate?.({ worktreeId: workspace.id, - preAllocatedHandle, + connectionId: workspace.connectionId, tabId, - leafId, - ...(terminalColorQueryReplies ? { terminalColorQueryReplies } : {}), - ...(launchOpts.agentSessionClaim - ? { - agentSessionEnsure: { - claim: launchOpts.agentSessionClaim, - surface: { - worktreeId: workspace.id, - tabId, - leafId, - terminalHandle: preAllocatedHandle - } - } - } - : {}), - ...(launchOpts.agentSessionCreateOperationId - ? { agentSessionCreateOperationId: launchOpts.agentSessionCreateOperationId } - : {}), - ...(launchOpts.signal ? { signal: launchOpts.signal } : {}), - ...(launchOpts.onPtySpawnCommitted ? { onPtySpawnCommitted: reportPtySpawnCommitted } : {}), - ...(launchOpts.sessionId ? { sessionId: launchOpts.sessionId } : {}), - // Why: a headless-created pane has no renderer session writer. Persist - // its tab/leaf binding at spawn so a later promoted window reattaches - // the live daemon or SSH PTY instead of replacing it with a fresh one. - // Re-check freshly: the entry-time snapshot can go stale across the - // awaits above if the authoritative window is destroyed mid-spawn. - ...(launchOpts.persistHostSessionBinding || this.getAvailableAuthoritativeWindow() === null - ? { persistHostSessionBinding: true } - : {}) + leafId }) - reportPtySpawnCommitted() - if (result.agentSessionEnsure) { - const canonicalSurface = result.agentSessionEnsure.owner.surface - preAllocatedHandle = canonicalSurface.terminalHandle - tabId = canonicalSurface.tabId - leafId = canonicalSurface.leafId - paneKey = makePaneKey(tabId, leafId) + let stablePaneCreateReleased = false + const releaseStablePaneCreate = (): void => { + if (stablePaneCreateReleased) { + return + } + stablePaneCreateReleased = true + claimedStablePaneCreate?.() } try { - this.assertPtyDidNotExitBeforeRegistration(result.id, result.incarnationId) - } catch (error) { - if (error instanceof Error && error.message === 'agent_session_exited_during_start') { - this.releaseRejectedPtyRegistrationFence(result.id, result.incarnationId) + if (launchOpts.signal?.aborted) { + throw new Error('client_disconnected') } - throw error - } - this.registerPreAllocatedHandleForPty(result.id, preAllocatedHandle) - if (result.wslDistro) { - this.preparePtyExecutionContext(result.id, result.wslDistro) - } - this.registerPty(result.id, workspace.id, workspace.connectionId, { - tabId, - leafId, - ...(result.incarnationId ? { incarnationId: result.incarnationId } : {}) - }) - const pty = this.getOrCreatePtyWorktreeRecord(result.id) - if (pty) { - if (launchOpts.persistHostSessionBinding) { - pty.runtimeSessionOwned = true + const adoptedBeforeLaunch = await this.ptyController.adoptStablePane?.({ + cols: 120, + rows: 40, + cwd, + connectionId: workspace.connectionId, + worktreeId: workspace.id, + preAllocatedHandle, + tabId, + leafId + }) + const launchToken = launchOpts.launchConfig + ? (launchOpts.launchToken ?? randomUUID()) + : undefined + const baseEnv = { + ...launchOpts.env, + ...(launchToken ? { ORCA_AGENT_LAUNCH_TOKEN: launchToken } : {}) } - if (launchOpts.title) { - const observedAt = this.nextTitleObservationSequence() - pty.title = launchOpts.title - pty.titleUpdatedAt = observedAt - this.setPtyManagementTitleFromObservedTitle(pty, launchOpts.title, observedAt) - } else { - pty.title = null - pty.titleUpdatedAt = null + const claudeAgentTeamsSourceCommand = + launchOpts.claudeAgentTeamsSourceCommand?.trim() || + launchOpts.command?.trim() || + undefined + const claudeAgentTeamsMode = this.store?.getSettings?.().claudeAgentTeamsMode + const effectiveClaudeAgentTeamsMode = inferCapturedClaudeAgentTeamsMode( + launchOpts.launchConfig, + claudeAgentTeamsSourceCommand, + claudeAgentTeamsMode + ) + let agentTeamsPlan: Awaited> | undefined + try { + agentTeamsPlan = adoptedBeforeLaunch + ? undefined + : await buildClaudeAgentTeamsLaunchPlan({ + command: claudeAgentTeamsSourceCommand, + mode: effectiveClaudeAgentTeamsMode, + baseEnv: { + ...process.env, + ...baseEnv + }, + createTeamEnv: (shimDir, shimBin) => + this.claudeAgentTeams.createLaunchEnv({ + leaderHandle: preAllocatedHandle, + baseEnv: { + ...process.env, + ...baseEnv + }, + shimDir, + shimBin + }).env + }) + } catch (error) { + releaseStablePaneCreate?.() + throw error } - pty.tabId = tabId - pty.paneKey = paneKey - pty.launchConfig = effectiveLaunchConfig - ? copySleepingAgentLaunchConfig(effectiveLaunchConfig) - : null - pty.launchToken = launchToken ?? null - pty.launchAgent = launchOpts.launchAgent ?? null - } - const handle = pty ? this.issuePtyHandle(pty) : preAllocatedHandle - if (pty && launchOpts.deferMobileSessionPublish !== true) { - this.publishPtyBackedMobileSessionTerminal(workspace.id, pty, { + const sequencedStartupCommand = + agentTeamsPlan && + claudeAgentTeamsSourceCommand && + launchOpts.command && + claudeAgentTeamsSourceCommand !== launchOpts.command + ? agentTeamsPlan.command + : undefined + const effectiveLaunchConfig = + launchOpts.launchConfig && agentTeamsPlan + ? { + ...launchOpts.launchConfig, + agentCommand: launchOpts.launchConfig.agentCommand + ? effectiveClaudeAgentTeamsMode === 'in-process' || process.platform === 'win32' + ? addClaudeTeammateModeInProcess(launchOpts.launchConfig.agentCommand) + : addClaudeTeammateModeAuto(launchOpts.launchConfig.agentCommand) + : agentTeamsPlan.command, + agentEnv: { + ...launchOpts.launchConfig.agentEnv, + ...agentTeamsPlan.env + } + } + : launchOpts.launchConfig + // Why: setup/agent sequencing wraps the PTY launch in a wait shell before + // Claude Agent Teams runs. Preserve the direct Claude command separately + // so the wrapper can exec the teammate-mode variant after setup completes. + const env = this.buildTerminalWorkspaceEnv( + workspace, + { + ...baseEnv, + ...(sequencedStartupCommand + ? { [SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]: sequencedStartupCommand } + : {}) + }, + paneKey, + tabId, + agentTeamsPlan?.env + ) + const terminalColorQueryReplies = + launchOpts.terminalColorQueryReplies ?? getTerminalViewColorQueryReplyColors() + if (launchOpts.signal?.aborted) { + throw new Error('client_disconnected') + } + const persistHostSessionBinding = + launchOpts.persistHostSessionBinding || + launchOpts.surfaceOwner === false || + this.getAvailableAuthoritativeWindow() === null + let result: Awaited>> + try { + result = await this.ptyController.spawn({ + cols: 120, + rows: 40, + cwd, + command: sequencedStartupCommand + ? launchOpts.command + : (agentTeamsPlan?.command ?? launchOpts.command), + launchAgent: launchOpts.launchAgent, + commandDelivery: 'provider', + startupCommandDelivery: launchOpts.startupCommandDelivery, + env, + envToDelete: mergeTerminalEnvDeletionKeys( + launchOpts.envToDelete, + agentTeamsPlan?.envToDelete + ), + resumeProviderSession: launchOpts.resumeProviderSession, + telemetry: launchOpts.telemetry, + connectionId: workspace.connectionId, + worktreeId: workspace.id, + preAllocatedHandle, + tabId, + leafId, + ...(terminalColorQueryReplies ? { terminalColorQueryReplies } : {}), + ...(launchOpts.agentSessionClaim + ? { + agentSessionEnsure: { + claim: launchOpts.agentSessionClaim, + surface: { + worktreeId: workspace.id, + tabId, + leafId, + terminalHandle: preAllocatedHandle + } + } + } + : {}), + ...(launchOpts.agentSessionCreateOperationId + ? { agentSessionCreateOperationId: launchOpts.agentSessionCreateOperationId } + : {}), + ...(launchOpts.signal ? { signal: launchOpts.signal } : {}), + ...(launchOpts.onPtySpawnCommitted + ? { onPtySpawnCommitted: reportPtySpawnCommitted } + : {}), + ...(adoptedBeforeLaunch ? { adoptedStablePane: adoptedBeforeLaunch } : {}), + ...(launchOpts.sessionId ? { sessionId: launchOpts.sessionId } : {}), + ...(!adoptedBeforeLaunch && launchOpts.isNewSession ? { isNewSession: true } : {}), + // Why: a headless-created pane has no renderer session writer. Persist + // its tab/leaf binding at spawn so a later promoted window reattaches + // the live daemon or SSH PTY instead of replacing it with a fresh one. + // Re-check freshly: the entry-time snapshot can go stale across the + // awaits above if the authoritative window is destroyed mid-spawn. + ...(persistHostSessionBinding ? { persistHostSessionBinding: true } : {}) + }) + } finally { + releaseStablePaneCreate?.() + } + if (!result.stablePaneOwner) { + reportPtySpawnCommitted() + } + const adoptedStablePane = Boolean(result.stablePaneOwner) + if (result.agentSessionEnsure) { + const canonicalSurface = result.agentSessionEnsure.owner.surface + preAllocatedHandle = canonicalSurface.terminalHandle + tabId = canonicalSurface.tabId + leafId = canonicalSurface.leafId + paneKey = makePaneKey(tabId, leafId) + } else if (result.stablePaneOwner) { + preAllocatedHandle = result.stablePaneOwner.handle + tabId = result.stablePaneOwner.tabId + leafId = result.stablePaneOwner.leafId + paneKey = makePaneKey(tabId, leafId) + } + try { + this.assertPtyDidNotExitBeforeRegistration(result.id, result.incarnationId) + } catch (error) { + if (error instanceof Error && error.message === 'agent_session_exited_during_start') { + this.releaseRejectedPtyRegistrationFence(result.id, result.incarnationId) + } + throw error + } + this.registerPreAllocatedHandleForPty(result.id, preAllocatedHandle) + if (result.wslDistro) { + this.preparePtyExecutionContext(result.id, result.wslDistro) + } + this.registerPty(result.id, workspace.id, workspace.connectionId, { tabId, leafId, - title: launchOpts.title ?? null, - activate: presentation === 'focused', - // Why: explicit background presentation may carry legacy activate - // metadata from an already-owned renderer pane; don't select it on mobile. - selectIfNoActiveTab: presentation !== 'background', - ...(launchOpts.viewMode ? { viewMode: launchOpts.viewMode } : {}), - ...(cwd !== workspace.path ? { startupCwd: cwd } : {}) + ...(result.incarnationId ? { incarnationId: result.incarnationId } : {}) }) - } - let surface: RuntimeTerminalCreate['surface'] = 'background' - let warning: string | undefined - if (presentation !== 'background' && this.notifier?.revealTerminalSession) { - try { - // Why: after the PTY is spawned, renderer tab adoption is best-effort; - // failing here must not strand a live process without returning a handle. - // Pass the pre-minted tabId so the renderer adopts under the same id - // already baked into the PTY env — keeps paneKey hook attribution intact. - await this.notifier.revealTerminalSession(workspace.id, { - ptyId: result.id, - title: launchOpts.title ?? null, - ...(cwd !== workspace.path ? { cwd } : {}), - ...(effectiveLaunchConfig ? { launchConfig: effectiveLaunchConfig } : {}), - ...(launchToken ? { launchToken } : {}), - ...(launchOpts.launchAgent ? { launchAgent: launchOpts.launchAgent } : {}), - ...(launchOpts.viewMode ? { viewMode: launchOpts.viewMode } : {}), - activate: presentation === 'focused', - ...(presentation ? { presentation } : {}), - ...ownerSurfacing(opts.surfaceOwner !== false), - tabId, - leafId - }) - surface = 'visible' - } catch (err) { - console.warn(`[terminal-create] failed to create inactive tab for ${result.id}:`, err) - warning = createTerminalRevealWarning(handle, err) + const pty = this.getOrCreatePtyWorktreeRecord(result.id) + if (pty) { + if (persistHostSessionBinding) { + pty.runtimeSessionOwned = true + } + if (!adoptedStablePane) { + if (launchOpts.title) { + const observedAt = this.nextTitleObservationSequence() + pty.title = launchOpts.title + pty.titleUpdatedAt = observedAt + this.setPtyManagementTitleFromObservedTitle(pty, launchOpts.title, observedAt) + } else { + pty.title = null + pty.titleUpdatedAt = null + } + pty.launchConfig = effectiveLaunchConfig + ? copySleepingAgentLaunchConfig(effectiveLaunchConfig) + : null + pty.launchToken = launchToken ?? null + pty.launchAgent = launchOpts.launchAgent ?? null + } + pty.tabId = tabId + pty.paneKey = paneKey } - } else if (presentation !== 'background') { - warning = createTerminalRevealWarning(handle) - } - return { - handle, - tabId, - paneKey, - ptyId: result.id, - worktreeId: workspace.id, - title: launchOpts.title ?? null, - ...this.getPtyExecutionHostMetadata(result.id), - surface, - ...(result.agentSessionEnsure - ? { agentSessionDisposition: result.agentSessionEnsure.disposition } - : {}), - ...(warning ? { warning } : {}) + const handle = pty ? this.issuePtyHandle(pty) : preAllocatedHandle + if (pty && !adoptedStablePane && launchOpts.deferMobileSessionPublish !== true) { + this.publishPtyBackedMobileSessionTerminal(workspace.id, pty, { + tabId, + leafId, + title: launchOpts.title ?? null, + activate: presentation === 'focused', + // Why: explicit background presentation may carry legacy activate + // metadata from an already-owned renderer pane; don't select it on mobile. + selectIfNoActiveTab: presentation !== 'background', + ...(launchOpts.viewMode ? { viewMode: launchOpts.viewMode } : {}), + ...(cwd !== workspace.path ? { startupCwd: cwd } : {}) + }) + } + let surface: RuntimeTerminalCreate['surface'] = 'background' + let warning: string | undefined + if (presentation !== 'background' && this.notifier?.revealTerminalSession) { + try { + // Why: after the PTY is spawned, renderer tab adoption is best-effort; + // failing here must not strand a live process without returning a handle. + // Pass the pre-minted tabId so the renderer adopts under the same id + // already baked into the PTY env — keeps paneKey hook attribution intact. + await this.notifier.revealTerminalSession(workspace.id, { + ptyId: result.id, + title: launchOpts.title ?? null, + ...(cwd !== workspace.path ? { cwd } : {}), + ...(effectiveLaunchConfig ? { launchConfig: effectiveLaunchConfig } : {}), + ...(launchToken ? { launchToken } : {}), + ...(launchOpts.launchAgent ? { launchAgent: launchOpts.launchAgent } : {}), + ...(launchOpts.viewMode ? { viewMode: launchOpts.viewMode } : {}), + activate: presentation === 'focused', + ...(presentation ? { presentation } : {}), + ...ownerSurfacing(opts.surfaceOwner !== false), + tabId, + leafId + }) + surface = 'visible' + } catch (err) { + console.warn(`[terminal-create] failed to create inactive tab for ${result.id}:`, err) + warning = createTerminalRevealWarning(handle, err) + } + } else if (presentation !== 'background') { + warning = createTerminalRevealWarning(handle) + } + return { + handle, + tabId, + paneKey, + ptyId: result.id, + worktreeId: workspace.id, + title: pty?.title ?? launchOpts.title ?? null, + ...this.getPtyExecutionHostMetadata(result.id), + surface, + ...(result.agentSessionEnsure + ? { agentSessionDisposition: result.agentSessionEnsure.disposition } + : {}), + ...(adoptedStablePane ? { isReattach: true as const } : {}), + ...(warning ? { warning } : {}) + } + } finally { + releaseStablePaneCreate() } } @@ -25052,6 +25343,7 @@ export class OrcaRuntimeService { activate: opts.activate !== false, paired: pairedCreate, selectIfNoActiveTab: true, + ...(startupCommand.command ? { startupCommand: startupCommand.command } : {}), ...(opts.viewMode ? { viewMode: opts.viewMode } : {}) }) try { @@ -25064,6 +25356,7 @@ export class OrcaRuntimeService { signal: opts.signal }) if (this.isReadyMobileTerminalSurface(surface)) { + this.deliverPendingStartupCommandToBareRendererPty(worktreeId, reply.tabId) return surface } const readySurface = await this.waitForMobileTerminalSurface(worktreeId, reply.tabId, { @@ -25072,6 +25365,7 @@ export class OrcaRuntimeService { signal: opts.signal }).catch(() => null) if (readySurface) { + this.deliverPendingStartupCommandToBareRendererPty(worktreeId, reply.tabId) return readySurface } if (opts.signal?.aborted) { @@ -25106,6 +25400,7 @@ export class OrcaRuntimeService { if (this.findLiveRegisteredPtyForRendererTab(worktreeId, reply.tabId)) { const rescued = this.ensurePtyBackedMobileSurfaceForRendererTab(worktreeId, reply.tabId) if (rescued) { + this.deliverPendingStartupCommandToBareRendererPty(worktreeId, reply.tabId) return rescued } } @@ -25234,6 +25529,7 @@ export class OrcaRuntimeService { // Why: SshPtyProvider treats sessionId as a relay reattach; only synthesize local serve ids so SSH fresh terminals still call pty.spawn. const stableSessionId = opts.identity?.sessionId ?? (workspace.connectionId ? undefined : `serve-${randomUUID()}`) + const isNewSession = stableSessionId !== undefined && opts.identity?.sessionId === undefined const terminal = await this.createTerminal(`id:${worktreeId}`, { focus: false, command: opts.command, @@ -25253,6 +25549,7 @@ export class OrcaRuntimeService { : stableSessionId ? { sessionId: stableSessionId } : {}), + ...(isNewSession ? { isNewSession: true } : {}), persistHostSessionBinding: true, // Why: this method publishes the authoritative snapshot below; skip the intermediate publish to avoid a wrong-group flash. deferMobileSessionPublish: true, @@ -25583,6 +25880,30 @@ export class OrcaRuntimeService { ) } + // Why: a create can settle over a renderer PTY that spawned without its + // startup command (the create's renderer stalled, #7587), silently binding + // the client to a plain shell under an agent tab forever — once the surface + // is ready, the activation-time materialize recovery (#7837) never runs + // (STA-3214). Spawn commands are recorded per PTY at spawn time, so a + // missing record on the locally registered live PTY proves the launch never + // ran; type it into the shell like the create would have. + private deliverPendingStartupCommandToBareRendererPty(worktreeId: string, tabId: string): void { + const pending = this.pendingMobileTerminalCreatesByKey.get(`${worktreeId}::${tabId}`) + const command = pending?.startupCommand + if (!command) { + return + } + const pty = this.findLiveRegisteredPtyForRendererTab(worktreeId, tabId) + if (!pty || this.terminalSpawnCommandsByPtyId.has(pty.ptyId)) { + return + } + if (this.ptyController?.write(pty.ptyId, command)) { + // Why: Enter rides its own write so a long command cannot swallow it. + this.ptyController.write(pty.ptyId, '\r') + this.noteTerminalSpawnCommand(pty.ptyId, command) + } + } + private waitForTerminalHandle(tabId: string, timeoutMs = 10_000): Promise { const existing = this.resolveHandleForTab(tabId) if (existing) { @@ -25777,38 +26098,158 @@ export class OrcaRuntimeService { handle: string, options: { navigateHost?: boolean } = {} ): Promise { + const navigateHost = options.navigateHost !== false + const livePtyIdentity = (): RuntimeTerminalFocus => { + const live = this.getLivePtyForHandle(handle) + if (!live?.pty.connected) { + throw new Error('terminal_exited') + } + return { + handle, + tabId: live.pty.tabId ?? live.record.tabId, + worktreeId: live.pty.worktreeId, + navigated: false + } + } + const liveLeafIdentity = (): RuntimeTerminalFocus => { + this.assertGraphReady() + const { leaf: current } = this.getLiveLeafForHandle(handle) + return { + handle, + tabId: current.tabId, + worktreeId: current.worktreeId, + navigated: false + } + } + const pty = this.getLivePtyForHandle(handle) if (pty) { if (!pty.pty.connected) { throw new Error('terminal_exited') } - const parsedPaneKey = parsePaneKey(pty.pty.paneKey ?? '') - const revealed = - options.navigateHost === false - ? undefined - : await this.notifier?.revealTerminalSession?.(pty.pty.worktreeId, { - ptyId: pty.pty.ptyId, - title: getLatestPtyTitle(pty.pty), - ...(pty.pty.launchConfig - ? { launchConfig: copySleepingAgentLaunchConfig(pty.pty.launchConfig) } - : {}), - ...(pty.pty.launchToken ? { launchToken: pty.pty.launchToken } : {}), - ...(pty.pty.launchAgent ? { launchAgent: pty.pty.launchAgent } : {}), - ...(pty.pty.tabId !== null ? { tabId: pty.pty.tabId } : {}), - ...(parsedPaneKey ? { leafId: parsedPaneKey.leafId } : {}) - }) - return { - handle, - tabId: revealed?.tabId ?? pty.pty.tabId ?? pty.record.tabId, - worktreeId: pty.pty.worktreeId + if (!navigateHost || !this.notifier?.revealTerminalSession) { + return { + handle, + tabId: pty.pty.tabId ?? pty.record.tabId, + worktreeId: pty.pty.worktreeId, + navigated: false + } } + // Coalesce concurrent host navigations: only the latest full reveal claims navigated. + return this.terminalFocusNavigationCoalescer.run({ + key: handle, + resolveSuperseded: (completed) => + completed ? { ...completed, navigated: false } : livePtyIdentity(), + run: async (ctx) => { + const live = this.getLivePtyForHandle(handle) + if (!live?.pty.connected) { + throw new Error('terminal_exited') + } + if (!ctx.isCurrent()) { + return { + handle, + tabId: live.pty.tabId ?? live.record.tabId, + worktreeId: live.pty.worktreeId, + navigated: false + } + } + const notifier = this.notifier + if (!notifier?.revealTerminalSession) { + return { + handle, + tabId: live.pty.tabId ?? live.record.tabId, + worktreeId: live.pty.worktreeId, + navigated: false + } + } + const parsedPaneKey = parsePaneKey(live.pty.paneKey ?? '') + const revealed = await notifier.revealTerminalSession(live.pty.worktreeId, { + ptyId: live.pty.ptyId, + title: getLatestPtyTitle(live.pty), + ...(live.pty.launchConfig + ? { launchConfig: copySleepingAgentLaunchConfig(live.pty.launchConfig) } + : {}), + ...(live.pty.launchToken ? { launchToken: live.pty.launchToken } : {}), + ...(live.pty.launchAgent ? { launchAgent: live.pty.launchAgent } : {}), + ...(live.pty.tabId !== null ? { tabId: live.pty.tabId } : {}), + ...(parsedPaneKey ? { leafId: parsedPaneKey.leafId } : {}) + }) + if (!ctx.isCurrent() || this.notifier !== notifier) { + return { + handle, + tabId: revealed?.tabId ?? live.pty.tabId ?? live.record.tabId, + worktreeId: live.pty.worktreeId, + navigated: false + } + } + return { + handle, + tabId: revealed?.tabId ?? live.pty.tabId ?? live.record.tabId, + worktreeId: live.pty.worktreeId, + navigated: true + } + } + }) } this.assertGraphReady() const { leaf } = this.getLiveLeafForHandle(handle) - if (options.navigateHost !== false) { - this.notifier?.focusTerminal(leaf.tabId, leaf.worktreeId, leaf.leafId) + if (!navigateHost) { + return { + handle, + tabId: leaf.tabId, + worktreeId: leaf.worktreeId, + navigated: false + } } - return { handle, tabId: leaf.tabId, worktreeId: leaf.worktreeId } + if (!this.notifier?.focusTerminal) { + return { + handle, + tabId: leaf.tabId, + worktreeId: leaf.worktreeId, + navigated: false + } + } + return this.terminalFocusNavigationCoalescer.run({ + key: handle, + resolveSuperseded: (completed) => + completed ? { ...completed, navigated: false } : liveLeafIdentity(), + run: async (ctx) => { + this.assertGraphReady() + const { leaf: liveLeaf } = this.getLiveLeafForHandle(handle) + if (!ctx.isCurrent()) { + return { + handle, + tabId: liveLeaf.tabId, + worktreeId: liveLeaf.worktreeId, + navigated: false + } + } + const notifier = this.notifier + if (!notifier?.focusTerminal) { + return { + handle, + tabId: liveLeaf.tabId, + worktreeId: liveLeaf.worktreeId, + navigated: false + } + } + notifier.focusTerminal(liveLeaf.tabId, liveLeaf.worktreeId, liveLeaf.leafId) + if (!ctx.isCurrent() || this.notifier !== notifier) { + return { + handle, + tabId: liveLeaf.tabId, + worktreeId: liveLeaf.worktreeId, + navigated: false + } + } + return { + handle, + tabId: liveLeaf.tabId, + worktreeId: liveLeaf.worktreeId, + navigated: true + } + } + }) } async closeTerminal(handle: string): Promise { @@ -28509,7 +28950,9 @@ export class OrcaRuntimeService { // Returns the worktrees whose stored snapshot object changed during this // sync, so the caller can fan out only actually-changed worktrees. private syncMobileSessionTabs( - snapshots: RuntimeMobileSessionTabsSnapshot[] | undefined + snapshots: RuntimeMobileSessionTabsSnapshot[] | undefined, + unchangedWorktreeIds?: string[], + resyncWorktreeIds: Set = new Set() ): Set { const changedWorktreeIds = new Set() if (snapshots === undefined) { @@ -28544,6 +28987,38 @@ export class OrcaRuntimeService { }) } const nextWorktrees = new Set() + const incomingWorktreeIds = new Set(snapshots.map((snapshot) => snapshot.worktree)) + // Why: the renderer withholds unchanged snapshots to keep the graph payload + // small, so these worktrees are still live and must not fall into the prune + // below. Ask for a republish when main no longer holds that accepted renderer + // publication or a formerly-preserved runtime tab has gone stale. + for (const worktreeId of unchangedWorktreeIds ?? []) { + const existing = this.mobileSessionTabsByWorktree.get(worktreeId) + const accepted = this.acceptedRendererMobileSnapshotByWorktree.get(worktreeId) + if (existing) { + nextWorktrees.add(worktreeId) + } + if ( + existing && + accepted && + (existing.publicationEpoch === accepted.publicationEpoch || + existing.publicationEpoch.startsWith(`${accepted.publicationEpoch}:headless-merge:`)) && + existing.tabs.length >= accepted.rendererTabCount && + (existing.tabs.length === accepted.rendererTabCount || + !this.storedMobileSnapshotHasStalePreservedTab( + existing, + accepted.rendererTabIdentityKeys + )) + ) { + continue + } + if (!incomingWorktreeIds.has(worktreeId)) { + resyncWorktreeIds.add(worktreeId) + } + // Why: the accept gate compares against the renderer's last accepted pair, + // which outlives the dropped snapshot and would reject the republish. + this.acceptedRendererMobileSnapshotByWorktree.delete(worktreeId) + } for (const snapshot of snapshots) { nextWorktrees.add(snapshot.worktree) const existing = this.mobileSessionTabsByWorktree.get(snapshot.worktree) @@ -28568,7 +29043,7 @@ export class OrcaRuntimeService { !( existing && snapshot.snapshotVersion === accepted.rendererVersion && - this.storedMobileSnapshotHasStalePreservedTab(existing, snapshot) + this.storedMobileSnapshotHasStalePreservedTab(existing, accepted.rendererTabIdentityKeys) ) ) { continue @@ -28592,7 +29067,11 @@ export class OrcaRuntimeService { ) this.acceptedRendererMobileSnapshotByWorktree.set(snapshot.worktree, { publicationEpoch: snapshot.publicationEpoch, - rendererVersion: snapshot.snapshotVersion + rendererVersion: snapshot.snapshotVersion, + rendererTabCount: fencedSnapshot.tabs.length, + rendererTabIdentityKeys: new Set( + fencedSnapshot.tabs.flatMap((tab) => this.getMobileSessionSnapshotTabIdentityKeys(tab)) + ) }) } for (const [worktreeId, existing] of [...this.mobileSessionTabsByWorktree.entries()]) { @@ -28714,22 +29193,19 @@ export class OrcaRuntimeService { } // Why: the accepted-revision no-op gate must not fossilize preserved runtime - // tabs. A stored merged snapshot's tabs that are absent from the incoming - // renderer publication exist only via preservation; if any such tab no longer + // tabs. A stored merged snapshot's tabs absent from the accepted renderer + // publication exist only via preservation; if any such tab no longer // passes the preservation predicate (binding removed from the live PTY table - // and persisted session, or browser page closed), the stored snapshot is - // stale even though the renderer revision is unchanged. + // and persisted session, or browser page closed), the stored snapshot is stale. private storedMobileSnapshotHasStalePreservedTab( existing: RuntimeMobileSessionTabsSnapshot, - incoming: RuntimeMobileSessionTabsSnapshot + rendererTabIdentityKeys: ReadonlySet ): boolean { - const incomingIds = new Set( - incoming.tabs.flatMap((tab) => this.getMobileSessionSnapshotTabIdentityKeys(tab)) - ) return existing.tabs.some( (tab) => - !this.getMobileSessionSnapshotTabIdentityKeys(tab).some((id) => incomingIds.has(id)) && - !this.shouldPreserveHeadlessMobileSessionTab(existing, tab) + !this.getMobileSessionSnapshotTabIdentityKeys(tab).some((id) => + rendererTabIdentityKeys.has(id) + ) && !this.shouldPreserveHeadlessMobileSessionTab(existing, tab) ) } @@ -29564,11 +30040,13 @@ export class OrcaRuntimeService { return undefined } const contexts: Record = {} + const queriedHandles = new Set() for (const leaf of this.leaves.values()) { if (!leaf.ptyId) { continue } const handle = this.issueHandle(leaf) + queriedHandles.add(handle) const context = this.getAgentStatusOrchestrationContextForHandle(handle, db) if (context) { contexts[this.makeRuntimePaneKey(leaf)] = context @@ -29579,6 +30057,10 @@ export class OrcaRuntimeService { continue } const handle = this.issuePtyHandle(pty) + if (queriedHandles.has(handle)) { + continue + } + queriedHandles.add(handle) const context = this.getAgentStatusOrchestrationContextForHandle(handle, db) if (context) { contexts[pty.paneKey] = context @@ -29598,7 +30080,7 @@ export class OrcaRuntimeService { if (!dispatch) { return undefined } - const task = db?.getTask?.(dispatch.task_id) + const task = db?.getTask?.(dispatch.task_id, dispatch.run_id) const display = typeof task?.spec === 'string' ? buildOrchestrationTaskDisplayMetadata({ @@ -29607,15 +30089,68 @@ export class OrcaRuntimeService { displayName: task.display_name }) : { taskTitle: '', displayName: '' } - const activeRun = - dispatch.status === 'pending' || dispatch.status === 'dispatched' + const owningRun = + task?.run_id && task.run_id === dispatch.run_id ? db?.getRun?.(dispatch.run_id) : undefined + const runCoordinatorHandle = owningRun?.coordinator_handle ?? undefined + const legacyActiveRun = + owningRun?.legacy === 1 && (dispatch.status === 'pending' || dispatch.status === 'dispatched') ? db?.getActiveCoordinatorRun?.() : undefined + // Why: legacy coordinator runs have no durable task ownership, so fail closed across worktrees. + const handleWorktreeId = legacyActiveRun ? this.getWorktreeIdForTerminalHandle(handle) : null + const legacyCoordinatorWorktreeId = legacyActiveRun + ? this.getWorktreeIdForTerminalHandle(legacyActiveRun.coordinator_handle) + : null + const scopedLegacyActiveRun = + legacyActiveRun && + handleWorktreeId && + legacyCoordinatorWorktreeId && + runtimeWorktreeIdsEqual(legacyCoordinatorWorktreeId, handleWorktreeId) + ? legacyActiveRun + : undefined + const coordinatorHandle = runCoordinatorHandle ?? scopedLegacyActiveRun?.coordinator_handle + const orchestrationRunId = owningRun?.legacy === 0 ? owningRun.id : scopedLegacyActiveRun?.id + const creatorPaneKey = task?.created_by_pane_key + const creatorPaneHandle = creatorPaneKey + ? this.getTerminalHandleForPaneKey(creatorPaneKey) + : null + const creatorAuthority = creatorPaneHandle + ? this.getOrchestrationDispatchAuthority(creatorPaneHandle) + : null + const storedCreatorPane = creatorPaneKey ? parsePaneKey(creatorPaneKey) : null + const currentCreatorPane = creatorAuthority?.paneKey + ? parsePaneKey(creatorAuthority.paneKey) + : null + const sameCreatorPane = Boolean( + creatorPaneKey && + creatorAuthority?.paneKey && + (creatorPaneKey === creatorAuthority.paneKey || + (storedCreatorPane && + currentCreatorPane && + storedCreatorPane.leafId === currentCreatorPane.leafId)) + ) + const paneRun = creatorPaneKey ? db?.getCurrentRunForPane?.(creatorPaneKey) : undefined + const sameRunCreatorDispatch = Boolean( + task?.creator_dispatch_id && + task.creator_dispatch_run_id === owningRun?.id && + task.creator_dispatch_pane_key && + task.creator_dispatch_process_incarnation === task.created_by_process_incarnation && + parsePaneKey(task.creator_dispatch_pane_key)?.leafId === storedCreatorPane?.leafId + ) + const currentCreatorHandle = + owningRun?.legacy === 0 && + task?.created_by_run_generation === owningRun.consumer_generation && + task.created_by_process_incarnation === creatorAuthority?.processIncarnation && + sameCreatorPane && + (paneRun + ? paneRun.id === owningRun.id && + paneRun.consumer_generation === task.created_by_run_generation + : sameRunCreatorDispatch) + ? (creatorPaneHandle ?? undefined) + : undefined const parentTerminalHandle = - task?.created_by_terminal_handle ?? - (activeRun?.coordinator_handle && activeRun.coordinator_handle !== handle - ? activeRun.coordinator_handle - : undefined) + currentCreatorHandle ?? + (coordinatorHandle && coordinatorHandle !== handle ? coordinatorHandle : undefined) const parentPaneKey = parentTerminalHandle ? this.getPaneKeyForTerminalHandle(parentTerminalHandle) : undefined @@ -29628,8 +30163,8 @@ export class OrcaRuntimeService { ...(display.displayName ? { displayName: display.displayName } : {}), ...(parentTerminalHandle ? { parentTerminalHandle } : {}), ...(parentPaneKey ? { parentPaneKey } : {}), - ...(activeRun?.coordinator_handle ? { coordinatorHandle: activeRun.coordinator_handle } : {}), - ...(activeRun?.id ? { orchestrationRunId: activeRun.id } : {}) + ...(coordinatorHandle ? { coordinatorHandle } : {}), + ...(orchestrationRunId ? { orchestrationRunId } : {}) } } @@ -29682,10 +30217,21 @@ export class OrcaRuntimeService { return pty } leafPty = pty ?? null + for (const candidate of this.leaves.values()) { + if (candidate.leafId !== parsed.leafId || !candidate.ptyId) { + continue + } + const remintedPty = this.ptysById.get(candidate.ptyId) + if (remintedPty?.connected) { + return remintedPty + } + leafPty ??= remintedPty ?? null + } } let newestMatch: RuntimePtyWorktreeRecord | null = null for (const pty of this.ptysById.values()) { - if (pty.paneKey === paneKey) { + const ptyPane = parsePaneKey(pty.paneKey ?? '') + if (pty.paneKey === paneKey || (parsed && ptyPane && parsed.leafId === ptyPane.leafId)) { if (pty.connected) { return pty } @@ -29710,6 +30256,18 @@ export class OrcaRuntimeService { return makePaneKey(record.tabId, record.leafId) } + private getWorktreeIdForTerminalHandle(handle: string): string | null { + const livePty = this.getLivePtyForHandle(handle) + if (livePty?.pty.worktreeId) { + return livePty.pty.worktreeId + } + const record = this.handles.get(handle) + if (!record || record.runtimeId !== this.runtimeId) { + return null + } + return record.worktreeId + } + private setPtyManagementTitleFromObservedTitle( pty: RuntimePtyWorktreeRecord, title: string | null | undefined, diff --git a/src/main/runtime/orchestration/coordinator.test.ts b/src/main/runtime/orchestration/coordinator.test.ts index 31e9180c93e..cbb3c3f8011 100644 --- a/src/main/runtime/orchestration/coordinator.test.ts +++ b/src/main/runtime/orchestration/coordinator.test.ts @@ -177,6 +177,42 @@ describe('Coordinator', () => { }) expect(db.getDispatchContext(task.id)?.assignee_pane_key).toBe('tab_a:leaf_a') + expect(db.getDispatchContext(task.id)?.process_incarnation).toBeNull() + + insertWorkerDone(db, { taskId: task.id }) + await runPromise + }) + + it('records authenticated process authority for automatic dispatch', async () => { + db = new OrchestrationDb(':memory:') + const runtime = createMockRuntime() + runtime.terminals = [{ handle: 'term_a', worktreeId: 'wt1', connected: true, writable: true }] + const withAuthority = Object.assign(runtime, { + getOrchestrationDispatchAuthority: (handle: string) => + handle === 'term_a' + ? { + paneKey: 'tab_a:leaf_a', + processIncarnation: 'pty_a:incarnation-a', + launchTokenHash: 'launch-token-hash' + } + : null + }) + const task = db.createTask({ spec: 'implement feature' }) + const coordinator = new Coordinator(db, withAuthority, { + spec: 'build it', + coordinatorHandle: 'coord', + pollIntervalMs: 50 + }) + const runPromise = coordinator.run() + await new Promise((r) => { + setTimeout(r, 100) + }) + + expect(db.getDispatchContext(task.id)).toMatchObject({ + assignee_pane_key: 'tab_a:leaf_a', + process_incarnation: 'pty_a:incarnation-a', + launch_token_hash: 'launch-token-hash' + }) insertWorkerDone(db, { taskId: task.id }) await runPromise diff --git a/src/main/runtime/orchestration/coordinator.ts b/src/main/runtime/orchestration/coordinator.ts index 7fcd5288f5d..df69ed9ef7b 100644 --- a/src/main/runtime/orchestration/coordinator.ts +++ b/src/main/runtime/orchestration/coordinator.ts @@ -26,8 +26,14 @@ export type CoordinatorRuntime = { behind: number recentSubjects: string[] } | null> - // Why: optional so lightweight runtime fakes keep compiling; when present, dispatch records the assignee's remint-stable pane identity. + // Why: pane-only fallback preserves reservation identity for lightweight runtime fakes. getTerminalPaneKey?(handle: string): string | null + // Why: automatic dispatch persists the same authenticated pane/process tuple as manual dispatch. + getOrchestrationDispatchAuthority?(handle: string): { + paneKey: string | null + processIncarnation: string | null + launchTokenHash: string | null + } | null // Why: Windows can host native and WSL workers at once, so the worker pane (not the coordinator) picks the packaged CLI name. getTerminalOrchestrationCliCommand?(handle: string): 'orca' | 'orca-ide' } @@ -419,10 +425,19 @@ export class Coordinator { } } + const dispatchAuthority = this.runtime.getOrchestrationDispatchAuthority?.(targetHandle) + const assigneePaneKey = + dispatchAuthority?.paneKey ?? this.runtime.getTerminalPaneKey?.(targetHandle) ?? undefined + const processIncarnation = + dispatchAuthority?.paneKey && dispatchAuthority.processIncarnation + ? dispatchAuthority.processIncarnation + : undefined const dispatch = this.db.createDispatchContext( task.id, targetHandle, - this.runtime.getTerminalPaneKey?.(targetHandle) ?? undefined + assigneePaneKey, + dispatchAuthority?.launchTokenHash ?? undefined, + processIncarnation ) // Why: dispatched agents use orca-dev in dev mode to reach the dev runtime's socket, not production (Section 6.4). diff --git a/src/main/runtime/orchestration/db.ts b/src/main/runtime/orchestration/db.ts index ddaeb172a72..3608ee7d754 100644 --- a/src/main/runtime/orchestration/db.ts +++ b/src/main/runtime/orchestration/db.ts @@ -42,6 +42,15 @@ import { ORCHESTRATION_LEGACY_RUN_ID } from '../../../shared/orchestration-rpc-c import { parsePaneKey } from '../../../shared/stable-pane-id' import { OrchestrationError } from './orchestration-error' import { resolveOrchestrationMigrationStartVersion } from './orchestration-schema-version-skew' +import { + deriveWorkerTerminalListState, + type WorkerTerminalResourceRow, + type WorkerTerminalArchiveRow, + type WorkerTerminalArchiveStatus, + type WorkerTerminalListState, + type WorkerTerminalOwnershipState, + type WorkerTerminalRetainedReason +} from './worker-terminal-ownership' import { ORCHESTRATION_RUN_PAGE_LIMIT } from '../../../shared/orchestration-run-pagination' import { ORCHESTRATION_CONTRACT_VERSION } from '../../../shared/protocol-version' @@ -57,8 +66,10 @@ function isEquivalentPaneKey(a: string, b: string): boolean { // Why: indexable pre-filter for isEquivalentPaneKey — equal strings and equal leaves both share the // text after the first ':', so this narrows candidates without deciding equivalence itself. -const PANE_KEY_MATCH_SUFFIX_SQL = +const RUN_PANE_KEY_MATCH_SUFFIX_SQL = "substr(coordinator_pane_key, instr(coordinator_pane_key, ':') + 1)" +const DISPATCH_PANE_KEY_MATCH_SUFFIX_SQL = + "substr(assignee_pane_key, instr(assignee_pane_key, ':') + 1)" function paneKeyMatchSuffix(paneKey: string): string { const colon = paneKey.indexOf(':') @@ -254,13 +265,20 @@ export type RunListPage = { nextCursor: string | null } +export type TaskRuntimeLineageRow = TaskRow & { + creator_dispatch_id: string | null + creator_dispatch_run_id: string | null + creator_dispatch_pane_key: string | null + creator_dispatch_process_incarnation: string | null +} + type RunListCursor = { createdAt: string id: string } -// Schema versions: v2 'heartbeat'+last_heartbeat_at, v3 delivered_at, v4 task-creator terminal, v5 task_title/display_name, v6 pane identity, v7 lightweight Runs, v8 crash-safe Run deliveries, v9 durable question threads, v10 Dispatch capabilities, v11 durable mutation receipts, v12 composed worker state, v18 post-v6 version-skew repair, v19 adopted legacy Runs and compatibility receipts, v20 legacy question backfill, v21 legacy scheduler-loss provenance, v22 dispatch assignee lookup. -const SCHEMA_VERSION = 22 +// Schema versions: v2 'heartbeat'+last_heartbeat_at, v3 delivered_at, v4 task-creator terminal, v5 task_title/display_name, v6 pane identity, v7 lightweight Runs, v8 crash-safe Run deliveries, v9 durable question threads, v10 Dispatch capabilities, v11 durable mutation receipts, v12 composed worker state, v18 post-v6 version-skew repair, v19 adopted legacy Runs and compatibility receipts, v20 legacy question backfill, v21 legacy scheduler-loss provenance, v22 dispatch assignee lookup, v23 worker terminal resource ownership, v24 creator-incarnation authority, v25 active Dispatch handle lookup. +const SCHEMA_VERSION = 25 function hardenOrchestrationDatabaseFiles(dbPath: string | ':memory:'): void { if (dbPath === ':memory:' || process.platform === 'win32') { @@ -387,6 +405,51 @@ export class OrchestrationDb { updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); + CREATE TABLE IF NOT EXISTS worker_terminal_resources ( + id TEXT PRIMARY KEY, + origin_dispatch_id TEXT NOT NULL, + owner_dispatch_id TEXT NOT NULL, + prior_owner_dispatch_ids TEXT NOT NULL DEFAULT '[]', + worktree_id TEXT, + terminal_handle TEXT NOT NULL, + pane_key TEXT, + process_incarnation TEXT, + host_scope TEXT, + ownership_state TEXT NOT NULL DEFAULT 'owned' + CHECK(ownership_state IN ('owned', 'transferred', 'user_owned', 'external', 'released')), + release_state TEXT NOT NULL DEFAULT 'not_requested' + CHECK(release_state IN ( + 'not_requested', 'retained', 'requested', 'releasing', 'released', 'unknown' + )), + retained_reason TEXT, + release_requested_at TEXT, + release_completed_at TEXT, + release_error TEXT, + archive_source TEXT, + archive_status TEXT, + created_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_at TEXT NOT NULL DEFAULT (datetime('now')) + ); + + CREATE UNIQUE INDEX IF NOT EXISTS idx_worker_terminal_resources_owner + ON worker_terminal_resources(owner_dispatch_id); + CREATE INDEX IF NOT EXISTS idx_worker_terminal_resources_handle + ON worker_terminal_resources(terminal_handle); + CREATE INDEX IF NOT EXISTS idx_worker_terminal_resources_pane + ON worker_terminal_resources(pane_key); + CREATE INDEX IF NOT EXISTS idx_worker_terminal_resources_identity + ON worker_terminal_resources(process_incarnation, host_scope); + CREATE INDEX IF NOT EXISTS idx_worker_terminal_resources_release + ON worker_terminal_resources(release_state); + + CREATE TABLE IF NOT EXISTS worker_terminal_archives ( + dispatch_id TEXT PRIMARY KEY, + resource_id TEXT NOT NULL, + kind TEXT NOT NULL CHECK(kind IN ('transcript_pin', 'terminal_tail')), + content TEXT NOT NULL, + created_at TEXT NOT NULL DEFAULT (datetime('now')) + ); + CREATE TABLE IF NOT EXISTS federated_dispatches ( dispatch_id TEXT PRIMARY KEY, environment_id TEXT NOT NULL, @@ -463,6 +526,9 @@ export class OrchestrationDb { run_id TEXT NOT NULL DEFAULT '${LEGACY_RUN_ID}', parent_id TEXT, created_by_terminal_handle TEXT, + created_by_pane_key TEXT, + created_by_process_incarnation TEXT, + created_by_run_generation INTEGER, task_title TEXT, display_name TEXT, spec TEXT NOT NULL, @@ -522,7 +588,7 @@ export class OrchestrationDb { CREATE INDEX IF NOT EXISTS idx_gates_status ON decision_gates(status); CREATE INDEX IF NOT EXISTS idx_runs_coordinator_pane_leaf - ON runs(${PANE_KEY_MATCH_SUFFIX_SQL}) + ON runs(${RUN_PANE_KEY_MATCH_SUFFIX_SQL}) WHERE coordinator_pane_key IS NOT NULL; CREATE TABLE IF NOT EXISTS coordinator_runs ( @@ -892,6 +958,32 @@ export class OrchestrationDb { ON dispatch_contexts(assignee_handle); `) } + if (current < 23) { + this.backfillWorkerTerminalResources() + } + if (current < 24) { + if (!this.hasColumn('tasks', 'created_by_pane_key')) { + this.db.exec('ALTER TABLE tasks ADD COLUMN created_by_pane_key TEXT') + } + if (!this.hasColumn('tasks', 'created_by_process_incarnation')) { + this.db.exec('ALTER TABLE tasks ADD COLUMN created_by_process_incarnation TEXT') + } + if (!this.hasColumn('tasks', 'created_by_run_generation')) { + this.db.exec('ALTER TABLE tasks ADD COLUMN created_by_run_generation INTEGER') + } + } + if (current < 25) { + this.db.exec(` + CREATE INDEX IF NOT EXISTS idx_dispatch_active_assignee_handle + ON dispatch_contexts(assignee_handle) + WHERE assignee_handle IS NOT NULL AND status IN ('pending', 'dispatched'); + `) + } + this.db.exec(` + CREATE INDEX IF NOT EXISTS idx_dispatch_assignee_pane_leaf + ON dispatch_contexts(${DISPATCH_PANE_KEY_MATCH_SUFFIX_SQL}) + WHERE assignee_pane_key IS NOT NULL AND status IN ('pending', 'dispatched'); + `) this.createUndeliveredInboxIndexIfPossible() this.db.pragma(`user_version = ${SCHEMA_VERSION}`) @@ -2366,7 +2458,7 @@ export class OrchestrationDb { .prepare( `SELECT * FROM runs WHERE coordinator_pane_key IS NOT NULL AND legacy = 0 - AND ${PANE_KEY_MATCH_SUFFIX_SQL} = ? + AND ${RUN_PANE_KEY_MATCH_SUFFIX_SQL} = ? ORDER BY rowid` ) .all(paneKeyMatchSuffix(paneKey)) as RunRow[] @@ -3686,6 +3778,9 @@ export class OrchestrationDb { deps?: string[] parentId?: string createdByTerminalHandle?: string + createdByPaneKey?: string + createdByProcessIncarnation?: string + createdByRunGeneration?: number runId?: string }): TaskRow { const runId = task.runId ?? LEGACY_RUN_ID @@ -3713,13 +3808,20 @@ export class OrchestrationDb { }) this.db .prepare( - 'INSERT INTO tasks (id, run_id, parent_id, created_by_terminal_handle, task_title, display_name, spec, status, deps) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' + `INSERT INTO tasks ( + id, run_id, parent_id, created_by_terminal_handle, created_by_pane_key, + created_by_process_incarnation, created_by_run_generation, + task_title, display_name, spec, status, deps + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` ) .run( id, runId, task.parentId ?? null, task.createdByTerminalHandle ?? null, + task.createdByPaneKey ?? null, + task.createdByProcessIncarnation ?? null, + task.createdByRunGeneration ?? null, display.taskTitle || null, display.displayName || null, task.spec, @@ -3729,8 +3831,33 @@ export class OrchestrationDb { return this.db.prepare('SELECT * FROM tasks WHERE id = ?').get(id) as TaskRow } - getTask(id: string): TaskRow | undefined { - return this.db.prepare('SELECT * FROM tasks WHERE id = ?').get(id) as TaskRow | undefined + // Why: return the active creator Dispatch proof with the Task read; runtime still owns pane/process currency. + getTask(id: string): TaskRow | undefined + getTask(id: string, dispatchRunId: string): TaskRuntimeLineageRow | undefined + getTask(id: string, dispatchRunId?: string): TaskRow | TaskRuntimeLineageRow | undefined { + if (dispatchRunId === undefined) { + return this.db.prepare('SELECT * FROM tasks WHERE id = ?').get(id) as TaskRow | undefined + } + return this.db + .prepare( + `SELECT t.*, + creator.id AS creator_dispatch_id, + creator.run_id AS creator_dispatch_run_id, + creator.assignee_pane_key AS creator_dispatch_pane_key, + creator.process_incarnation AS creator_dispatch_process_incarnation + FROM tasks t + LEFT JOIN dispatch_contexts creator ON creator.rowid = ( + SELECT candidate.rowid + FROM dispatch_contexts candidate + WHERE candidate.assignee_handle = t.created_by_terminal_handle + AND candidate.run_id = ? + AND candidate.status IN ('pending', 'dispatched') + ORDER BY candidate.rowid DESC + LIMIT 1 + ) + WHERE t.id = ?` + ) + .get(dispatchRunId, id) as TaskRuntimeLineageRow | undefined } listTasks(filter?: { status?: TaskStatus; ready?: boolean; runId?: string }): TaskRow[] { @@ -4054,6 +4181,11 @@ export class OrchestrationDb { worktreeId: string effects: unknown[] setupState: string + hostScope?: string | null + // 'created': this worker-start operation created the agent terminal (including agent-first + // worktree creation, whose effects receipt says 'reused_agent_terminal'). 'external': an + // explicit --terminal reuse; ownership transfers only from an exact owned settled resource. + terminalOwnership?: 'created' | 'external' }): string { const dispatch = this.getDispatchContextById(params.dispatchId) const worker = this.getWorkerDispatch(params.dispatchId) @@ -4116,6 +4248,46 @@ export class OrchestrationDb { ), params.dispatchId ) + if (params.terminalOwnership && !this.getWorkerTerminalResourceByOwner(params.dispatchId)) { + if (params.terminalOwnership === 'created') { + this.createWorkerTerminalResourceStatement({ + dispatchId: params.dispatchId, + worktreeId: params.worktreeId, + terminalHandle: params.handle, + paneKey: params.paneKey, + processIncarnation: params.processIncarnation, + hostScope: params.hostScope, + ownership: 'owned' + }) + } else { + const transferable = this.findTransferableWorkerTerminalResource({ + terminalHandle: params.handle, + paneKey: params.paneKey, + processIncarnation: params.processIncarnation, + hostScope: params.hostScope ?? null + }) + if (transferable) { + this.transferWorkerTerminalResourceStatement({ + resourceId: transferable.id, + toDispatchId: params.dispatchId, + terminalHandle: params.handle, + paneKey: params.paneKey, + processIncarnation: params.processIncarnation, + hostScope: params.hostScope ?? null + }) + } else { + this.createWorkerTerminalResourceStatement({ + dispatchId: params.dispatchId, + worktreeId: params.worktreeId, + terminalHandle: params.handle, + paneKey: params.paneKey, + processIncarnation: params.processIncarnation, + hostScope: params.hostScope, + ownership: 'external' + }) + } + } + } this.db.exec('COMMIT') return capability } catch (error) { @@ -5419,12 +5591,575 @@ export class OrchestrationDb { } } + // --- Worker terminal resources (schema v23) --------------------------------------------------- + + // Historical renderer input and reuse cannot be proven, so pre-v23 terminals stay external. + private backfillWorkerTerminalResources(): void { + const rows = this.db + .prepare( + `SELECT w.dispatch_id, w.worktree_id, w.agent_terminal_handle, + d.assignee_pane_key, d.process_incarnation + FROM worker_dispatches w + JOIN dispatch_contexts d ON d.id = w.dispatch_id + WHERE w.agent_terminal_handle IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM federated_dispatches f WHERE f.dispatch_id = w.dispatch_id) + AND NOT EXISTS ( + SELECT 1 FROM worker_terminal_resources r WHERE r.owner_dispatch_id = w.dispatch_id + )` + ) + .all() as { + dispatch_id: string + worktree_id: string | null + agent_terminal_handle: string + assignee_pane_key: string | null + process_incarnation: string | null + }[] + const insert = this.db.prepare( + `INSERT INTO worker_terminal_resources ( + id, origin_dispatch_id, owner_dispatch_id, worktree_id, terminal_handle, + pane_key, process_incarnation, ownership_state, release_state, retained_reason + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` + ) + for (const row of rows) { + insert.run( + generateId('wtr'), + row.dispatch_id, + row.dispatch_id, + row.worktree_id, + row.agent_terminal_handle, + row.assignee_pane_key, + row.process_incarnation, + 'external', + 'retained', + 'legacy_ambiguous' + ) + } + } + + // No transaction: composes inside worker-start's authority transaction. + createWorkerTerminalResourceStatement(params: { + dispatchId: string + worktreeId: string | null + terminalHandle: string + paneKey: string | null + processIncarnation: string | null + hostScope?: string | null + ownership: Extract + }): WorkerTerminalResourceRow { + const id = generateId('wtr') + this.db + .prepare( + `INSERT INTO worker_terminal_resources ( + id, origin_dispatch_id, owner_dispatch_id, worktree_id, terminal_handle, + pane_key, process_incarnation, host_scope, ownership_state, release_state, + retained_reason + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'not_requested', ?)` + ) + .run( + id, + params.dispatchId, + params.dispatchId, + params.worktreeId, + params.terminalHandle, + params.paneKey, + params.processIncarnation, + params.hostScope ?? null, + params.ownership, + params.ownership === 'external' ? 'external_terminal' : null + ) + return this.getWorkerTerminalResource(id) as WorkerTerminalResourceRow + } + + getWorkerTerminalResource(id: string): WorkerTerminalResourceRow | undefined { + return this.db.prepare('SELECT * FROM worker_terminal_resources WHERE id = ?').get(id) as + | WorkerTerminalResourceRow + | undefined + } + + getWorkerTerminalResourceByOwner(dispatchId: string): WorkerTerminalResourceRow | undefined { + return this.db + .prepare('SELECT * FROM worker_terminal_resources WHERE owner_dispatch_id = ?') + .get(dispatchId) as WorkerTerminalResourceRow | undefined + } + + getWorkerTerminalResourceFormerlyOwnedBy( + dispatchId: string + ): WorkerTerminalResourceRow | undefined { + return this.db + .prepare( + `SELECT * FROM worker_terminal_resources + WHERE prior_owner_dispatch_ids LIKE ? + ORDER BY updated_at DESC LIMIT 1` + ) + .get(`%"${dispatchId}"%`) as WorkerTerminalResourceRow | undefined + } + + // Reusable exact settled terminal: transfers cleanup ownership to the new Dispatch and fences + // release through the old owner. No transaction: composes inside the authority transaction. + transferWorkerTerminalResourceStatement(params: { + resourceId: string + toDispatchId: string + terminalHandle: string + paneKey: string + processIncarnation: string + hostScope: string | null + }): WorkerTerminalResourceRow { + const resource = this.getWorkerTerminalResource(params.resourceId) + if (!resource) { + throw new OrchestrationError( + 'dispatch_not_found', + `Worker terminal resource ${params.resourceId} was not found.` + ) + } + const priorOwners = JSON.parse(resource.prior_owner_dispatch_ids) as string[] + priorOwners.push(resource.owner_dispatch_id) + this.db + .prepare( + `UPDATE worker_terminal_resources + SET owner_dispatch_id = ?, prior_owner_dispatch_ids = ?, release_state = 'not_requested', + retained_reason = NULL, release_requested_at = NULL, release_completed_at = NULL, + release_error = NULL, terminal_handle = ?, pane_key = ?, process_incarnation = ?, + host_scope = ?, updated_at = datetime('now') + WHERE id = ? AND ownership_state = 'owned'` + ) + .run( + params.toDispatchId, + JSON.stringify(priorOwners), + params.terminalHandle, + params.paneKey, + params.processIncarnation, + params.hostScope, + params.resourceId + ) + return this.getWorkerTerminalResource(params.resourceId) as WorkerTerminalResourceRow + } + + // Finds an owned, settled, exact-match resource for an explicitly reused terminal. + findTransferableWorkerTerminalResource(params: { + terminalHandle: string + paneKey: string | null + processIncarnation: string | null + hostScope: string | null + }): WorkerTerminalResourceRow | undefined { + if (!params.paneKey || !params.processIncarnation) { + return undefined + } + const candidates = this.db + .prepare( + `SELECT r.* FROM worker_terminal_resources r + JOIN worker_dispatches w ON w.dispatch_id = r.owner_dispatch_id + WHERE r.process_incarnation = ? AND r.host_scope IS ? + AND r.ownership_state != 'released'` + ) + .all(params.processIncarnation, params.hostScope) as WorkerTerminalResourceRow[] + const exact = candidates.filter( + (candidate) => + candidate.pane_key && + params.paneKey && + isEquivalentPaneKey(candidate.pane_key, params.paneKey) && + candidate.process_incarnation === params.processIncarnation && + candidate.host_scope === params.hostScope + ) + if ( + exact.some((candidate) => + ['requested', 'releasing', 'unknown'].includes(candidate.release_state) + ) + ) { + throw new OrchestrationError( + 'terminal_release_in_progress', + `Terminal ${params.terminalHandle} has a release in progress; wait for cleanup or use another terminal.` + ) + } + return exact.find( + (candidate) => + candidate.ownership_state === 'owned' && + ['not_requested', 'retained'].includes(candidate.release_state) && + ['succeeded', 'failed', 'stopped', 'abandoned'].includes( + this.getWorkerDispatch(candidate.owner_dispatch_id)?.state ?? '' + ) + ) + } + + workerTerminalResourceHasIdentityConflict(resourceId: string): boolean { + const resource = this.getWorkerTerminalResource(resourceId) + if (!resource?.pane_key || !resource.process_incarnation) { + return true + } + const candidates = this.db + .prepare( + `SELECT * FROM worker_terminal_resources + WHERE process_incarnation = ? AND host_scope IS ? + AND id != ? AND ownership_state != 'released'` + ) + .all( + resource.process_incarnation, + resource.host_scope, + resource.id + ) as WorkerTerminalResourceRow[] + return candidates.some( + (candidate) => + candidate.pane_key && + isEquivalentPaneKey(candidate.pane_key, resource.pane_key as string) && + candidate.process_incarnation === resource.process_incarnation && + candidate.host_scope === resource.host_scope + ) + } + + requestWorkerTerminalRelease(dispatchId: string): + | { disposition: 'requested'; resource: WorkerTerminalResourceRow } + | { disposition: 'already_released'; resource: WorkerTerminalResourceRow } + | { + disposition: 'retained' + resource: WorkerTerminalResourceRow | null + reason: WorkerTerminalRetainedReason + } { + this.db.exec('BEGIN IMMEDIATE') + try { + const worker = this.getWorkerDispatch(dispatchId) + if (!worker) { + throw new OrchestrationError('dispatch_not_found', `Dispatch ${dispatchId} was not found.`) + } + if (!['succeeded', 'failed'].includes(worker.state)) { + // Why: release is post-completion cleanup only; recording intent for an unsettled or + // uncertain worker would let recovery close a terminal the coordinator never reviewed. + throw new OrchestrationError( + 'dispatch_inactive', + `Dispatch ${dispatchId} is ${worker.state}; only a succeeded or failed worker can release. Use worker-stop to cancel an active worker.` + ) + } + const resource = this.getWorkerTerminalResourceByOwner(dispatchId) + if (!resource) { + const transferred = this.getWorkerTerminalResourceFormerlyOwnedBy(dispatchId) + this.db.exec('COMMIT') + return transferred + ? { disposition: 'retained', resource: transferred, reason: 'ownership_transferred' } + : { disposition: 'retained', resource: null, reason: 'no_owned_resource' } + } + if (resource.release_state === 'released' || resource.ownership_state === 'released') { + this.db.exec('COMMIT') + return { disposition: 'already_released', resource } + } + if (resource.ownership_state === 'external') { + this.db.exec('COMMIT') + return { + disposition: 'retained', + resource, + reason: (resource.retained_reason as WorkerTerminalRetainedReason) ?? 'external_terminal' + } + } + if (resource.ownership_state === 'user_owned') { + this.db.exec('COMMIT') + return { disposition: 'retained', resource, reason: 'user_takeover' } + } + if (resource.ownership_state === 'transferred') { + this.db.exec('COMMIT') + return { disposition: 'retained', resource, reason: 'ownership_transferred' } + } + if ( + resource.release_state === 'unknown' || + (resource.release_state === 'retained' && resource.retained_reason === 'user_requested') + ) { + this.db + .prepare('DELETE FROM worker_terminal_archives WHERE dispatch_id = ?') + .run(dispatchId) + } + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = CASE + WHEN release_state = 'releasing' THEN 'releasing' + ELSE 'requested' + END, + retained_reason = NULL, + release_requested_at = COALESCE(release_requested_at, datetime('now')), + release_error = NULL, updated_at = datetime('now') + WHERE id = ? AND release_state IN ('not_requested', 'retained', 'requested', 'releasing', 'unknown')` + ) + .run(resource.id) + this.db.exec('COMMIT') + return { + disposition: 'requested', + resource: this.getWorkerTerminalResource(resource.id) as WorkerTerminalResourceRow + } + } catch (error) { + this.db.exec('ROLLBACK') + throw error + } + } + + storeWorkerTerminalArchive(params: { + dispatchId: string + resourceId: string + kind: 'transcript_pin' | 'terminal_tail' + content: string + }): void { + this.db + .prepare( + `INSERT INTO worker_terminal_archives (dispatch_id, resource_id, kind, content) + VALUES (?, ?, ?, ?) + ON CONFLICT(dispatch_id) DO UPDATE SET + resource_id = excluded.resource_id, kind = excluded.kind, content = excluded.content` + ) + .run(params.dispatchId, params.resourceId, params.kind, params.content) + } + + commitWorkerTerminalArchiveForRelease(params: { + dispatchId: string + resourceId: string + kind?: 'transcript_pin' | 'terminal_tail' + content?: string + archiveSource: 'transcript' | 'terminal' + archiveStatus: Extract + }): WorkerTerminalResourceRow { + this.db.exec('BEGIN IMMEDIATE') + try { + const resource = this.getWorkerTerminalResource(params.resourceId) + if ( + resource?.owner_dispatch_id === params.dispatchId && + resource.ownership_state === 'owned' && + resource.release_state === 'requested' + ) { + if (params.kind && params.content !== undefined) { + this.storeWorkerTerminalArchive({ + dispatchId: params.dispatchId, + resourceId: params.resourceId, + kind: params.kind, + content: params.content + }) + } + const archive = this.getWorkerTerminalArchive(params.dispatchId) + if (!archive || archive.resource_id !== params.resourceId) { + throw new OrchestrationError( + 'archive_failed', + `Output could not be preserved for Dispatch ${params.dispatchId}; the terminal was retained.` + ) + } + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = 'releasing', archive_source = ?, archive_status = ?, + updated_at = datetime('now') + WHERE id = ? AND owner_dispatch_id = ? AND ownership_state = 'owned' + AND release_state = 'requested'` + ) + .run(params.archiveSource, params.archiveStatus, params.resourceId, params.dispatchId) + } + const updated = this.getWorkerTerminalResource(params.resourceId) as WorkerTerminalResourceRow + this.db.exec('COMMIT') + return updated + } catch (error) { + this.db.exec('ROLLBACK') + throw error + } + } + + getWorkerTerminalArchive(dispatchId: string): WorkerTerminalArchiveRow | undefined { + return this.db + .prepare('SELECT * FROM worker_terminal_archives WHERE dispatch_id = ?') + .get(dispatchId) as WorkerTerminalArchiveRow | undefined + } + + settleWorkerTerminalRelease(resourceId: string): WorkerTerminalResourceRow { + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = 'released', ownership_state = 'released', + release_completed_at = datetime('now'), release_error = NULL, + updated_at = datetime('now') + WHERE id = ? AND release_state IN ('requested', 'releasing', 'unknown')` + ) + .run(resourceId) + return this.getWorkerTerminalResource(resourceId) as WorkerTerminalResourceRow + } + + markWorkerTerminalReleaseUnknown(resourceId: string, reason: string): WorkerTerminalResourceRow { + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = 'unknown', release_error = ?, updated_at = datetime('now') + WHERE id = ? AND release_state IN ('requested', 'releasing')` + ) + .run(reason, resourceId) + return this.getWorkerTerminalResource(resourceId) as WorkerTerminalResourceRow + } + + revertWorkerTerminalReleaseToRetained( + resourceId: string, + reason: WorkerTerminalRetainedReason + ): WorkerTerminalResourceRow { + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = 'retained', retained_reason = ?, updated_at = datetime('now') + WHERE id = ? AND release_state IN ('requested', 'releasing')` + ) + .run(reason, resourceId) + return this.getWorkerTerminalResource(resourceId) as WorkerTerminalResourceRow + } + + retainWorkerTerminalResource( + dispatchId: string + ): + | { disposition: 'retained'; resource: WorkerTerminalResourceRow } + | { disposition: 'already_released'; resource: WorkerTerminalResourceRow } + | { disposition: 'release_committed'; resource: WorkerTerminalResourceRow } + | { disposition: 'no_owned_resource'; resource: null } { + this.db.exec('BEGIN IMMEDIATE') + try { + const resource = this.getWorkerTerminalResourceByOwner(dispatchId) + if (!resource) { + this.db.exec('COMMIT') + return { disposition: 'no_owned_resource', resource: null } + } + if (resource.release_state === 'released') { + this.db.exec('COMMIT') + return { disposition: 'already_released', resource } + } + this.db + .prepare( + `UPDATE worker_terminal_resources + SET release_state = 'retained', retained_reason = 'user_requested', + updated_at = datetime('now') + WHERE id = ? AND release_state IN ('not_requested', 'retained', 'requested')` + ) + .run(resource.id) + const updated = this.getWorkerTerminalResource(resource.id) as WorkerTerminalResourceRow + if (updated.release_state !== 'retained') { + this.db.exec('COMMIT') + return { disposition: 'release_committed', resource: updated } + } + this.db.prepare('DELETE FROM worker_terminal_archives WHERE dispatch_id = ?').run(dispatchId) + this.db.exec('COMMIT') + return { disposition: 'retained', resource: updated } + } catch (error) { + this.db.exec('ROLLBACK') + throw error + } + } + + // Real user input relinquishes orchestration ownership durably; programmatic prompt delivery, + // query auto-replies, resize, and output never reach this path. + markWorkerTerminalUserOwned(paneKey: string): number { + this.db.exec('BEGIN IMMEDIATE') + try { + const exact = this.db + .prepare( + `SELECT id, owner_dispatch_id, pane_key FROM worker_terminal_resources + WHERE pane_key = ? AND ownership_state = 'owned' + AND release_state IN ('not_requested', 'retained', 'requested')` + ) + .all(paneKey) as { id: string; owner_dispatch_id: string; pane_key: string }[] + const candidates = + exact.length > 0 + ? exact + : ( + this.db + .prepare( + `SELECT id, owner_dispatch_id, pane_key FROM worker_terminal_resources + WHERE ownership_state = 'owned' + AND release_state IN ('not_requested', 'retained', 'requested') + AND pane_key IS NOT NULL` + ) + .all() as { id: string; owner_dispatch_id: string; pane_key: string }[] + ).filter((candidate) => isEquivalentPaneKey(candidate.pane_key, paneKey)) + const update = this.db.prepare( + `UPDATE worker_terminal_resources + SET ownership_state = 'user_owned', release_state = 'retained', + retained_reason = 'user_takeover', updated_at = datetime('now') + WHERE id = ? AND ownership_state = 'owned' + AND release_state IN ('not_requested', 'retained', 'requested')` + ) + let changed = 0 + for (const candidate of candidates) { + const result = Number(update.run(candidate.id).changes) + if (result > 0) { + this.db + .prepare('DELETE FROM worker_terminal_archives WHERE dispatch_id = ?') + .run(candidate.owner_dispatch_id) + changed += result + } + } + this.db.exec('COMMIT') + return changed + } catch (error) { + this.db.exec('ROLLBACK') + throw error + } + } + + listWorkerTerminalReleaseBacklog(): WorkerTerminalResourceRow[] { + return this.db + .prepare( + `SELECT * FROM worker_terminal_resources + WHERE release_state IN ('requested', 'releasing') + ORDER BY release_requested_at ASC` + ) + .all() as WorkerTerminalResourceRow[] + } + + listWorkerTerminalResources(params: { runId?: string } = {}): { + dispatchId: string + taskId: string + runId: string + workerState: WorkerDispatchState + dispatchStatus: DispatchStatus + agentTerminalHandle: string | null + terminalState: WorkerTerminalListState | null + resource: WorkerTerminalResourceRow | null + }[] { + const rows = this.db + .prepare( + `SELECT w.dispatch_id, w.state AS worker_state, w.agent_terminal_handle, + d.task_id, d.run_id, d.status AS dispatch_status + FROM worker_dispatches w + JOIN dispatch_contexts d ON d.id = w.dispatch_id + ${params.runId ? 'WHERE d.run_id = ?' : ''} + ORDER BY w.created_at ASC` + ) + .all(...(params.runId ? [params.runId] : [])) as { + dispatch_id: string + worker_state: WorkerDispatchState + agent_terminal_handle: string | null + task_id: string + run_id: string + dispatch_status: DispatchStatus + }[] + const resources = this.db + .prepare( + `SELECT r.* FROM worker_terminal_resources r + JOIN dispatch_contexts d ON d.id = r.owner_dispatch_id + ${params.runId ? 'WHERE d.run_id = ?' : ''}` + ) + .all(...(params.runId ? [params.runId] : [])) as WorkerTerminalResourceRow[] + const resourceByOwner = new Map( + resources.map((resource) => [resource.owner_dispatch_id, resource]) + ) + return rows.map((row) => { + const resource = resourceByOwner.get(row.dispatch_id) ?? null + return { + dispatchId: row.dispatch_id, + taskId: row.task_id, + runId: row.run_id, + workerState: row.worker_state, + dispatchStatus: row.dispatch_status, + agentTerminalHandle: row.agent_terminal_handle, + terminalState: deriveWorkerTerminalListState({ + workerState: row.worker_state, + agentTerminalHandle: row.agent_terminal_handle, + resource + }), + resource + } + }) + } + createDispatchContext( taskId: string, assigneeHandle: string, // Why: pane key is the remint-stable identity behind the handle — lets worker_done ownership survive handle reissue. assigneePaneKey?: string, - launchTokenHash?: string + launchTokenHash?: string, + processIncarnation?: string ): DispatchContextRow { const task = this.getTask(taskId) if (!task) { @@ -5454,8 +6189,9 @@ export class OrchestrationDb { .prepare( `INSERT INTO dispatch_contexts ( id, run_id, task_id, contract_version, launch_token_hash, - assignee_handle, assignee_pane_key, status, failure_count, dispatched_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, 'dispatched', ?, datetime('now'))` + assignee_handle, assignee_pane_key, process_incarnation, + status, failure_count, dispatched_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'dispatched', ?, datetime('now'))` ) .run( id, @@ -5465,6 +6201,7 @@ export class OrchestrationDb { launchTokenHash ?? null, assigneeHandle, assigneePaneKey ?? null, + processIncarnation ?? null, priorFailures ) this.hasAnyDispatchContextsCache = true @@ -5636,9 +6373,12 @@ export class OrchestrationDb { const actives = this.db .prepare( - "SELECT * FROM dispatch_contexts WHERE assignee_pane_key IS NOT NULL AND status IN ('pending', 'dispatched')" + `SELECT * FROM dispatch_contexts + WHERE assignee_pane_key IS NOT NULL + AND status IN ('pending', 'dispatched') + AND ${DISPATCH_PANE_KEY_MATCH_SUFFIX_SQL} = ?` ) - .all() as DispatchContextRow[] + .all(paneKeyMatchSuffix(assigneePaneKey)) as DispatchContextRow[] for (const row of actives) { if (row.assignee_pane_key && isEquivalentPaneKey(row.assignee_pane_key, assigneePaneKey)) { @@ -6016,6 +6756,8 @@ export class OrchestrationDb { DELETE FROM federation_relay_items; DELETE FROM remote_dispatch_attachments; DELETE FROM federated_dispatches; + DELETE FROM worker_terminal_archives; + DELETE FROM worker_terminal_resources; DELETE FROM worker_dispatches; DELETE FROM dispatch_contexts; DELETE FROM tasks; @@ -6040,6 +6782,8 @@ export class OrchestrationDb { DELETE FROM federation_relay_items; DELETE FROM remote_dispatch_attachments; DELETE FROM federated_dispatches; + DELETE FROM worker_terminal_archives; + DELETE FROM worker_terminal_resources; DELETE FROM worker_dispatches; DELETE FROM dispatch_contexts; DELETE FROM tasks; diff --git a/src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts b/src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts new file mode 100644 index 00000000000..d13344004c3 --- /dev/null +++ b/src/main/runtime/orchestration/orchestration-creator-authority-performance.test.ts @@ -0,0 +1,156 @@ +import { afterEach, describe, expect, it } from 'vitest' +import type Database from '../../sqlite/sync-database' +import { OrchestrationDb } from './db' + +const CREATOR_PANE = 'tab-creator:11111111-1111-4111-8111-111111111111' +const CREATOR_PROCESS = 'pty-creator:incarnation-a' + +function sqliteFor(db: OrchestrationDb): Database.Database { + return (db as unknown as { db: Database.Database }).db +} + +describe('creator authority lookup performance', () => { + let db: OrchestrationDb | undefined + + afterEach(() => db?.close()) + + it('uses bounded creator-handle and pane-leaf indexes', () => { + db = new OrchestrationDb(':memory:') + const sqlite = sqliteFor(db) + const taskPlan = sqlite + .prepare( + `EXPLAIN QUERY PLAN + SELECT t.*, creator.id + FROM tasks t + LEFT JOIN dispatch_contexts creator ON creator.rowid = ( + SELECT candidate.rowid + FROM dispatch_contexts candidate + WHERE candidate.assignee_handle = t.created_by_terminal_handle + AND candidate.run_id = ? + AND candidate.status IN ('pending', 'dispatched') + ORDER BY candidate.rowid DESC LIMIT 1 + ) + WHERE t.id = ?` + ) + .all('run-owner', 'task-worker') as { detail: string }[] + const panePlan = sqlite + .prepare( + `EXPLAIN QUERY PLAN + SELECT * FROM dispatch_contexts + WHERE assignee_pane_key IS NOT NULL + AND status IN ('pending', 'dispatched') + AND substr(assignee_pane_key, instr(assignee_pane_key, ':') + 1) = ?` + ) + .all('11111111-1111-4111-8111-111111111111') as { detail: string }[] + const taskDetails = taskPlan.map((row) => row.detail).join(' | ') + const paneDetails = panePlan.map((row) => row.detail).join(' | ') + + expect(taskDetails).toContain('idx_dispatch_active_assignee_handle') + expect(taskDetails).not.toMatch(/SCAN (?:runs|rebound)/) + expect(paneDetails).toContain('idx_dispatch_assignee_pane_leaf') + }) + + it('keeps 300 Task reads bounded with 50,000 retained Runs', () => { + db = new OrchestrationDb(':memory:') + const run = db.createRun({ + objective: 'owner', + coordinatorHandle: 'term-coordinator', + coordinatorPaneKey: 'tab-coordinator:22222222-2222-4222-8222-222222222222' + }) + const creatorTask = db.createTask({ spec: 'creator', runId: run.id }) + db.createDispatchContext( + creatorTask.id, + 'term-creator', + CREATOR_PANE, + undefined, + CREATOR_PROCESS + ) + const workerTask = db.createTask({ + spec: 'worker', + runId: run.id, + createdByTerminalHandle: 'term-creator', + createdByPaneKey: CREATOR_PANE, + createdByProcessIncarnation: CREATOR_PROCESS, + createdByRunGeneration: run.consumer_generation + }) + sqliteFor(db) + .prepare( + `WITH RECURSIVE run_numbers(value) AS ( + VALUES (1) UNION ALL SELECT value + 1 FROM run_numbers WHERE value < ? + ) + INSERT INTO runs (id, objective, coordinator_handle, consumer_generation, legacy) + SELECT printf('retained_%05d', value), 'retained', printf('term_%05d', value), 1, 0 + FROM run_numbers` + ) + .run(50_000) + + for (let index = 0; index < 10; index += 1) { + db.getTask(workerTask.id, run.id) + } + const startedAt = performance.now() + for (let index = 0; index < 300; index += 1) { + expect(db.getTask(workerTask.id, run.id)?.creator_dispatch_run_id).toBe(run.id) + } + const elapsedMs = performance.now() - startedAt + + expect(elapsedMs).toBeLessThan(200) + }) + + it.each([20_000, 50_000])( + 'keeps active creator lookup bounded with %i retained same-handle Dispatches', + (retainedDispatchCount) => { + db = new OrchestrationDb(':memory:') + const run = db.createRun({ + objective: 'owner', + coordinatorHandle: 'term-coordinator', + coordinatorPaneKey: 'tab-coordinator:22222222-2222-4222-8222-222222222222' + }) + sqliteFor(db) + .prepare( + `WITH RECURSIVE dispatch_numbers(value) AS ( + VALUES (1) UNION ALL SELECT value + 1 FROM dispatch_numbers WHERE value < ? + ) + INSERT INTO dispatch_contexts ( + id, run_id, task_id, assignee_handle, status, completed_at + ) + SELECT printf('retained_ctx_%05d', value), ?, printf('retained_task_%05d', value), + 'term-creator', 'completed', datetime('now') + FROM dispatch_numbers` + ) + .run(retainedDispatchCount, run.id) + const creatorTask = db.createTask({ spec: 'creator', runId: run.id }) + const creatorDispatch = db.createDispatchContext( + creatorTask.id, + 'term-creator', + CREATOR_PANE, + undefined, + CREATOR_PROCESS + ) + const workerTask = db.createTask({ + spec: 'worker', + runId: run.id, + createdByTerminalHandle: 'term-creator', + createdByPaneKey: CREATOR_PANE, + createdByProcessIncarnation: CREATOR_PROCESS, + createdByRunGeneration: run.consumer_generation + }) + + for (let index = 0; index < 10; index += 1) { + db.getTask(workerTask.id, run.id) + db.getActiveDispatchForTerminal('term-creator') + } + const startedAt = performance.now() + for (let index = 0; index < 300; index += 1) { + expect(db.getTask(workerTask.id, run.id)?.creator_dispatch_id).toBe(creatorDispatch.id) + expect(db.getActiveDispatchForTerminal('term-creator')?.id).toBe(creatorDispatch.id) + } + const elapsedMs = performance.now() - startedAt + + const competingTask = db.createTask({ spec: 'competing creator', runId: run.id }) + expect(() => db!.createDispatchContext(competingTask.id, 'term-creator')).toThrow( + `Terminal term-creator already has an active dispatch (${creatorDispatch.id}` + ) + expect(elapsedMs).toBeLessThan(200) + } + ) +}) diff --git a/src/main/runtime/orchestration/orchestration-db-retention-pagination.test.ts b/src/main/runtime/orchestration/orchestration-db-retention-pagination.test.ts index 914321e0646..8cb0547ee27 100644 --- a/src/main/runtime/orchestration/orchestration-db-retention-pagination.test.ts +++ b/src/main/runtime/orchestration/orchestration-db-retention-pagination.test.ts @@ -218,7 +218,7 @@ describe('OrchestrationDb dispatch assignee index migration', () => { } }) - it('migrates a populated v21 database idempotently', () => { + it('migrates a populated upstream v23 database idempotently', () => { tempDir = mkdtempSync(join(tmpdir(), 'orca-dispatch-index-migration-')) const dbPath = join(tempDir, 'orchestration.db') db = new OrchestrationDb(dbPath) @@ -228,14 +228,25 @@ describe('OrchestrationDb dispatch assignee index migration', () => { db = undefined const oldDb = new Database(dbPath) - oldDb.exec('DROP INDEX IF EXISTS idx_dispatch_assignee_handle') - oldDb.pragma('user_version = 21') + oldDb.exec(` + DROP INDEX IF EXISTS idx_dispatch_active_assignee_handle; + DROP INDEX IF EXISTS idx_dispatch_assignee_pane_leaf; + ALTER TABLE tasks DROP COLUMN created_by_pane_key; + ALTER TABLE tasks DROP COLUMN created_by_process_incarnation; + ALTER TABLE tasks DROP COLUMN created_by_run_generation; + `) + oldDb.pragma('user_version = 23') oldDb.close() db = new OrchestrationDb(dbPath) const sqlite = sqliteFor(db) - expect(sqlite.pragma('user_version', { simple: true })).toBe(22) + expect(sqlite.pragma('user_version', { simple: true })).toBe(25) expect(db.getDispatchContextById(dispatch.id)).toMatchObject({ assignee_handle: 'term_worker' }) + expect(db.getTask(task.id)).toMatchObject({ + created_by_pane_key: null, + created_by_process_incarnation: null, + created_by_run_generation: null + }) expect( sqlite .prepare("SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?") @@ -249,12 +260,75 @@ describe('OrchestrationDb dispatch assignee index migration', () => { ) .all('term_worker') as { detail: string }[] expect(plan.map((row) => row.detail).join('\n')).toContain( - 'USING INDEX idx_dispatch_assignee_handle' + 'USING INDEX idx_dispatch_active_assignee_handle' ) + expect( + sqlite + .prepare("SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ?") + .get('idx_dispatch_active_assignee_handle') + ).toMatchObject({ + sql: expect.stringContaining("status IN ('pending', 'dispatched')") + }) + expect( + sqlite + .prepare("SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?") + .get('idx_dispatch_assignee_pane_leaf') + ).toBeDefined() db.close() db = new OrchestrationDb(dbPath) - expect(sqliteFor(db).pragma('user_version', { simple: true })).toBe(22) + expect(sqliteFor(db).pragma('user_version', { simple: true })).toBe(25) expect(db.getDispatchContextById(dispatch.id)).toBeDefined() }) + + it('adds the active-handle index to a populated v24 database idempotently', () => { + tempDir = mkdtempSync(join(tmpdir(), 'orca-active-dispatch-index-migration-')) + const dbPath = join(tempDir, 'orchestration.db') + db = new OrchestrationDb(dbPath) + const run = db.createRun({ + objective: 'retained v24 authority', + coordinatorHandle: 'term_coord', + coordinatorPaneKey: 'tab_coord:leaf_coord' + }) + const task = db.createTask({ + spec: 'indexed lookup', + runId: run.id, + createdByTerminalHandle: 'term_creator', + createdByPaneKey: 'tab_creator:leaf_creator', + createdByProcessIncarnation: 'pty_creator:incarnation-a', + createdByRunGeneration: run.consumer_generation + }) + const dispatch = db.createDispatchContext(task.id, 'term_worker') + db.close() + db = undefined + + const oldDb = new Database(dbPath) + oldDb.exec('DROP INDEX IF EXISTS idx_dispatch_active_assignee_handle') + oldDb.pragma('user_version = 24') + oldDb.close() + + db = new OrchestrationDb(dbPath) + const sqlite = sqliteFor(db) + expect(sqlite.pragma('user_version', { simple: true })).toBe(25) + expect(db.getTask(task.id)).toMatchObject({ + created_by_pane_key: 'tab_creator:leaf_creator', + created_by_process_incarnation: 'pty_creator:incarnation-a', + created_by_run_generation: 1 + }) + expect(db.getDispatchContextById(dispatch.id)).toMatchObject({ + assignee_handle: 'term_worker' + }) + expect( + sqlite + .prepare("SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ?") + .get('idx_dispatch_active_assignee_handle') + ).toMatchObject({ + sql: expect.stringContaining('assignee_handle IS NOT NULL') + }) + + db.close() + db = new OrchestrationDb(dbPath) + expect(sqliteFor(db).pragma('user_version', { simple: true })).toBe(25) + expect(db.getTask(task.id)?.created_by_process_incarnation).toBe('pty_creator:incarnation-a') + }) }) diff --git a/src/main/runtime/orchestration/setup-completion-signal.test.ts b/src/main/runtime/orchestration/setup-completion-signal.test.ts index 0f2b3976f1e..baa5af51cf3 100644 --- a/src/main/runtime/orchestration/setup-completion-signal.test.ts +++ b/src/main/runtime/orchestration/setup-completion-signal.test.ts @@ -41,6 +41,29 @@ describe('orchestration setup completion signal', () => { expect(command).toContain('exit "$status"') }) + it('routes a WSL-launched Windows-drive runner through its /mnt mount', () => { + const { command } = buildObservedSetupCommand( + 'C:\\repo\\.git\\orca\\setup-runner.sh', + 'windows', + 'token-mnt', + { family: 'posix', executable: 'wsl.exe' } + ) + + expect(command).toContain('bash /mnt/c/repo/.git/orca/setup-runner.sh') + expect(command).not.toContain('bash /c/repo') + }) + + it('keeps a Git Bash runner on the MSYS drive form', () => { + const { command } = buildObservedSetupCommand( + 'C:\\repo\\.git\\orca\\setup-runner.sh', + 'windows', + 'token-git-bash', + { family: 'posix' } + ) + + expect(command).toContain('bash /c/repo/.git/orca/setup-runner.sh') + }) + it('recognizes one completion signal across output chunk boundaries', () => { const onComplete = vi.fn() const scanner = createSetupCompletionScanner('token-chunks', onComplete) diff --git a/src/main/runtime/orchestration/setup-completion-signal.ts b/src/main/runtime/orchestration/setup-completion-signal.ts index 17819c12a0c..23e22008387 100644 --- a/src/main/runtime/orchestration/setup-completion-signal.ts +++ b/src/main/runtime/orchestration/setup-completion-signal.ts @@ -1,6 +1,7 @@ import { resolveSetupRunnerCommand, - type SetupRunnerCommandPlatform + type SetupRunnerCommandPlatform, + type SetupRunnerShell } from '../../../shared/setup-runner-command' const SETUP_COMPLETION_PREFIX = '__ORCA_SETUP_COMPLETE__:' @@ -10,9 +11,12 @@ const WINDOWS_SETUP_RUNNER_ENV = 'ORCA_SETUP_RUNNER_PATH' export function buildObservedSetupCommand( runnerScriptPath: string, platform: SetupRunnerCommandPlatform, - completionToken: string + completionToken: string, + // Why: the observed command must reuse the shell the runner was written for, or a + // WSL-routed Windows-drive runner gets Git Bash `/c/...` instead of `/mnt/c/...`. + shell?: SetupRunnerShell ): { command: string; env?: Record } { - const resolution = resolveSetupRunnerCommand(runnerScriptPath, platform) + const resolution = resolveSetupRunnerCommand(runnerScriptPath, platform, shell) if (resolution.shell === 'windows') { const script = [ `$runner = $env:${WINDOWS_SETUP_RUNNER_ENV}`, diff --git a/src/main/runtime/orchestration/types.ts b/src/main/runtime/orchestration/types.ts index 76b3d536fe8..e399b13ce49 100644 --- a/src/main/runtime/orchestration/types.ts +++ b/src/main/runtime/orchestration/types.ts @@ -246,6 +246,9 @@ export type TaskRow = { run_id: string parent_id: string | null created_by_terminal_handle: string | null + created_by_pane_key: string | null + created_by_process_incarnation: string | null + created_by_run_generation: number | null task_title: string | null display_name: string | null spec: string diff --git a/src/main/runtime/orchestration/worker-output-archive.ts b/src/main/runtime/orchestration/worker-output-archive.ts new file mode 100644 index 00000000000..c6fe9970feb --- /dev/null +++ b/src/main/runtime/orchestration/worker-output-archive.ts @@ -0,0 +1,132 @@ +import type { AgentType, NativeChatMessage } from '../../../shared/native-chat-types' +import type { OrcaRuntimeService } from '../orca-runtime' +import { OrchestrationError } from './orchestration-error' +import { + MAX_WORKER_TRANSCRIPT_MESSAGE_LIMIT, + redactWorkerTerminalLines +} from './worker-transcript-payload' +import { readWorkerTranscript } from './worker-transcript-read' + +// Bound the durable copy of raw terminal output; the tail end is the evidence that matters. +const TERMINAL_ARCHIVE_MAX_CHARS = 262_144 + +export type WorkerTranscriptPinArchive = { + agent: AgentType + providerSessionKey: string + providerSessionId: string + transcriptPath: string | null + processIncarnation: string + observedAfter: number + endOffset?: number +} + +export type WorkerTranscriptSnapshotArchive = { + version: 2 + agent: AgentType + processIncarnation: string + messages: NativeChatMessage[] + limited: boolean + warnings: string[] +} + +export type WorkerTerminalTailArchive = { + lines: string[] + truncated: boolean + terminalStatus: string + warnings: string[] +} + +export type WorkerOutputArchiveCapture = + | { + kind: 'transcript_pin' + content: WorkerTranscriptSnapshotArchive + status: 'captured' + } + | { kind: 'terminal_tail'; content: WorkerTerminalTailArchive; status: 'captured' | 'empty' } + +// Freezes an inspectable output source before the live PTY is closed. Prefers the exact +// hook-reported provider transcript; falls back to bounded redacted terminal output. Throws +// typed archive_failed so release retains the live terminal when no evidence can be preserved. +export async function captureWorkerOutputArchive(args: { + runtime: OrcaRuntimeService + dispatchId: string + terminalHandle: string + attachedAtMs: number +}): Promise { + const session = args.runtime.getExactWorkerProviderSession(args.terminalHandle, args.attachedAtMs) + if (session) { + const snapshot = await readWorkerTranscript({ + agent: session.agent, + sessionId: session.providerSession.id, + transcriptPath: session.providerSession.transcriptPath, + limit: MAX_WORKER_TRANSCRIPT_MESSAGE_LIMIT + }).catch(() => null) + if (snapshot?.ok && snapshot.messages.length > 0) { + return { + kind: 'transcript_pin', + status: 'captured', + content: { + version: 2, + agent: session.agent, + processIncarnation: session.processIncarnation, + messages: snapshot.messages, + limited: snapshot.limited, + warnings: snapshot.warnings + } + } + } + } + let terminal + try { + terminal = await args.runtime.readTerminal(args.terminalHandle, {}) + } catch (error) { + throw new OrchestrationError( + 'archive_failed', + `Output could not be preserved for Dispatch ${args.dispatchId}; the terminal was retained. ${error instanceof Error ? error.message : String(error)}` + ) + } + const redacted = redactWorkerTerminalLines(terminal.tail) + const bounded = boundArchiveLines(redacted.lines) + // Why: an exited PTY zeroes its tail immediately, so an empty capture is a distinct receipt, + // not silent success — worker-read must be able to say why nothing is there. + const empty = bounded.lines.every((line) => line.trim() === '') + return { + kind: 'terminal_tail', + status: empty ? 'empty' : 'captured', + content: { + lines: bounded.lines, + truncated: terminal.truncated || bounded.truncated, + terminalStatus: terminal.status, + warnings: empty + ? [ + ...redacted.warnings, + 'The live terminal buffer was empty at release; structured transcript output was unavailable.' + ] + : redacted.warnings + } + } +} + +function boundArchiveLines(lines: string[]): { lines: string[]; truncated: boolean } { + let total = 0 + for (const line of lines) { + total += line.length + 1 + } + if (total <= TERMINAL_ARCHIVE_MAX_CHARS) { + return { lines, truncated: false } + } + const kept: string[] = [] + let budget = TERMINAL_ARCHIVE_MAX_CHARS + for (let index = lines.length - 1; index >= 0; index -= 1) { + const cost = lines[index].length + 1 + if (cost > budget) { + if (kept.length === 0 && budget > 1) { + kept.unshift(lines[index].slice(-(budget - 1))) + } + break + } + kept.unshift(lines[index]) + budget -= cost + } + return { lines: kept, truncated: true } +} diff --git a/src/main/runtime/orchestration/worker-terminal-ownership.ts b/src/main/runtime/orchestration/worker-terminal-ownership.ts new file mode 100644 index 00000000000..d6f160cda4a --- /dev/null +++ b/src/main/runtime/orchestration/worker-terminal-ownership.ts @@ -0,0 +1,134 @@ +import type { WorkerDispatchState } from './types' + +export type WorkerTerminalOwnershipState = + | 'owned' + | 'transferred' + | 'user_owned' + | 'external' + | 'released' + +export type WorkerTerminalReleaseState = + | 'not_requested' + | 'retained' + | 'requested' + | 'releasing' + | 'released' + | 'unknown' + +export type WorkerTerminalRetainedReason = + | 'external_terminal' + | 'ownership_transferred' + | 'user_takeover' + | 'user_requested' + | 'no_owned_resource' + | 'identity_unproven' + | 'legacy_ambiguous' + | 'federation_unsupported' + +export type WorkerTerminalArchiveStatus = 'captured' | 'empty' | 'unavailable' + +export type WorkerTerminalResourceRow = { + id: string + origin_dispatch_id: string + owner_dispatch_id: string + prior_owner_dispatch_ids: string + worktree_id: string | null + terminal_handle: string + pane_key: string | null + process_incarnation: string | null + host_scope: string | null + ownership_state: WorkerTerminalOwnershipState + release_state: WorkerTerminalReleaseState + retained_reason: string | null + release_requested_at: string | null + release_completed_at: string | null + release_error: string | null + archive_source: string | null + archive_status: WorkerTerminalArchiveStatus | null + created_at: string + updated_at: string +} + +// Terminal state exposed by worker-list; process accounting, never Task/Dispatch outcome. +export type WorkerTerminalListState = + | 'active' + | 'reclaimable' + | 'retained' + | 'release_pending' + | 'release_unknown' + | 'released' + +export type WorkerTerminalArchiveRow = { + dispatch_id: string + resource_id: string + kind: 'transcript_pin' | 'terminal_tail' + content: string + created_at: string +} + +export const WORKER_SETTLED_STATES: readonly WorkerDispatchState[] = [ + 'succeeded', + 'failed', + 'stopped', + 'abandoned' +] + +export const WORKER_RELEASABLE_STATES: readonly WorkerDispatchState[] = ['succeeded', 'failed'] + +// Same-operation creation evidence: worker-start labels its own agent terminal 'created' +// (existing worktree) or 'reused_agent_terminal' (agent-first worktree creation). An explicit +// --terminal reuse is labeled 'reused' and never claims ownership. +export function residualResourcesClaimAgentTerminal( + residualResourcesJson: string, + terminalHandle: string +): boolean { + let parsed: unknown + try { + parsed = JSON.parse(residualResourcesJson) + } catch { + return false + } + if (!Array.isArray(parsed)) { + return false + } + return parsed.some((effect) => { + if (!effect || typeof effect !== 'object') { + return false + } + const candidate = effect as { kind?: unknown; role?: unknown; action?: unknown; id?: unknown } + return ( + candidate.kind === 'terminal' && + candidate.role === 'agent' && + candidate.id === terminalHandle && + (candidate.action === 'created' || candidate.action === 'reused_agent_terminal') + ) + }) +} + +// Process accounting for worker-list; deliberately independent of Task/Dispatch outcome. +export function deriveWorkerTerminalListState(params: { + workerState: WorkerDispatchState + agentTerminalHandle: string | null + resource: WorkerTerminalResourceRow | null +}): WorkerTerminalListState | null { + const { resource } = params + if (!resource) { + return params.agentTerminalHandle ? 'retained' : null + } + if (resource.release_state === 'released') { + return 'released' + } + if (resource.release_state === 'unknown') { + return 'release_unknown' + } + if (resource.release_state === 'requested' || resource.release_state === 'releasing') { + return 'release_pending' + } + if (resource.ownership_state !== 'owned' || resource.release_state === 'retained') { + return 'retained' + } + if (WORKER_RELEASABLE_STATES.includes(params.workerState)) { + return 'reclaimable' + } + return WORKER_SETTLED_STATES.includes(params.workerState) ? 'retained' : 'active' +} diff --git a/src/main/runtime/orchestration/worker-terminal-release-reconciliation.ts b/src/main/runtime/orchestration/worker-terminal-release-reconciliation.ts new file mode 100644 index 00000000000..86a10ed06de --- /dev/null +++ b/src/main/runtime/orchestration/worker-terminal-release-reconciliation.ts @@ -0,0 +1,101 @@ +import type { OrcaRuntimeService } from '../orca-runtime' +import { completeWorkerTerminalRelease } from '../rpc/methods/orchestration-worker-release-completion' + +export type WorkerTerminalReleaseReconciliationResult = { + attempted: number + released: number + pending: number + unknown: number + retained: number +} + +type ActiveReconciliation = { + rerunRequested: boolean + promise?: Promise +} + +const activeReconciliationByRuntime = new WeakMap() + +// Finishes ONLY previously requested releases after startup/reconnect terminal discovery. +// It never invents release intent: resources outside requested/releasing are untouched, and +// unresolved identity defers (release_pending) rather than settling or broadening the close. +export function reconcileRequestedWorkerTerminalReleases( + runtime: OrcaRuntimeService +): Promise { + const active = activeReconciliationByRuntime.get(runtime) + if (active?.promise) { + active.rerunRequested = true + return active.promise + } + const state: ActiveReconciliation = { rerunRequested: false } + const reconciliation = runReconciliationPasses(runtime, state).finally(() => { + if (activeReconciliationByRuntime.get(runtime) === state) { + activeReconciliationByRuntime.delete(runtime) + } + }) + state.promise = reconciliation + activeReconciliationByRuntime.set(runtime, state) + return reconciliation +} + +async function runReconciliationPasses( + runtime: OrcaRuntimeService, + state: ActiveReconciliation +): Promise { + const combined = emptyResult() + do { + state.rerunRequested = false + const pass = await reconcileRequestedWorkerTerminalReleasesOnce(runtime) + combined.attempted += pass.attempted + combined.released += pass.released + combined.pending += pass.pending + combined.unknown += pass.unknown + combined.retained += pass.retained + } while (state.rerunRequested) + if (combined.attempted > 0) { + // Structured counts only; never transcript content or paths. + console.info('[orchestration] worker terminal release reconciliation', combined) + } + return combined +} + +async function reconcileRequestedWorkerTerminalReleasesOnce( + runtime: OrcaRuntimeService +): Promise { + const db = runtime.getOrchestrationDb() + const backlog = db.listWorkerTerminalReleaseBacklog() + const result = { ...emptyResult(), attempted: backlog.length } + for (const resource of backlog) { + try { + const receipt = await completeWorkerTerminalRelease({ + runtime, + db, + dispatchId: resource.owner_dispatch_id, + resource, + mode: 'recovery' + }) + if (receipt.state === 'released' || receipt.state === 'already_released') { + result.released += 1 + } else if (receipt.state === 'release_pending') { + result.pending += 1 + } else if (receipt.state === 'release_unknown') { + result.unknown += 1 + } else { + result.retained += 1 + } + } catch (error) { + // Archive or endpoint failure: durable intent stays requested; a later discovery retries. + console.warn('[orchestration] worker terminal release retry failed', { + resourceId: resource.id, + dispatchId: resource.owner_dispatch_id, + error: error instanceof Error ? error.message : String(error) + }) + result.pending += 1 + } + } + return result +} + +function emptyResult(): WorkerTerminalReleaseReconciliationResult { + return { attempted: 0, released: 0, pending: 0, unknown: 0, retained: 0 } +} diff --git a/src/main/runtime/orchestration/worker-transcript-read.test.ts b/src/main/runtime/orchestration/worker-transcript-read.test.ts index 0bcceda11f5..48500734a5f 100644 --- a/src/main/runtime/orchestration/worker-transcript-read.test.ts +++ b/src/main/runtime/orchestration/worker-transcript-read.test.ts @@ -77,6 +77,49 @@ describe('worker transcript reads', () => { }) }) + it('pins archived reads to the transcript offset observed before release', async () => { + await writeFile( + transcriptPath, + `${codexMessage('one', 'before release')}\n${codexMessage('two', 'release boundary')}\n` + ) + const snapshot = await readWorkerTranscript({ + agent: 'codex', + sessionId: 'session-exact', + transcriptPath, + limit: 1 + }) + if (!snapshot.ok) { + throw new Error('Expected the release transcript probe') + } + await appendFile(transcriptPath, `${codexMessage('three', 'after release')}\n`) + + await expect( + readWorkerTranscript({ + agent: 'codex', + sessionId: 'session-exact', + transcriptPath, + endOffset: snapshot.nextOffset, + limit: 10 + }) + ).resolves.toMatchObject({ + ok: true, + messages: [ + { id: 'one', blocks: [{ type: 'text', text: 'before release' }] }, + { id: 'two', blocks: [{ type: 'text', text: 'release boundary' }] } + ] + }) + await expect( + readWorkerTranscript({ + agent: 'codex', + sessionId: 'session-exact', + transcriptPath, + offset: snapshot.nextOffset, + endOffset: snapshot.nextOffset, + limit: 10 + }) + ).resolves.toMatchObject({ ok: true, messages: [], nextOffset: snapshot.nextOffset }) + }) + it('reports source changes and unsupported providers without guessing', async () => { await writeFile(transcriptPath, `${codexMessage('one', 'first')}\n`) diff --git a/src/main/runtime/orchestration/worker-transcript-read.ts b/src/main/runtime/orchestration/worker-transcript-read.ts index d893c35f995..f63e073b825 100644 --- a/src/main/runtime/orchestration/worker-transcript-read.ts +++ b/src/main/runtime/orchestration/worker-transcript-read.ts @@ -39,6 +39,7 @@ export async function readWorkerTranscript(args: { sessionId: string transcriptPath?: string offset?: number + endOffset?: number limit?: number }): Promise { const transcriptAgent = resolveNativeChatTranscriptAgent(args.agent) @@ -64,8 +65,8 @@ export async function readWorkerTranscript(args: { try { const page = args.offset === undefined - ? await readInitialPage(filePath, limit, decode) - : await readForwardPage(filePath, args.offset, limit, decode) + ? await readInitialPage(filePath, limit, decode, args.endOffset) + : await readForwardPage(filePath, args.offset, limit, decode, args.endOffset) if (!page.ok) { return page } @@ -96,9 +97,13 @@ export async function readWorkerTranscript(args: { async function readInitialPage( filePath: string, limit: number, - decode: NativeChatLineDecoder -): Promise { - const page = await readNativeChatTranscriptTailFile(filePath, limit, decode, false) + decode: NativeChatLineDecoder, + endOffset?: number +): Promise { + if (endOffset !== undefined && (await stat(filePath)).size < endOffset) { + return { ok: false, reason: 'source_changed', warnings: [] } + } + const page = await readNativeChatTranscriptTailFile(filePath, limit, decode, false, endOffset) return { ok: true, filePath, @@ -113,9 +118,14 @@ async function readForwardPage( filePath: string, startOffset: number, limit: number, - decode: NativeChatLineDecoder + decode: NativeChatLineDecoder, + endOffset?: number ): Promise { - const fileSize = (await stat(filePath)).size + const currentFileSize = (await stat(filePath)).size + if (endOffset !== undefined && currentFileSize < endOffset) { + return { ok: false, reason: 'source_changed', warnings: [] } + } + const fileSize = Math.min(currentFileSize, endOffset ?? Number.MAX_SAFE_INTEGER) if (startOffset > fileSize) { return { ok: false, reason: 'source_changed', warnings: [] } } diff --git a/src/main/runtime/pty-waiver-source-invariant.test.ts b/src/main/runtime/pty-waiver-source-invariant.test.ts new file mode 100644 index 00000000000..e0b7122d825 --- /dev/null +++ b/src/main/runtime/pty-waiver-source-invariant.test.ts @@ -0,0 +1,61 @@ +import { readFileSync } from 'node:fs' +import { join } from 'node:path' +import { describe, expect, it } from 'vitest' + +// Why (#11960): behavioural tests only reach one of the removal branches in each +// file, so re-deriving the waiver from `force` at any of the others stays green +// while silently disabling the PTY gate on that path. `force` is set by the +// ordinary delete confirmation (to skip the dirty-file prompt) and is NOT user +// intent to delete past live terminals — so pin the wiring itself, at every site. +const FILES = [join(__dirname, '..', 'ipc', 'worktrees.ts'), join(__dirname, 'orca-runtime.ts')] + +// Why: a comment quoting `allowUnverifiedStop:` would otherwise count as a site — +// and this very invariant invites people to write one in the file it guards. +function stripComments(source: string): string { + return source + .replace(/\/\*[\s\S]*?\*\//g, '') + .split('\n') + .filter((line) => !/^\s*(\/\/|\*)/.test(line)) + .join('\n') +} + +describe('the PTY-stop waiver is never derived from `force`', () => { + it.each(FILES)('%s passes only an explicit waiver to the teardown', (file) => { + const source = stripComments(readFileSync(file, 'utf8')) + + // Why: derived, not hardcoded — merging two removal branches is a legitimate + // refactor and must not read as a deleted safety wiring, while dropping the + // waiver from a branch that still exists must still fail loudly. + const teardownCallSites = + [...source.matchAll(/stopPtysForDestructiveWorktreeRemoval\(/g)].length - 1 + expect(teardownCallSites).toBeGreaterThan(0) + + const values = [...source.matchAll(/allowUnverifiedStop:\s*([^,\n}]+)/g)].map((match) => + match[1].trim() + ) + // One per call site, plus the single conditional spread inside the helper. + expect(values).toHaveLength(teardownCallSites + 1) + for (const value of values) { + expect(value).not.toMatch(/\bforce\b/) + // Positive check too: "not literally force" would still admit any other + // in-scope boolean being wired in by mistake. + expect(value).toMatch(/^(?:args\.)?allowUnverifiedPtyStop$|^true$/) + } + // Only the helper's spread may hardcode `true`; a call site doing so would + // waive unconditionally. + expect(values.filter((value) => value === 'true')).toHaveLength(1) + + // Why: checking the value alone is not enough — `...(force || allowUnverifiedStop + // ? { allowUnverifiedStop: true } : {})` re-disables the gate on every confirmed + // delete while the value stays a blameless `true`. Pin the guarding condition too. + // Lazy `[\s\S]*?` rather than `[^?]*` so an optional chain (`args?.force`) inside + // the condition cannot end the match early and slip the whole check. + const conditions = [ + ...source.matchAll(/\.\.\.\(([\s\S]{0,200}?)\?\s*\{\s*allowUnverifiedStop:/g) + ].map((match) => match[1].trim()) + expect(conditions).toHaveLength(1) + for (const condition of conditions) { + expect(condition).not.toMatch(/\bforce\b/i) + } + }) +}) diff --git a/src/main/runtime/rpc/methods/ai-vault.test.ts b/src/main/runtime/rpc/methods/ai-vault.test.ts index a622ea4f835..606972f4249 100644 --- a/src/main/runtime/rpc/methods/ai-vault.test.ts +++ b/src/main/runtime/rpc/methods/ai-vault.test.ts @@ -85,6 +85,11 @@ describe('aiVault.listSessions params schema', () => { expect(parsed.success).toBe(false) }) + it('accepts Unlimited without applying the numeric cap', () => { + const parsed = AiVaultListSessionsParams.safeParse({ limit: 5000, unlimited: true }) + expect(parsed.success).toBe(true) + }) + it('clamps scopePaths past the cap instead of rejecting', () => { // Why: uncapped producers (web client, pre-cap desktop parents) may exceed // the bound; scope paths only widen discovery, so truncation is safe. @@ -181,6 +186,33 @@ describe('aiVault.listSessions handler + shared cache', () => { expect(scanAiVaultSessions).toHaveBeenCalledTimes(1) }) + it('serves lower depths from a larger completed scan', async () => { + await listAiVaultSessions({ limit: 1000 }) + await listAiVaultSessions({ limit: 250 }) + await listAiVaultSessions({ limit: 500 }) + + expect(scanAiVaultSessions).toHaveBeenCalledTimes(1) + }) + + it('shares a cache entry across equivalent scope path ordering', async () => { + await listAiVaultSessions({ limit: 500, scopePaths: ['/repo/a', '/repo/b'] }) + await listAiVaultSessions({ limit: 500, scopePaths: ['/repo/b', '/repo/a'] }) + + expect(scanAiVaultSessions).toHaveBeenCalledTimes(1) + }) + + it('forwards Unlimited without a numeric limit', async () => { + const dispatcher = makeDispatcher() + const response = await dispatcher.dispatch( + makeRequest('aiVault.listSessions', { limit: 5000, unlimited: true }) + ) + + expect(response).toMatchObject({ ok: true }) + expect(scanAiVaultSessions).toHaveBeenCalledWith( + expect.objectContaining({ limit: undefined, unlimited: true }) + ) + }) + it('keeps a newer different-key scan dedupable after an older scan resolves', async () => { // Why: the resolving scan's cleanup must not clear tracking a concurrent // different-key scan replaced, or re-requests start a duplicate rescan. diff --git a/src/main/runtime/rpc/methods/ai-vault.ts b/src/main/runtime/rpc/methods/ai-vault.ts index e494148ef7f..70acf5dab67 100644 --- a/src/main/runtime/rpc/methods/ai-vault.ts +++ b/src/main/runtime/rpc/methods/ai-vault.ts @@ -23,27 +23,34 @@ const executionHostIdSchema = z.string().transform((value, ctx): `runtime:${stri return z.NEVER }) -export const AiVaultListSessionsParams = z.object({ - limit: z - .unknown() - .transform((value) => - typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined - ) - .pipe(z.union([z.number().int().max(AI_VAULT_LIMIT_MAX), z.undefined()])) - .optional(), - force: OptionalBoolean, - scopePaths: z - .array(z.string().min(1).max(AI_VAULT_SCOPE_PATH_MAX_LENGTH)) - // Why: clamp instead of reject — scope paths only ever widen discovery, and - // rejecting would hard-break older/uncapped producers (web client, pre-cap - // desktop parents) that send more than the bound. - .transform((paths) => paths.slice(0, AI_VAULT_SCOPE_PATHS_MAX_COUNT)) - .optional(), - // Why: desktop/web callers name the runtime host they are addressing; mobile - // omits it. The scan itself is host-local either way, so the id must never - // change what is scanned — it only restamps the shared cached result. - executionHostId: executionHostIdSchema.optional() -}) +export const AiVaultListSessionsParams = z + .object({ + limit: z + .unknown() + .transform((value) => + typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined + ) + .pipe(z.union([z.number().int(), z.undefined()])) + .optional(), + unlimited: OptionalBoolean, + force: OptionalBoolean, + scopePaths: z + .array(z.string().min(1).max(AI_VAULT_SCOPE_PATH_MAX_LENGTH)) + // Why: clamp instead of reject — scope paths only ever widen discovery, and + // rejecting would hard-break older/uncapped producers (web client, pre-cap + // desktop parents) that send more than the bound. + .transform((paths) => paths.slice(0, AI_VAULT_SCOPE_PATHS_MAX_COUNT)) + .optional(), + // Why: desktop/web callers name the runtime host they are addressing; mobile + // omits it. The scan itself is host-local either way, so the id must never + // change what is scanned — it only restamps the shared cached result. + executionHostId: executionHostIdSchema.optional() + }) + .superRefine((params, ctx) => { + if (params.unlimited !== true && params.limit && params.limit > AI_VAULT_LIMIT_MAX) { + ctx.addIssue({ code: 'custom', path: ['limit'], message: 'Limit exceeds maximum' }) + } + }) export const AiVaultPrepareSessionResumeParams = z.object({ agent: z.enum(AI_VAULT_AGENTS), @@ -58,7 +65,8 @@ export const AI_VAULT_METHODS: RpcMethod[] = [ params: AiVaultListSessionsParams, handler: async (params, { runtime }) => { const result = await runtime.listAiVaultSessions({ - limit: params.limit, + limit: params.unlimited ? undefined : params.limit, + unlimited: params.unlimited, force: params.force, scopePaths: params.scopePaths }) diff --git a/src/main/runtime/rpc/methods/native-chat.test.ts b/src/main/runtime/rpc/methods/native-chat.test.ts index 2e0358e338d..47708d36077 100644 --- a/src/main/runtime/rpc/methods/native-chat.test.ts +++ b/src/main/runtime/rpc/methods/native-chat.test.ts @@ -83,6 +83,10 @@ function makeMessage(text: string): NativeChatMessage { } } +function makeTextMessage(text: string): NativeChatMessage { + return { ...makeMessage(''), blocks: [{ type: 'text', text }] } +} + function readSessionHandler(): (params: unknown, ctx: RpcContext) => Promise { const method = NATIVE_CHAT_METHODS.find((m) => m.name === 'nativeChat.readSession') if (!method) { @@ -144,8 +148,35 @@ describe('nativeChat.readSession clientKind truncation gating', () => { ctxWith('mobile') ) const output = firstOutput(result) - expect(output.length).toBeLessThan(OVERSIZED.length) - expect(output).toContain('truncated') + expect(output).toBe(`${OVERSIZED.slice(0, 4000)}\n… (truncated)`) + }) + + // STA-3230: a paired desktop or mobile client saw long assistant replies cut + // at the tool-preview cap with `… (truncated)` and no way to read the rest. + it('passes a long assistant text block through unclipped for mobile clients', async () => { + const text = 'prose '.repeat(1000) + cachedResult.value = { messages: [makeTextMessage(text)] } + const result = await readSessionHandler()( + { agent: 'claude', sessionId: 's' }, + ctxWith('mobile') + ) + const block = (result as { messages: NativeChatMessage[] }).messages[0].blocks[0] as { + text: string + } + expect(block.text).toBe(text) + }) + + it('clips a pathological text block at the safety ceiling for mobile clients', async () => { + const text = 'y'.repeat(70_000) + cachedResult.value = { messages: [makeTextMessage(text)] } + const result = await readSessionHandler()( + { agent: 'claude', sessionId: 's' }, + ctxWith('mobile') + ) + const block = (result as { messages: NativeChatMessage[] }).messages[0].blocks[0] as { + text: string + } + expect(block.text).toBe(`${text.slice(0, 64_000)}\n… (truncated)`) }) it('bounds raw tool-call inputs before sending them to mobile', async () => { @@ -324,6 +355,33 @@ describe('nativeChat.readSession clientKind truncation gating', () => { }) describe('nativeChat.subscribe initial snapshot', () => { + it('preserves long assistant text across mobile stream frame types', async () => { + watcher.watching = true + watcher.args = null + const emitted: unknown[] = [] + const text = 'prose '.repeat(1000) + const message = makeTextMessage(text) + await subscribeHandler()( + { agent: 'claude', sessionId: 's' }, + streamingContext('mobile'), + (value) => emitted.push(value) + ) + + const callbacks = activeWatcherArgs() + callbacks.onInitialSnapshot?.([message], false, 123) + callbacks.onReplace?.([message], false, 123) + callbacks.onAppend([message]) + + expect(emitted.map((frame) => (frame as { type: string }).type)).toEqual([ + 'snapshot', + 'replacement', + 'appended' + ]) + for (const frame of emitted as { messages: NativeChatMessage[] }[]) { + expect(frame.messages[0].blocks[0]).toEqual({ type: 'text', text }) + } + }) + it('emits one windowed snapshot with pagination state before live appends', async () => { watcher.watching = true watcher.args = null diff --git a/src/main/runtime/rpc/methods/native-chat.ts b/src/main/runtime/rpc/methods/native-chat.ts index 1e94b95176e..ee9343524e7 100644 --- a/src/main/runtime/rpc/methods/native-chat.ts +++ b/src/main/runtime/rpc/methods/native-chat.ts @@ -62,26 +62,32 @@ const NativeChatUnsubscribe = z.object({ const MOBILE_NATIVE_CHAT_DEFAULT_WINDOW = 40 const MOBILE_NATIVE_CHAT_MAX_WINDOW = 2000 // Why: a single tool result (a big file read, a long diff) can be hundreds of KB. -// The mobile view only previews block bodies, so truncate them on the wire to -// keep the payload small; the marker tells the user content was clipped. +// The mobile view only previews tool block bodies, so truncate them on the wire +// to keep the payload small; the marker tells the user content was clipped. const MOBILE_BLOCK_CHAR_CAP = 4000 +// Why: text blocks are the message body itself, rendered in full by the chat +// view — a preview-sized cap cut long assistant replies mid-sentence with no way +// to read on (STA-3230). Keep only a generous safety ceiling: a transcript +// record can legally reach 2MB, and shipping that much markdown in one block +// would freeze the phone. +const MOBILE_TEXT_BLOCK_CHAR_CAP = 64_000 const MOBILE_TOOL_INPUT_ITEMS_CAP = 20 const MOBILE_TOOL_INPUT_NODE_CAP = 100 const TRUNCATION_MARKER = '\n… (truncated)' -function clip(text: string): string { - return text.length > MOBILE_BLOCK_CHAR_CAP - ? text.slice(0, MOBILE_BLOCK_CHAR_CAP) + TRUNCATION_MARKER - : text +function clip(text: string, cap: number): string { + return text.length > cap ? text.slice(0, cap) + TRUNCATION_MARKER : text } function clipBlock(block: NativeChatBlock): NativeChatBlock { if (block.type === 'text') { - return block.text.length > MOBILE_BLOCK_CHAR_CAP ? { ...block, text: clip(block.text) } : block + return block.text.length > MOBILE_TEXT_BLOCK_CHAR_CAP + ? { ...block, text: clip(block.text, MOBILE_TEXT_BLOCK_CHAR_CAP) } + : block } if (block.type === 'tool-result') { return block.output.length > MOBILE_BLOCK_CHAR_CAP - ? { ...block, output: clip(block.output) } + ? { ...block, output: clip(block.output, MOBILE_BLOCK_CHAR_CAP) } : block } if (block.type === 'tool-call') { diff --git a/src/main/runtime/rpc/methods/orchestration-federation-agent-launch.test.ts b/src/main/runtime/rpc/methods/orchestration-federation-agent-launch.test.ts new file mode 100644 index 00000000000..15b2194140a --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-federation-agent-launch.test.ts @@ -0,0 +1,89 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { OrcaRuntimeService } from '../../orca-runtime' +import { OrchestrationDb } from '../../orchestration/db' +import { ORCHESTRATION_METHODS } from './orchestration' + +// Why: a federated worker terminal is created from an agent id. Passing that id +// as a shell command launched Cursor's desktop app instead of `cursor-agent` +// (issue #11926), so the remote path must resolve through the TUI agent config +// exactly like the local one. +describe('federated worker agent launch', () => { + let db: OrchestrationDb | undefined + + afterEach(() => { + db?.close() + vi.restoreAllMocks() + }) + + it('creates the remote worker terminal from the agent id, never as a command', async () => { + db = new OrchestrationDb(':memory:') + const runtime = new OrcaRuntimeService() + runtime.setOrchestrationDb(db) + vi.spyOn(runtime, 'validateOrchestrationAgentLauncher').mockImplementation(() => {}) + vi.spyOn(runtime, 'showManagedWorktree').mockResolvedValue({ + id: 'repo::remote-worktree' + } as never) + const createTerminal = vi.spyOn(runtime, 'createTerminal').mockResolvedValue({ + handle: 'term_remote_worker', + worktreeId: 'repo::remote-worktree', + title: 'worker' + }) + vi.spyOn(runtime, 'waitForTerminal').mockResolvedValue({ + handle: 'term_remote_worker', + condition: 'tui-idle', + satisfied: true, + status: 'running', + exitCode: null + }) + // Why: without a stable pane the handler bails at agent_readiness, so the + // assertions below would pass against a worker that never actually started. + vi.spyOn(runtime, 'getTerminalPaneKey').mockReturnValue('tab_remote:leaf_remote') + vi.spyOn(runtime, 'getTerminalProcessIncarnation').mockReturnValue( + 'runtime_test:term_remote_worker:1' + ) + vi.spyOn(runtime, 'getTerminalOrchestrationCliCommand').mockReturnValue('orca') + vi.spyOn(runtime, 'sendTerminalAgentPrompt').mockResolvedValue({ + handle: 'term_remote_worker', + accepted: true, + bytesWritten: 1 + }) + const method = ORCHESTRATION_METHODS.find( + (candidate) => candidate.name === 'orchestration.federationAttachStart' + ) + if (!method) { + throw new Error('federationAttachStart method is not registered') + } + + const result = (await method.handler( + method.params!.parse({ + dispatchId: 'ctx_remote', + taskId: 'task_remote', + taskSpec: 'remote cursor worker', + protocolVersion: 1, + worktree: 'id:repo::remote-worktree', + agent: 'cursor' + }), + { + runtime, + orchestrationMutation: { + callerFingerprint: 'home_peer', + requestId: 'request_remote', + method: 'orchestration.federationAttachStart', + payloadHash: 'remote_payload' + } + } + )) as { state: string; failedStage?: string; lastError?: string } + + // Why: assert the worker actually reached ready — a spy-only assertion would + // stay green even if every stage after terminal_create regressed. + expect(result).toMatchObject({ state: 'ready' }) + expect(createTerminal).toHaveBeenCalledWith( + 'id:repo::remote-worktree', + expect.objectContaining({ startupAgent: 'cursor' }) + ) + expect(createTerminal).toHaveBeenCalledWith( + 'id:repo::remote-worktree', + expect.not.objectContaining({ command: expect.anything() }) + ) + }) +}) diff --git a/src/main/runtime/rpc/methods/orchestration-federation.ts b/src/main/runtime/rpc/methods/orchestration-federation.ts index a0e5b877b8e..7ee1022b5a7 100644 --- a/src/main/runtime/rpc/methods/orchestration-federation.ts +++ b/src/main/runtime/rpc/methods/orchestration-federation.ts @@ -191,7 +191,9 @@ export const ORCHESTRATION_FEDERATION_ATTACH_METHODS: RpcMethod[] = [ } else { failedStage = 'terminal_create' const terminal = await runtime.createTerminal(`id:${worktree.id}`, { - command: agent, + // Why: agent ids are not shell commands (`cursor` is the desktop app, + // its CLI is `cursor-agent`); resolve through the TUI agent config. + startupAgent: agent as TuiAgent, title: `worker-${params.taskId}`, presentation: 'background' }) diff --git a/src/main/runtime/rpc/methods/orchestration-runs.ts b/src/main/runtime/rpc/methods/orchestration-runs.ts index 29ec45b3656..36ddcb1201f 100644 --- a/src/main/runtime/rpc/methods/orchestration-runs.ts +++ b/src/main/runtime/rpc/methods/orchestration-runs.ts @@ -2,7 +2,10 @@ import { z } from 'zod' import { defineMethod, type RpcMethod } from '../core' import { OptionalBoolean, OptionalString, requiredString } from '../schemas' import { ORCHESTRATION_RUN_PAGE_LIMIT } from '../../../../shared/orchestration-run-pagination' -import type { OrcaRuntimeService } from '../../orca-runtime' +import type { + OrcaRuntimeService, + OrchestrationCompatibilityCallerAuthority +} from '../../orca-runtime' import { OrchestrationError } from '../../orchestration/orchestration-error' import { assertCallerHandleMatchesEvidence } from './orchestration-run-scope' @@ -24,8 +27,15 @@ const RunListParams = z.object({ }) const RunShowParams = z.object({ id: requiredString('Missing --id'), from: OptionalString }) -function requireCallerPane(runtime: OrcaRuntimeService, handle: string): string { - const paneKey = runtime.getTerminalPaneKey(handle) +function requireCallerPane( + runtime: OrcaRuntimeService, + handle: string, + callerAuthority?: OrchestrationCompatibilityCallerAuthority +): string { + const paneKey = + callerAuthority?.terminalHandle === handle + ? callerAuthority.paneKey + : runtime.getTerminalPaneKey(handle) if (!paneKey) { throw new OrchestrationError( 'stable_pane_required', @@ -67,7 +77,7 @@ export const ORCHESTRATION_RUN_METHODS: RpcMethod[] = [ orchestrationCompatibilityCallerAuthority: callerAuthority } ) => { - const paneKey = requireCallerPane(runtime, params.from) + const paneKey = requireCallerPane(runtime, params.from, callerAuthority) if ( params.takeoverLegacy && (callerAuthority?.terminalHandle !== params.from || callerAuthority.paneKey !== paneKey) diff --git a/src/main/runtime/rpc/methods/orchestration-worker-archive-read.ts b/src/main/runtime/rpc/methods/orchestration-worker-archive-read.ts new file mode 100644 index 00000000000..29e01e45558 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-archive-read.ts @@ -0,0 +1,226 @@ +import type { + OrchestrationWorkerReadResult, + OrchestrationWorkerReadSource +} from '../../../../shared/orchestration-worker-output' +import type { OrchestrationDb } from '../../orchestration/db' +import { OrchestrationError } from '../../orchestration/orchestration-error' +import type { + WorkerTerminalArchiveRow, + WorkerTerminalResourceRow +} from '../../orchestration/worker-terminal-ownership' +import type { + WorkerTerminalTailArchive, + WorkerTranscriptPinArchive, + WorkerTranscriptSnapshotArchive +} from '../../orchestration/worker-output-archive' +import { clampWorkerTranscriptLimit } from '../../orchestration/worker-transcript-payload' +import { + createWorkerOutputSourceIdentity, + decodeWorkerOutputCursor, + encodeWorkerOutputCursor +} from '../../orchestration/worker-output-cursor' +import { readWorkerTranscript } from '../../orchestration/worker-transcript-read' + +const ARCHIVED_TERMINAL_PAGE_LINES = 2_000 + +// Serves the frozen output source after the live PTY is gone. Transcript pins read the exact +// provider transcript directly; terminal archives page the stored redacted tail. Cursors stay +// Dispatch-scoped and source-pinned exactly like live reads. +export async function readArchivedWorkerOutput(args: { + db: OrchestrationDb + dispatchId: string + workerState: string + resource: WorkerTerminalResourceRow + source?: OrchestrationWorkerReadSource + cursor?: string | number + limit?: number +}): Promise { + const archive = args.db.getWorkerTerminalArchive(args.dispatchId) + if (!archive) { + throw new OrchestrationError( + 'archive_unavailable', + `Dispatch ${args.dispatchId} was released without a preserved output archive.` + ) + } + if (archive.kind === 'transcript_pin') { + if (args.source === 'terminal') { + throw new OrchestrationError( + 'archive_unavailable', + `Dispatch ${args.dispatchId} preserved structured transcript output only; terminal output was released.` + ) + } + const content = JSON.parse(archive.content) as + | WorkerTranscriptPinArchive + | WorkerTranscriptSnapshotArchive + return isTranscriptSnapshot(content) + ? readFrozenTranscript(args, archive, content) + : readLegacyPinnedTranscript(args, content) + } + if (args.source === 'transcript') { + throw new OrchestrationError( + 'transcript_required', + `Structured output is unavailable for released Dispatch ${args.dispatchId}: the archive holds terminal output only.` + ) + } + return readArchivedTerminalTail(args, archive) +} + +function readFrozenTranscript( + args: Parameters[0], + archive: WorkerTerminalArchiveRow, + snapshot: WorkerTranscriptSnapshotArchive +): OrchestrationWorkerReadResult { + const cursor = decodeWorkerOutputCursor(args.cursor, args.dispatchId) + const sourceIdentity = createWorkerOutputSourceIdentity([ + 'released-transcript-snapshot', + args.resource.id, + snapshot.processIncarnation, + archive.created_at + ]) + if (cursor && (cursor.source !== 'transcript' || cursor.sourceIdentity !== sourceIdentity)) { + throw sourceChanged() + } + const start = Math.min(cursor?.position ?? 0, snapshot.messages.length) + const end = Math.min(start + clampWorkerTranscriptLimit(args.limit), snapshot.messages.length) + const nextCursor = encodeWorkerOutputCursor(args.dispatchId, 'transcript', sourceIdentity, end) + return { + dispatchId: args.dispatchId, + source: 'transcript', + sourceIdentity, + provider: snapshot.agent, + transcript: { + messages: snapshot.messages.slice(start, end), + nextCursor, + limited: end < snapshot.messages.length, + returnedMessageCount: end - start + }, + cursor: nextCursor, + status: { worker: args.workerState, terminal: 'exited' }, + fallbackReason: null, + warnings: [ + ...snapshot.warnings, + ...(snapshot.limited + ? ['Older transcript messages were omitted from the bounded archive.'] + : []) + ], + archived: true + } +} + +async function readLegacyPinnedTranscript( + args: Parameters[0], + pin: WorkerTranscriptPinArchive +): Promise { + const cursor = decodeWorkerOutputCursor(args.cursor, args.dispatchId) + const sourceIdentity = createWorkerOutputSourceIdentity([ + 'released-transcript', + pin.processIncarnation, + pin.agent, + pin.providerSessionKey, + pin.providerSessionId, + pin.transcriptPath ?? '', + String(pin.endOffset) + ]) + if (cursor && cursor.source !== 'transcript') { + throw sourceChanged() + } + if (cursor && cursor.sourceIdentity !== sourceIdentity) { + throw sourceChanged() + } + const transcript = await readWorkerTranscript({ + agent: pin.agent, + sessionId: pin.providerSessionId, + transcriptPath: pin.transcriptPath ?? undefined, + offset: cursor?.position, + endOffset: pin.endOffset, + limit: args.limit + }) + if (!transcript.ok) { + throw new OrchestrationError( + 'transcript_required', + `The pinned transcript for released Dispatch ${args.dispatchId} is unavailable: ${transcript.reason}.`, + { reason: transcript.reason } + ) + } + const nextCursor = encodeWorkerOutputCursor( + args.dispatchId, + 'transcript', + sourceIdentity, + transcript.nextOffset + ) + return { + dispatchId: args.dispatchId, + source: 'transcript', + sourceIdentity, + provider: pin.agent, + transcript: { + messages: transcript.messages, + nextCursor, + limited: transcript.limited, + returnedMessageCount: transcript.messages.length + }, + cursor: nextCursor, + status: { worker: args.workerState, terminal: 'exited' }, + fallbackReason: null, + warnings: transcript.warnings, + archived: true + } +} + +function isTranscriptSnapshot( + content: WorkerTranscriptPinArchive | WorkerTranscriptSnapshotArchive +): content is WorkerTranscriptSnapshotArchive { + return 'version' in content && content.version === 2 +} + +function readArchivedTerminalTail( + args: Parameters[0], + archive: WorkerTerminalArchiveRow +): OrchestrationWorkerReadResult { + const content = JSON.parse(archive.content) as WorkerTerminalTailArchive + const cursor = decodeWorkerOutputCursor(args.cursor, args.dispatchId) + const sourceIdentity = createWorkerOutputSourceIdentity([ + 'released-terminal', + args.resource.id, + archive.created_at + ]) + if (cursor && cursor.source !== 'terminal') { + throw sourceChanged() + } + if (cursor && (cursor.legacy || cursor.sourceIdentity !== sourceIdentity)) { + throw sourceChanged() + } + const start = Math.min(cursor?.position ?? 0, content.lines.length) + const pageSize = Math.max(1, Math.min(args.limit ?? ARCHIVED_TERMINAL_PAGE_LINES, 10_000)) + const end = Math.min(start + pageSize, content.lines.length) + const tail = content.lines.slice(start, end) + const nextCursor = + end < content.lines.length + ? encodeWorkerOutputCursor(args.dispatchId, 'terminal', sourceIdentity, end) + : null + return { + dispatchId: args.dispatchId, + source: 'terminal', + sourceIdentity, + terminal: { + handle: args.resource.terminal_handle, + status: 'exited', + tail, + truncated: content.truncated, + nextCursor, + returnedLineCount: tail.length + }, + cursor: nextCursor, + status: { worker: args.workerState, terminal: 'exited' }, + fallbackReason: null, + warnings: content.warnings, + archived: true + } +} + +function sourceChanged(): OrchestrationError { + return new OrchestrationError( + 'source_changed', + 'The worker output source changed. Start a fresh worker-read without the old cursor.' + ) +} diff --git a/src/main/runtime/rpc/methods/orchestration-worker-control.ts b/src/main/runtime/rpc/methods/orchestration-worker-control.ts index ae64f967e06..23233b63965 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-control.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-control.ts @@ -3,14 +3,8 @@ import { ORCHESTRATION_WORKER_READ_SOURCES, type OrchestrationWorkerReadResult } from '../../../../shared/orchestration-worker-output' -import type { RuntimeTerminalRead } from '../../../../shared/runtime-types' import { OrchestrationError } from '../../orchestration/orchestration-error' import { syncFederatedDispatch } from '../../orchestration/federation-sync' -import { - createWorkerOutputSourceIdentity, - decodeWorkerOutputCursor, - encodeWorkerOutputCursor -} from '../../orchestration/worker-output-cursor' import { defineMethod, type RpcMethod } from '../core' import { OptionalFiniteNumber, requiredString } from '../schemas' import { @@ -19,7 +13,10 @@ import { inspectWorkerTerminal, resolvePinnedFederatedServer } from './orchestration-worker-observation' +import { readArchivedWorkerOutput } from './orchestration-worker-archive-read' +import { readLegacyFederatedTerminal } from './orchestration-worker-legacy-federated-read' import { readExactWorkerOutput } from './orchestration-worker-output' +import { exposeWorkerTerminalResource } from './orchestration-worker-release-completion' const WorkerDispatchParams = z.object({ dispatch: requiredString('Missing --dispatch') }) const WorkerReadParams = WorkerDispatchParams.extend({ @@ -119,11 +116,13 @@ export const ORCHESTRATION_WORKER_CONTROL_METHODS: RpcMethod[] = [ } } const observation = await inspectWorkerTerminal(runtime, db, params.dispatch) + const resource = db.getWorkerTerminalResourceByOwner(params.dispatch) return { dispatch, worker: exposeWorker(worker), terminal: observation.exact ? observation.terminal : null, - observation: { status: observation.status, exactWorker: observation.exact } + observation: { status: observation.status, exactWorker: observation.exact }, + terminalResource: resource ? exposeWorkerTerminalResource(resource) : null } } }), @@ -175,6 +174,18 @@ export const ORCHESTRATION_WORKER_CONTROL_METHODS: RpcMethod[] = [ `Worker Dispatch ${params.dispatch} has no agent terminal.` ) } + const resource = db.getWorkerTerminalResourceByOwner(params.dispatch) + if (resource && ['releasing', 'released'].includes(resource.release_state)) { + return readArchivedWorkerOutput({ + db, + dispatchId: params.dispatch, + workerState: worker.state, + resource, + source: params.source, + cursor: params.cursor, + limit: params.limit + }) + } const observation = await inspectWorkerTerminal(runtime, db, params.dispatch) if (!observation.exact) { throw new OrchestrationError( @@ -227,68 +238,3 @@ export const ORCHESTRATION_WORKER_CONTROL_METHODS: RpcMethod[] = [ } }) ] - -async function readLegacyFederatedTerminal(args: { - runtime: Parameters[0] - server: ReturnType - federated: Parameters[1] - workerState: string - dispatchId: string - source: (typeof ORCHESTRATION_WORKER_READ_SOURCES)[number] | undefined - cursor: string | number | undefined - limit: number | undefined -}) { - const cursor = decodeWorkerOutputCursor(args.cursor, args.dispatchId) - if (args.source === 'transcript' || cursor?.source === 'transcript') { - throw new OrchestrationError( - 'transcript_required', - `Connected server ${args.server.name} does not support structured worker output.`, - { reason: 'remote_capability_unavailable' } - ) - } - const remote = (await args.runtime.callOrchestrationWorkerServer( - args.server.environmentId, - 'orchestration.federationRead', - { - dispatchId: args.dispatchId, - cursor: cursor?.source === 'terminal' ? cursor.position : undefined, - limit: args.limit - }, - 15_000 - )) as { runtimeEpoch: string; terminal: RuntimeTerminalRead } - const sourceIdentity = createWorkerOutputSourceIdentity([ - 'legacy-remote-terminal', - args.federated.peer_fingerprint, - args.dispatchId, - remote.runtimeEpoch - ]) - if ( - cursor?.source === 'terminal' && - cursor.sourceIdentity !== null && - cursor.sourceIdentity !== sourceIdentity - ) { - throw new OrchestrationError( - 'source_changed', - 'The worker output source changed. Start a fresh worker-read without the old cursor.' - ) - } - const nextPosition = - remote.terminal.nextCursor !== null && /^\d+$/.test(remote.terminal.nextCursor) - ? Number.parseInt(remote.terminal.nextCursor, 10) - : null - return { - dispatchId: args.dispatchId, - source: 'terminal' as const, - sourceIdentity, - terminal: remote.terminal, - cursor: - nextPosition === null - ? null - : encodeWorkerOutputCursor(args.dispatchId, 'terminal', sourceIdentity, nextPosition), - status: { worker: args.workerState, terminal: remote.terminal.status }, - fallbackReason: 'remote_capability_unavailable' as const, - warnings: [], - server: { environmentId: args.server.environmentId, name: args.server.name }, - remoteRuntimeEpoch: remote.runtimeEpoch - } -} diff --git a/src/main/runtime/rpc/methods/orchestration-worker-legacy-federated-read.ts b/src/main/runtime/rpc/methods/orchestration-worker-legacy-federated-read.ts new file mode 100644 index 00000000000..87935f07173 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-legacy-federated-read.ts @@ -0,0 +1,76 @@ +import type { ORCHESTRATION_WORKER_READ_SOURCES } from '../../../../shared/orchestration-worker-output' +import type { RuntimeTerminalRead } from '../../../../shared/runtime-types' +import { OrchestrationError } from '../../orchestration/orchestration-error' +import { + createWorkerOutputSourceIdentity, + decodeWorkerOutputCursor, + encodeWorkerOutputCursor +} from '../../orchestration/worker-output-cursor' +import type { resolvePinnedFederatedServer } from './orchestration-worker-observation' + +// Pre-structured-output servers only expose raw terminal reads; keep that path fenced and +// cursor-scoped so an old peer never silently degrades a transcript cursor. +export async function readLegacyFederatedTerminal(args: { + runtime: Parameters[0] + server: ReturnType + federated: Parameters[1] + workerState: string + dispatchId: string + source: (typeof ORCHESTRATION_WORKER_READ_SOURCES)[number] | undefined + cursor: string | number | undefined + limit: number | undefined +}) { + const cursor = decodeWorkerOutputCursor(args.cursor, args.dispatchId) + if (args.source === 'transcript' || cursor?.source === 'transcript') { + throw new OrchestrationError( + 'transcript_required', + `Connected server ${args.server.name} does not support structured worker output.`, + { reason: 'remote_capability_unavailable' } + ) + } + const remote = (await args.runtime.callOrchestrationWorkerServer( + args.server.environmentId, + 'orchestration.federationRead', + { + dispatchId: args.dispatchId, + cursor: cursor?.source === 'terminal' ? cursor.position : undefined, + limit: args.limit + }, + 15_000 + )) as { runtimeEpoch: string; terminal: RuntimeTerminalRead } + const sourceIdentity = createWorkerOutputSourceIdentity([ + 'legacy-remote-terminal', + args.federated.peer_fingerprint, + args.dispatchId, + remote.runtimeEpoch + ]) + if ( + cursor?.source === 'terminal' && + cursor.sourceIdentity !== null && + cursor.sourceIdentity !== sourceIdentity + ) { + throw new OrchestrationError( + 'source_changed', + 'The worker output source changed. Start a fresh worker-read without the old cursor.' + ) + } + const nextPosition = + remote.terminal.nextCursor !== null && /^\d+$/.test(remote.terminal.nextCursor) + ? Number.parseInt(remote.terminal.nextCursor, 10) + : null + return { + dispatchId: args.dispatchId, + source: 'terminal' as const, + sourceIdentity, + terminal: remote.terminal, + cursor: + nextPosition === null + ? null + : encodeWorkerOutputCursor(args.dispatchId, 'terminal', sourceIdentity, nextPosition), + status: { worker: args.workerState, terminal: remote.terminal.status }, + fallbackReason: 'remote_capability_unavailable' as const, + warnings: [], + server: { environmentId: args.server.environmentId, name: args.server.name }, + remoteRuntimeEpoch: remote.runtimeEpoch + } +} diff --git a/src/main/runtime/rpc/methods/orchestration-worker-methods.ts b/src/main/runtime/rpc/methods/orchestration-worker-methods.ts index 341521323fd..c613732d263 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-methods.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-methods.ts @@ -1,10 +1,12 @@ import type { RpcMethod } from '../core' import { ORCHESTRATION_WORKER_CONTROL_METHODS } from './orchestration-worker-control' +import { ORCHESTRATION_WORKER_RELEASE_METHODS } from './orchestration-worker-release' import { ORCHESTRATION_WORKER_STOP_METHODS } from './orchestration-worker-stop' import { ORCHESTRATION_WORKER_START_METHODS } from './orchestration-workers' export const ORCHESTRATION_WORKER_METHODS: RpcMethod[] = [ ...ORCHESTRATION_WORKER_START_METHODS, ...ORCHESTRATION_WORKER_CONTROL_METHODS, - ...ORCHESTRATION_WORKER_STOP_METHODS + ...ORCHESTRATION_WORKER_STOP_METHODS, + ...ORCHESTRATION_WORKER_RELEASE_METHODS ] diff --git a/src/main/runtime/rpc/methods/orchestration-worker-output.ts b/src/main/runtime/rpc/methods/orchestration-worker-output.ts index 60e3f942839..2b222f01586 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-output.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-output.ts @@ -181,7 +181,7 @@ function assertCursorSourceMatchesRequest( } } -function orchestrationTimestampToMs(value: string): number { +export function orchestrationTimestampToMs(value: string): number { const normalized = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(value) ? `${value.replace(' ', 'T')}Z` : value diff --git a/src/main/runtime/rpc/methods/orchestration-worker-release-completion.ts b/src/main/runtime/rpc/methods/orchestration-worker-release-completion.ts new file mode 100644 index 00000000000..4beb0323fd1 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-release-completion.ts @@ -0,0 +1,292 @@ +import type { OrchestrationDb } from '../../orchestration/db' +import type { + WorkerTerminalArchiveRow, + WorkerTerminalArchiveStatus, + WorkerTerminalResourceRow, + WorkerTerminalRetainedReason +} from '../../orchestration/worker-terminal-ownership' +import { + captureWorkerOutputArchive, + type WorkerTerminalTailArchive +} from '../../orchestration/worker-output-archive' +import type { OrcaRuntimeService } from '../../orca-runtime' +import { inspectWorkerTerminal } from './orchestration-worker-observation' +import { orchestrationTimestampToMs } from './orchestration-worker-output' + +export type WorkerReleaseReceipt = { + dispatchId: string + state: 'released' | 'already_released' | 'retained' | 'release_pending' | 'release_unknown' + reason?: WorkerTerminalRetainedReason + processAction: 'closed_agent_terminal' | 'closed_exited_terminal' | 'none' + archive: { source: string | null; status: string | null } | null + recovery?: string + lastError?: string +} + +type WorkerTerminalReleaseArgs = { + runtime: OrcaRuntimeService + db: OrchestrationDb + dispatchId: string + resource: WorkerTerminalResourceRow + mode?: 'interactive' | 'recovery' +} + +const activeReleaseByRuntime = new WeakMap< + OrcaRuntimeService, + Map> +>() + +export function exposeWorkerTerminalResource(resource: WorkerTerminalResourceRow): { + id: string + ownershipState: string + releaseState: string + retainedReason: string | null + terminalHandle: string + worktreeId: string | null + originDispatchId: string + ownerDispatchId: string + releaseRequestedAt: string | null + releaseCompletedAt: string | null + releaseError: string | null + archive: { source: string | null; status: string | null } +} { + return { + id: resource.id, + ownershipState: resource.ownership_state, + releaseState: resource.release_state, + retainedReason: resource.retained_reason, + terminalHandle: resource.terminal_handle, + worktreeId: resource.worktree_id, + originDispatchId: resource.origin_dispatch_id, + ownerDispatchId: resource.owner_dispatch_id, + releaseRequestedAt: resource.release_requested_at, + releaseCompletedAt: resource.release_completed_at, + releaseError: resource.release_error, + archive: { source: resource.archive_source, status: resource.archive_status } + } +} + +export function archiveSummary( + resource: WorkerTerminalResourceRow | null +): { source: string | null; status: string | null } | null { + if (!resource) { + return null + } + if (!resource.archive_source && !resource.archive_status) { + return null + } + return { source: resource.archive_source, status: resource.archive_status } +} + +// Completes a durably requested release: re-prove exact identity, freeze output, close only the +// exact agent terminal, settle. Shared between the RPC method and the startup reconciler. +export function completeWorkerTerminalRelease( + args: WorkerTerminalReleaseArgs +): Promise { + let activeByResource = activeReleaseByRuntime.get(args.runtime) + if (!activeByResource) { + activeByResource = new Map() + activeReleaseByRuntime.set(args.runtime, activeByResource) + } + const active = activeByResource.get(args.resource.id) + if (active) { + return active + } + const release = completeWorkerTerminalReleaseOnce(args).finally(() => { + if (activeByResource?.get(args.resource.id) === release) { + activeByResource.delete(args.resource.id) + } + }) + activeByResource.set(args.resource.id, release) + return release +} + +async function completeWorkerTerminalReleaseOnce( + args: WorkerTerminalReleaseArgs +): Promise { + const { runtime, db, dispatchId, resource } = args + const worker = db.getWorkerDispatch(dispatchId) + if (!worker || worker.agent_terminal_handle !== resource.terminal_handle) { + const retained = db.revertWorkerTerminalReleaseToRetained(resource.id, 'identity_unproven') + return { + dispatchId, + state: 'retained', + reason: 'identity_unproven', + processAction: 'none', + archive: archiveSummary(retained) + } + } + const observation = await inspectWorkerTerminal(runtime, db, dispatchId) + if (observation.status === 'identity_changed') { + const retained = db.revertWorkerTerminalReleaseToRetained(resource.id, 'identity_unproven') + return { + dispatchId, + state: 'retained', + reason: 'identity_unproven', + processAction: 'none', + archive: archiveSummary(retained) + } + } + if (!workerTerminalLeaseIsCurrent(runtime, db, dispatchId, resource)) { + const retained = db.revertWorkerTerminalReleaseToRetained(resource.id, 'identity_unproven') + return { + dispatchId, + state: 'retained', + reason: 'identity_unproven', + processAction: 'none', + archive: archiveSummary(retained) + } + } + if (observation.status === 'missing' || observation.status === 'unattached') { + if (args.mode === 'recovery') { + // Inventory may still be incomplete during startup/reconnect discovery; defer. + return { + dispatchId, + state: 'release_pending', + processAction: 'none', + archive: archiveSummary(resource), + recovery: + 'The recorded terminal has not been rediscovered yet; recovery will retry after the next terminal inventory.' + } + } + // Why: the handle resolves nowhere, but the PTY could have been re-homed after a restart — + // claiming released would hide a live process; only an exact observation may settle it. + const unknown = db.markWorkerTerminalReleaseUnknown( + resource.id, + 'The recorded terminal no longer resolves; whether its process is gone cannot be proven.' + ) + return { + dispatchId, + state: 'release_unknown', + processAction: 'none', + archive: archiveSummary(unknown), + lastError: unknown.release_error ?? undefined, + recovery: `Inspect with: orca orchestration worker-show --dispatch ${dispatchId} --json — then repeat worker-release with the same --retry-request. Never substitute a broad terminal close.` + } + } + + const archive = db.getWorkerTerminalArchive(dispatchId) + let archiveSource = resource.archive_source as 'transcript' | 'terminal' | null + let archiveStatus: WorkerTerminalArchiveStatus | null = resource.archive_status + let capturedArchive: { kind: 'transcript_pin' | 'terminal_tail'; content: string } | undefined + if (!archive) { + const captured = await captureWorkerOutputArchive({ + runtime, + dispatchId, + terminalHandle: resource.terminal_handle, + attachedAtMs: orchestrationTimestampToMs(worker.created_at) + }) + capturedArchive = { kind: captured.kind, content: JSON.stringify(captured.content) } + archiveSource = captured.kind === 'transcript_pin' ? 'transcript' : 'terminal' + archiveStatus = captured.status + } else { + const stored = summarizeStoredArchive(archive) + archiveSource ??= stored.source + archiveStatus ??= stored.status + } + const releasing = db.commitWorkerTerminalArchiveForRelease({ + dispatchId, + resourceId: resource.id, + ...capturedArchive, + archiveSource, + archiveStatus: archiveStatus === 'empty' ? 'empty' : 'captured' + }) + if (releasing.ownership_state !== 'owned' || releasing.release_state !== 'releasing') { + return { + dispatchId, + state: 'retained', + reason: retainedReason(releasing), + processAction: 'none', + archive: archiveSummary(releasing) + } + } + if (!workerTerminalLeaseIsCurrent(runtime, db, dispatchId, releasing)) { + const retained = db.revertWorkerTerminalReleaseToRetained(resource.id, 'identity_unproven') + return { + dispatchId, + state: 'retained', + reason: 'identity_unproven', + processAction: 'none', + archive: archiveSummary(retained) + } + } + + try { + await runtime.closeTerminal(resource.terminal_handle) + } catch (error) { + const reason = error instanceof Error ? error.message : String(error) + if (/disposed|not connected|unavailable/i.test(reason)) { + // Durable intent exists; the owning endpoint is temporarily unreachable. Recovery retries. + return { + dispatchId, + state: 'release_pending', + processAction: 'none', + archive: { source: archiveSource, status: archiveStatus }, + lastError: reason, + recovery: + 'The owning endpoint is temporarily unavailable; recovery will retry this release after reconnect without another coordinator decision.' + } + } + const unknown = db.markWorkerTerminalReleaseUnknown(resource.id, reason) + return { + dispatchId, + state: 'release_unknown', + processAction: 'none', + archive: { source: archiveSource, status: archiveStatus }, + lastError: unknown.release_error ?? reason, + recovery: `Inspect with: orca orchestration worker-show --dispatch ${dispatchId} --json — then repeat worker-release with the same --retry-request. Never substitute a broad terminal close.` + } + } + const released = db.settleWorkerTerminalRelease(resource.id) + runtime.notifyMessageArrived(`dispatch:${dispatchId}`, 'status') + return { + dispatchId, + state: 'released', + processAction: + observation.status === 'exited' ? 'closed_exited_terminal' : 'closed_agent_terminal', + archive: archiveSummary(released) + } +} + +function workerTerminalLeaseIsCurrent( + runtime: OrcaRuntimeService, + db: OrchestrationDb, + dispatchId: string, + resource: WorkerTerminalResourceRow +): boolean { + const worker = db.getWorkerDispatch(dispatchId) + const authority = runtime.getOrchestrationDispatchAuthority(resource.terminal_handle) + return Boolean( + worker?.agent_terminal_handle === resource.terminal_handle && + authority && + resource.host_scope === JSON.stringify(authority.hostScope) && + db.isDispatchProcessCurrent({ + dispatchId, + paneKey: runtime.getTerminalPaneKey(resource.terminal_handle), + processIncarnation: runtime.getTerminalProcessIncarnation(resource.terminal_handle) + }) && + !db.workerTerminalResourceHasIdentityConflict(resource.id) + ) +} + +function summarizeStoredArchive(archive: WorkerTerminalArchiveRow): { + source: 'transcript' | 'terminal' + status: Extract +} { + if (archive.kind === 'transcript_pin') { + return { source: 'transcript', status: 'captured' } + } + const content = JSON.parse(archive.content) as WorkerTerminalTailArchive + const empty = content.lines.every((line) => line.trim() === '') + return { source: 'terminal', status: empty ? 'empty' : 'captured' } +} + +function retainedReason(resource: WorkerTerminalResourceRow): WorkerTerminalRetainedReason { + if (resource.retained_reason) { + return resource.retained_reason as WorkerTerminalRetainedReason + } + if (resource.ownership_state === 'user_owned') { + return 'user_takeover' + } + return 'identity_unproven' +} diff --git a/src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts new file mode 100644 index 00000000000..175cac9edac --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-release-recovery.test.ts @@ -0,0 +1,314 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { OrchestrationDb } from '../../orchestration/db' +import { reconcileRequestedWorkerTerminalReleases } from '../../orchestration/worker-terminal-release-reconciliation' +import { OrcaRuntimeService } from '../../orca-runtime' +import type { RpcContext } from '../core' +import { ORCHESTRATION_METHODS } from './orchestration' + +function deferred(): { promise: Promise; resolve: (value: T) => void } { + let resolve!: (value: T) => void + const promise = new Promise((promiseResolve) => { + resolve = promiseResolve + }) + return { promise, resolve } +} + +describe('orchestration worker release recovery', () => { + let db: OrchestrationDb + let dbOpen = false + let runtime: OrcaRuntimeService + let ctx: RpcContext + let activeRunId: string + + const coordinatorPaneKey = 'tab_coord:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa' + const workerPaneKey = 'tab_worker:bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb' + + function setup(): void { + db = new OrchestrationDb(':memory:') + dbOpen = true + runtime = new OrcaRuntimeService() + runtime.setOrchestrationDb(db) + vi.spyOn(runtime, 'getTerminalPaneKey').mockImplementation((handle) => + handle === 'term_coord' ? coordinatorPaneKey : handle === 'term_worker' ? workerPaneKey : null + ) + vi.spyOn(runtime, 'getTerminalProcessIncarnation').mockImplementation((handle) => + handle === 'term_worker' ? 'runtime_test:term_worker:1' : null + ) + vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockImplementation((handle) => + handle === 'term_worker' + ? ({ + terminalHandle: handle, + paneKey: workerPaneKey, + processIncarnation: 'runtime_test:term_worker:1', + hostScope: { kind: 'local', hostId: 'local' } + } as never) + : null + ) + vi.spyOn(runtime, 'validateOrchestrationAgentLauncher').mockImplementation(() => {}) + vi.spyOn(runtime, 'showTerminal').mockImplementation( + async (handle) => ({ handle, worktreeId: 'repo::worktree', status: 'running' }) as never + ) + vi.spyOn(runtime, 'showManagedWorktree').mockResolvedValue({ + id: 'repo::worktree' + } as never) + vi.spyOn(runtime, 'createTerminal').mockResolvedValue({ + handle: 'term_worker', + worktreeId: 'repo::worktree', + title: 'worker' + }) + vi.spyOn(runtime, 'waitForTerminal').mockResolvedValue({ + handle: 'term_worker', + condition: 'tui-idle', + satisfied: true, + status: 'running', + exitCode: null + }) + vi.spyOn(runtime, 'getTerminalOrchestrationCliCommand').mockReturnValue('orca') + vi.spyOn(runtime, 'sendTerminalAgentPrompt').mockResolvedValue({ + handle: 'term_worker', + accepted: true, + bytesWritten: 1 + }) + vi.spyOn(runtime, 'isTerminalRunningAgent').mockResolvedValue(true) + vi.spyOn(runtime, 'getExactWorkerProviderSession').mockReturnValue(null) + vi.spyOn(runtime, 'readTerminal').mockResolvedValue({ + handle: 'term_worker', + status: 'running', + tail: ['worker output line 1', 'worker output line 2'], + truncated: false, + nextCursor: '2' + }) + vi.spyOn(runtime, 'closeTerminal').mockResolvedValue({ + handle: 'term_worker', + closed: true + } as never) + vi.spyOn(runtime, 'notifyMessageArrived').mockImplementation(() => {}) + activeRunId = db.createRun({ + objective: 'Release recovery test Run', + coordinatorHandle: 'term_coord', + coordinatorPaneKey + }).id + ctx = { runtime } + } + + afterEach(() => { + if (dbOpen) { + dbOpen = false + db.close() + } + vi.restoreAllMocks() + }) + + async function call(name: string, params: Record) { + const method = ORCHESTRATION_METHODS.find((candidate) => candidate.name === name) + if (!method) { + throw new Error(`Method not found: ${name}`) + } + const parsed = method.params ? method.params.parse(params) : undefined + return method.handler(parsed, ctx) + } + + async function startWorker(): Promise<{ taskId: string; dispatchId: string }> { + const task = db.createTask({ spec: 'release recovery fixture task', runId: activeRunId }) + const result = (await call('orchestration.workerStart', { + task: task.id, + from: 'term_coord', + agent: 'codex' + })) as { dispatchId: string; state: string } + expect(result.state).toBe('ready') + return { taskId: task.id, dispatchId: result.dispatchId } + } + + async function startSettledWorker( + outcome: 'succeeded' | 'failed' = 'succeeded' + ): Promise<{ taskId: string; dispatchId: string }> { + const worker = await startWorker() + expect( + db.settleWorkerReport({ + taskId: worker.taskId, + dispatchId: worker.dispatchId, + outcome, + result: `worker ${outcome}` + }).action + ).toBe('settled') + return worker + } + + it('finishes a requested release after restart-style interruption', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.closeTerminal).mockRejectedValueOnce(new Error('Multiplexer disposed')) + const interrupted = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + } + expect(interrupted.state).toBe('release_pending') + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('releasing') + + const result = await reconcileRequestedWorkerTerminalReleases(runtime) + expect(result).toMatchObject({ attempted: 1, released: 1 }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('released') + expect(runtime.closeTerminal).toHaveBeenCalledTimes(2) + }) + + it('defers instead of settling unknown while inventory is incomplete', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.closeTerminal).mockRejectedValueOnce(new Error('Multiplexer disposed')) + await call('orchestration.workerRelease', { dispatch: dispatchId }) + vi.mocked(runtime.showTerminal).mockRejectedValue(new Error('terminal_handle_stale')) + + const result = await reconcileRequestedWorkerTerminalReleases(runtime) + expect(result).toMatchObject({ attempted: 1, pending: 1, unknown: 0 }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('releasing') + }) + + it('never touches resources without requested releases', async () => { + setup() + await startSettledWorker() + const result = await reconcileRequestedWorkerTerminalReleases(runtime) + expect(result.attempted).toBe(0) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('coalesces overlapping reconciliation passes and closes each resource once', async () => { + setup() + const { dispatchId } = await startSettledWorker() + expect(db.requestWorkerTerminalRelease(dispatchId).disposition).toBe('requested') + const pendingClose = deferred>>() + vi.mocked(runtime.closeTerminal).mockReturnValue(pendingClose.promise) + + const first = reconcileRequestedWorkerTerminalReleases(runtime) + await vi.waitFor(() => expect(runtime.closeTerminal).toHaveBeenCalledTimes(1)) + const second = reconcileRequestedWorkerTerminalReleases(runtime) + expect(second).toBe(first) + pendingClose.resolve({ handle: 'term_worker', tabId: 'tab-worker', ptyKilled: true }) + + await expect(Promise.all([first, second])).resolves.toEqual([ + expect.objectContaining({ attempted: 1, released: 1 }), + expect.objectContaining({ attempted: 1, released: 1 }) + ]) + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + }) + + it('keeps live terminals bounded across 50 settled workers while controls survive', async () => { + setup() + for (let wave = 0; wave < 50; wave += 1) { + const worker = await startSettledWorker(wave % 2 === 0 ? 'succeeded' : 'failed') + const receipt = (await call('orchestration.workerRelease', { + dispatch: worker.dispatchId + })) as { state: string } + expect(receipt.state).toBe('released') + } + expect(runtime.closeTerminal).toHaveBeenCalledTimes(50) + + const control = await startWorker() + const listed = (await call('orchestration.workerList', { run: activeRunId })) as { + workers: { dispatchId: string; terminalState: string | null }[] + counts: Record + } + expect(listed.counts).toMatchObject({ released: 50, active: 1 }) + expect( + listed.workers.find((worker) => worker.dispatchId === control.dispatchId)?.terminalState + ).toBe('active') + expect(runtime.closeTerminal).toHaveBeenCalledTimes(50) + }) + + it('backfills legacy terminal resources as retained external evidence', () => { + setup() + const insertLegacy = (dispatchId: string, handle: string, paneKey: string | null): void => { + const task = db.createTask({ spec: `legacy ${dispatchId}`, runId: activeRunId }) + const raw = ( + db as unknown as { db: { prepare: (sql: string) => { run: (...args: unknown[]) => void } } } + ).db + raw + .prepare( + `INSERT INTO dispatch_contexts (id, run_id, task_id, contract_version, assignee_pane_key, process_incarnation, status) + VALUES (?, ?, ?, 2, ?, ?, 'completed')` + ) + .run(dispatchId, activeRunId, task.id, paneKey, paneKey ? `inc:${dispatchId}` : null) + raw + .prepare( + `INSERT INTO worker_dispatches (dispatch_id, state, stage, agent_terminal_handle, residual_resources) + VALUES (?, 'succeeded', 'settled', ?, ?)` + ) + .run( + dispatchId, + handle, + JSON.stringify([{ kind: 'terminal', role: 'agent', action: 'created', id: handle }]) + ) + } + insertLegacy('ctx_unique', 'term_unique', 'tab_u:leaf_u') + insertLegacy('ctx_shared_a', 'term_shared', 'tab_s:leaf_s') + insertLegacy('ctx_shared_b', 'term_shared', 'tab_s:leaf_s') + insertLegacy('ctx_no_identity', 'term_bare', null) + ;( + db as unknown as { backfillWorkerTerminalResources: () => void } + ).backfillWorkerTerminalResources() + + for (const ambiguous of ['ctx_unique', 'ctx_shared_a', 'ctx_shared_b', 'ctx_no_identity']) { + expect(db.getWorkerTerminalResourceByOwner(ambiguous)).toMatchObject({ + ownership_state: 'external', + release_state: 'retained', + retained_reason: 'legacy_ambiguous' + }) + } + }) + + it('backfills a legacy creator plus explicit reuser as ambiguous', () => { + setup() + const insertLegacy = (dispatchId: string, action: 'created' | 'reused'): void => { + const task = db.createTask({ spec: dispatchId, runId: activeRunId }) + const raw = ( + db as unknown as { db: { prepare: (sql: string) => { run: (...args: unknown[]) => void } } } + ).db + raw + .prepare( + `INSERT INTO dispatch_contexts (id, run_id, task_id, contract_version, assignee_pane_key, process_incarnation, status) + VALUES (?, ?, ?, 2, ?, ?, ?)` + ) + .run( + dispatchId, + activeRunId, + task.id, + workerPaneKey, + 'runtime_test:term_worker:1', + action === 'created' ? 'completed' : 'dispatched' + ) + raw + .prepare( + `INSERT INTO worker_dispatches (dispatch_id, state, stage, agent_terminal_handle, residual_resources) + VALUES (?, ?, 'legacy', 'term_worker', ?)` + ) + .run( + dispatchId, + action === 'created' ? 'succeeded' : 'ready', + JSON.stringify([{ kind: 'terminal', role: 'agent', action, id: 'term_worker' }]) + ) + } + insertLegacy('ctx_creator', 'created') + insertLegacy('ctx_reuser', 'reused') + ;( + db as unknown as { backfillWorkerTerminalResources: () => void } + ).backfillWorkerTerminalResources() + + for (const dispatchId of ['ctx_creator', 'ctx_reuser']) { + expect(db.getWorkerTerminalResourceByOwner(dispatchId)).toMatchObject({ + ownership_state: 'external', + release_state: 'retained', + retained_reason: 'legacy_ambiguous' + }) + } + }) + + it('removes terminal authority and archived output on orchestration reset', async () => { + setup() + const { dispatchId } = await startSettledWorker() + await call('orchestration.workerRelease', { dispatch: dispatchId }) + expect(db.getWorkerTerminalArchive(dispatchId)).toBeDefined() + + db.resetTasks() + + expect(db.getWorkerTerminalResourceByOwner(dispatchId)).toBeUndefined() + expect(db.getWorkerTerminalArchive(dispatchId)).toBeUndefined() + }) +}) diff --git a/src/main/runtime/rpc/methods/orchestration-worker-release.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-release.test.ts new file mode 100644 index 00000000000..25670dda1e7 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-release.test.ts @@ -0,0 +1,763 @@ +import { mkdtemp, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it, vi } from 'vitest' +import { ORCHESTRATION_METHODS } from './orchestration' +import type { RpcContext } from '../core' +import { OrchestrationDb } from '../../orchestration/db' +import { OrcaRuntimeService } from '../../orca-runtime' + +function deferred(): { promise: Promise; resolve: (value: T) => void } { + let resolve!: (value: T) => void + const promise = new Promise((promiseResolve) => { + resolve = promiseResolve + }) + return { promise, resolve } +} + +describe('orchestration worker release', () => { + let db: OrchestrationDb + let dbOpen = false + let runtime: OrcaRuntimeService + let ctx: RpcContext + let activeRunId: string + + const coordinatorPaneKey = 'tab_coord:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa' + const workerPaneKey = 'tab_worker:bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb' + + function setup(): void { + db = new OrchestrationDb(':memory:') + dbOpen = true + runtime = new OrcaRuntimeService() + runtime.setOrchestrationDb(db) + vi.spyOn(runtime, 'getTerminalPaneKey').mockImplementation((handle) => + handle === 'term_coord' + ? coordinatorPaneKey + : handle === 'term_worker' || handle === 'term_reminted' + ? workerPaneKey + : null + ) + vi.spyOn(runtime, 'getTerminalProcessIncarnation').mockImplementation((handle) => + handle === 'term_worker' || handle === 'term_reminted' ? 'runtime_test:term_worker:1' : null + ) + vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockImplementation((handle) => + handle === 'term_worker' || handle === 'term_reminted' + ? ({ + terminalHandle: handle, + paneKey: workerPaneKey, + processIncarnation: 'runtime_test:term_worker:1', + hostScope: { kind: 'local', hostId: 'local' } + } as never) + : null + ) + vi.spyOn(runtime, 'validateOrchestrationAgentLauncher').mockImplementation(() => {}) + vi.spyOn(runtime, 'showTerminal').mockImplementation( + async (handle) => ({ handle, worktreeId: 'repo::worktree', status: 'running' }) as never + ) + vi.spyOn(runtime, 'showManagedWorktree').mockResolvedValue({ + id: 'repo::worktree' + } as never) + vi.spyOn(runtime, 'createTerminal').mockResolvedValue({ + handle: 'term_worker', + worktreeId: 'repo::worktree', + title: 'worker' + }) + vi.spyOn(runtime, 'waitForTerminal').mockResolvedValue({ + handle: 'term_worker', + condition: 'tui-idle', + satisfied: true, + status: 'running', + exitCode: null + }) + vi.spyOn(runtime, 'getTerminalOrchestrationCliCommand').mockReturnValue('orca') + vi.spyOn(runtime, 'sendTerminalAgentPrompt').mockResolvedValue({ + handle: 'term_worker', + accepted: true, + bytesWritten: 1 + }) + vi.spyOn(runtime, 'isTerminalRunningAgent').mockResolvedValue(true) + vi.spyOn(runtime, 'getExactWorkerProviderSession').mockReturnValue(null) + vi.spyOn(runtime, 'readTerminal').mockResolvedValue({ + handle: 'term_worker', + status: 'running', + tail: ['worker output line 1', 'worker output line 2'], + truncated: false, + nextCursor: '2' + }) + vi.spyOn(runtime, 'closeTerminal').mockResolvedValue({ + handle: 'term_worker', + closed: true + } as never) + vi.spyOn(runtime, 'notifyMessageArrived').mockImplementation(() => {}) + activeRunId = db.createRun({ + objective: 'Release test Run', + coordinatorHandle: 'term_coord', + coordinatorPaneKey + }).id + ctx = { runtime } + } + + afterEach(() => { + if (dbOpen) { + dbOpen = false + db.close() + } + vi.restoreAllMocks() + }) + + function findMethod(name: string) { + const method = ORCHESTRATION_METHODS.find((m) => m.name === name) + if (!method) { + throw new Error(`Method not found: ${name}`) + } + return method + } + + async function call(name: string, params: Record) { + const method = findMethod(name) + const parsed = method.params ? method.params.parse(params) : undefined + return method.handler(parsed, ctx) + } + + async function startWorker(options: { terminal?: string } = {}): Promise<{ + taskId: string + dispatchId: string + }> { + const task = db.createTask({ spec: 'release fixture task', runId: activeRunId }) + const result = (await call('orchestration.workerStart', { + task: task.id, + from: 'term_coord', + ...(options.terminal ? { terminal: options.terminal } : { agent: 'codex' }) + })) as { dispatchId: string; state: string } + expect(result.state).toBe('ready') + return { taskId: task.id, dispatchId: result.dispatchId } + } + + function settle(taskId: string, dispatchId: string, outcome: 'succeeded' | 'failed'): void { + const settlement = db.settleWorkerReport({ + taskId, + dispatchId, + outcome, + result: `worker ${outcome}` + }) + expect(settlement.action).toBe('settled') + } + + async function startSettledWorker( + outcome: 'succeeded' | 'failed' = 'succeeded', + options: { terminal?: string } = {} + ): Promise<{ taskId: string; dispatchId: string }> { + const worker = await startWorker(options) + settle(worker.taskId, worker.dispatchId, outcome) + return worker + } + + it('creates an owned resource for a fresh worker terminal', async () => { + setup() + const { dispatchId } = await startWorker() + const resource = db.getWorkerTerminalResourceByOwner(dispatchId) + expect(resource).toMatchObject({ + ownership_state: 'owned', + release_state: 'not_requested', + terminal_handle: 'term_worker', + pane_key: workerPaneKey, + process_incarnation: 'runtime_test:term_worker:1' + }) + }) + + it('releases a succeeded worker: archives then closes exactly the agent terminal', async () => { + setup() + const { dispatchId } = await startSettledWorker('succeeded') + + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + processAction: string + archive: { source: string | null; status: string | null } | null + } + + expect(receipt).toMatchObject({ + state: 'released', + processAction: 'closed_agent_terminal', + archive: { source: 'terminal', status: 'captured' } + }) + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + expect(runtime.closeTerminal).toHaveBeenCalledWith('term_worker') + const resource = db.getWorkerTerminalResourceByOwner(dispatchId) + expect(resource?.release_state).toBe('released') + expect(resource?.ownership_state).toBe('released') + // Outcome is untouched by release. + expect(db.getWorkerDispatch(dispatchId)?.state).toBe('succeeded') + }) + + it('releases a failed worker the same way', async () => { + setup() + const { dispatchId } = await startSettledWorker('failed') + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + } + expect(receipt.state).toBe('released') + expect(db.getWorkerDispatch(dispatchId)?.state).toBe('failed') + }) + + it('is idempotent: a duplicate release returns already_released without another close', async () => { + setup() + const { dispatchId } = await startSettledWorker() + await call('orchestration.workerRelease', { dispatch: dispatchId }) + const second = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + processAction: string + } + expect(second).toMatchObject({ state: 'already_released', processAction: 'none' }) + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + }) + + it('rejects an active worker without recording release intent', async () => { + setup() + const { dispatchId } = await startWorker() + await expect(call('orchestration.workerRelease', { dispatch: dispatchId })).rejects.toThrow( + /only a succeeded or failed worker can release/ + ) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('not_requested') + }) + + it('retains an explicitly reused external terminal without closing it', async () => { + setup() + const { dispatchId } = await startSettledWorker('succeeded', { terminal: 'term_worker' }) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + reason?: string + } + expect(receipt).toMatchObject({ state: 'retained', reason: 'external_terminal' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('retains a user-taken-over terminal durably', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const changed = (await call('orchestration.workerTerminalUserInput', { + paneKey: workerPaneKey + })) as { changed: number } + expect(changed.changed).toBe(1) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + reason?: string + } + expect(receipt).toMatchObject({ state: 'retained', reason: 'user_takeover' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.ownership_state).toBe('user_owned') + }) + + it('lets user takeover cancel a release while output capture is pending', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const pendingRead = deferred>>() + vi.mocked(runtime.readTerminal).mockReturnValue(pendingRead.promise) + + const release = call('orchestration.workerRelease', { dispatch: dispatchId }) + await vi.waitFor(() => expect(runtime.readTerminal).toHaveBeenCalledTimes(1)) + const changed = (await call('orchestration.workerTerminalUserInput', { + paneKey: workerPaneKey + })) as { changed: number } + expect(changed.changed).toBe(1) + pendingRead.resolve({ + handle: 'term_worker', + status: 'running', + tail: ['captured before takeover'], + truncated: false, + nextCursor: '1' + }) + + await expect(release).resolves.toMatchObject({ state: 'retained', reason: 'user_takeover' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + expect(db.getWorkerTerminalArchive(dispatchId)).toBeUndefined() + }) + + it('lets an explicit retain cancel a release while output capture is pending', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const pendingRead = deferred>>() + vi.mocked(runtime.readTerminal).mockReturnValue(pendingRead.promise) + + const release = call('orchestration.workerRelease', { dispatch: dispatchId }) + await vi.waitFor(() => expect(runtime.readTerminal).toHaveBeenCalledTimes(1)) + await expect( + call('orchestration.workerRetain', { dispatch: dispatchId }) + ).resolves.toMatchObject({ state: 'retained', reason: 'user_requested' }) + pendingRead.resolve({ + handle: 'term_worker', + status: 'running', + tail: ['captured before retention'], + truncated: false, + nextCursor: '1' + }) + + await expect(release).resolves.toMatchObject({ state: 'retained', reason: 'user_requested' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + expect(db.getWorkerTerminalArchive(dispatchId)).toBeUndefined() + }) + + it('does not claim retention succeeded after terminal close was committed', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const pendingClose = deferred>>() + vi.mocked(runtime.closeTerminal).mockReturnValue(pendingClose.promise) + + const release = call('orchestration.workerRelease', { dispatch: dispatchId }) + await vi.waitFor(() => expect(runtime.closeTerminal).toHaveBeenCalledTimes(1)) + await expect( + call('orchestration.workerRetain', { dispatch: dispatchId }) + ).resolves.toMatchObject({ state: 'release_pending' }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('releasing') + pendingClose.resolve({ handle: 'term_worker', tabId: 'tab-worker', ptyKilled: true }) + + await expect(release).resolves.toMatchObject({ state: 'released' }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('released') + }) + + it('never marks takeover for panes without an owned resource', async () => { + setup() + const changed = (await call('orchestration.workerTerminalUserInput', { + paneKey: 'tab_other:cccccccc-cccc-4ccc-8ccc-cccccccccccc' + })) as { changed: number } + expect(changed.changed).toBe(0) + }) + + it('preserves takeover across a reminted tab key for the same pane leaf', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const changed = (await call('orchestration.workerTerminalUserInput', { + paneKey: 'tab_reminted:bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb' + })) as { changed: number } + + expect(changed.changed).toBe(1) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.ownership_state).toBe('user_owned') + }) + + it('retains when the exact process identity changed instead of closing', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.getTerminalProcessIncarnation).mockImplementation((handle) => + handle === 'term_worker' ? 'runtime_test:term_worker:2' : null + ) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + reason?: string + } + expect(receipt).toMatchObject({ state: 'retained', reason: 'identity_unproven' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('retains when the terminal host scope changed instead of closing', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.getOrchestrationDispatchAuthority).mockReturnValue({ + terminalHandle: 'term_worker', + paneKey: workerPaneKey, + processIncarnation: 'runtime_test:term_worker:1', + hostScope: { kind: 'ssh', targetId: 'replacement-host' } + } as never) + + await expect( + call('orchestration.workerRelease', { dispatch: dispatchId }) + ).resolves.toMatchObject({ state: 'retained', reason: 'identity_unproven' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('re-proves process identity after archive capture before closing', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const pendingRead = deferred>>() + vi.mocked(runtime.readTerminal).mockReturnValue(pendingRead.promise) + + const release = call('orchestration.workerRelease', { dispatch: dispatchId }) + await vi.waitFor(() => expect(runtime.readTerminal).toHaveBeenCalledTimes(1)) + vi.mocked(runtime.getTerminalProcessIncarnation).mockImplementation((handle) => + handle === 'term_worker' ? 'runtime_test:term_worker:2' : null + ) + pendingRead.resolve({ + handle: 'term_worker', + status: 'running', + tail: ['output from the old process'], + truncated: false, + nextCursor: '1' + }) + + await expect(release).resolves.toMatchObject({ + state: 'retained', + reason: 'identity_unproven' + }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('returns release_unknown when the terminal no longer resolves, then completes a retry', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.showTerminal).mockRejectedValue(new Error('terminal_handle_stale')) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + recovery?: string + } + expect(receipt.state).toBe('release_unknown') + expect(receipt.recovery).toContain('worker-show') + expect(runtime.closeTerminal).not.toHaveBeenCalled() + + vi.mocked(runtime.showTerminal).mockImplementation( + async (handle) => ({ handle, worktreeId: 'repo::worktree', status: 'running' }) as never + ) + const retry = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + } + expect(retry.state).toBe('released') + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + }) + + it('retains the live terminal when output capture fails', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.readTerminal).mockRejectedValue(new Error('read exploded')) + await expect(call('orchestration.workerRelease', { dispatch: dispatchId })).rejects.toThrow( + /Output could not be preserved/ + ) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + // Durable intent survives for recovery. + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('requested') + }) + + it('marks release_unknown when the close itself fails', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.closeTerminal).mockRejectedValue(new Error('close exploded')) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + lastError?: string + } + expect(receipt.state).toBe('release_unknown') + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('unknown') + }) + + it('records an explicitly empty archive for an already-exited worker process', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.showTerminal).mockImplementation( + async (handle) => ({ handle, worktreeId: 'repo::worktree', connected: false }) as never + ) + vi.mocked(runtime.readTerminal).mockResolvedValue({ + handle: 'term_worker', + status: 'exited', + tail: [], + truncated: false, + nextCursor: null + }) + const receipt = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + processAction: string + archive: { status: string | null } | null + } + expect(receipt).toMatchObject({ + state: 'released', + processAction: 'closed_exited_terminal', + archive: { status: 'empty' } + }) + }) + + it('keeps a bounded tail when one terminal line exceeds the archive budget', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const suffix = 'meaningful-tail' + vi.mocked(runtime.readTerminal).mockResolvedValue({ + handle: 'term_worker', + status: 'running', + tail: [`${'x'.repeat(300_000)}${suffix}`], + truncated: false, + nextCursor: '1' + }) + + const release = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + archive: { status: string | null } | null + } + const read = (await call('orchestration.workerRead', { dispatch: dispatchId })) as { + terminal: { tail: string[]; truncated: boolean } + warnings: string[] + } + + expect(release.archive?.status).toBe('captured') + expect(read.terminal.tail).toHaveLength(1) + expect(read.terminal.tail[0]).toMatch(new RegExp(`${suffix}$`)) + expect(read.terminal.truncated).toBe(true) + expect(read.warnings).not.toContain( + 'The live terminal buffer was empty at release; structured transcript output was unavailable.' + ) + }) + + it('serves the frozen redacted archive through worker-read after release, with cursors', async () => { + setup() + const { dispatchId } = await startSettledWorker() + vi.mocked(runtime.readTerminal).mockResolvedValue({ + handle: 'term_worker', + status: 'running', + tail: ['first line', `capability dcap_${'a'.repeat(24)} leaked`, 'last line'], + truncated: false, + nextCursor: '3' + }) + await call('orchestration.workerRelease', { dispatch: dispatchId }) + vi.mocked(runtime.readTerminal).mockClear() + + const page1 = (await call('orchestration.workerRead', { + dispatch: dispatchId, + limit: 2 + })) as { archived?: boolean; terminal: { tail: string[] }; cursor: string | null } + expect(page1.archived).toBe(true) + expect(page1.terminal.tail).toEqual([ + 'first line', + 'capability [dispatch capability redacted] leaked' + ]) + expect(page1.cursor).not.toBeNull() + + const page2 = (await call('orchestration.workerRead', { + dispatch: dispatchId, + cursor: page1.cursor as string + })) as { terminal: { tail: string[] }; cursor: string | null } + expect(page2.terminal.tail).toEqual(['last line']) + expect(page2.cursor).toBeNull() + // The live terminal is never consulted after release. + expect(runtime.readTerminal).not.toHaveBeenCalled() + }) + + it('reads an immutable transcript snapshot after the provider file disappears', async () => { + setup() + const directory = await mkdtemp(join(tmpdir(), 'orca-worker-release-snapshot-')) + const transcriptPath = join(directory, 'rollout.jsonl') + try { + await writeFile( + transcriptPath, + `${JSON.stringify({ + timestamp: '2026-08-03T12:00:00.000Z', + type: 'event_msg', + payload: { id: 'snapshot-message', type: 'agent_message', message: 'frozen output' } + })}\n` + ) + vi.mocked(runtime.getExactWorkerProviderSession).mockReturnValue({ + agent: 'codex', + processIncarnation: 'runtime_test:term_worker:1', + providerSession: { + key: 'codex:snapshot-session', + id: 'snapshot-session', + transcriptPath + } + } as never) + const { dispatchId } = await startSettledWorker() + await call('orchestration.workerRelease', { dispatch: dispatchId }) + await rm(transcriptPath) + + await expect( + call('orchestration.workerRead', { dispatch: dispatchId }) + ).resolves.toMatchObject({ + archived: true, + source: 'transcript', + transcript: { + messages: [{ id: 'snapshot-message', blocks: [{ type: 'text', text: 'frozen output' }] }] + } + }) + } finally { + await rm(directory, { recursive: true, force: true }) + } + }) + + it('rejects a legacy live-terminal cursor after output moves to the archive', async () => { + setup() + const { dispatchId } = await startSettledWorker() + await call('orchestration.workerRelease', { dispatch: dispatchId }) + + await expect( + call('orchestration.workerRead', { dispatch: dispatchId, cursor: 1 }) + ).rejects.toThrow(/source changed/i) + }) + + it('recovers archive metadata when a prior attempt committed only the archive row', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const requested = db.requestWorkerTerminalRelease(dispatchId) + expect(requested.disposition).toBe('requested') + if (requested.disposition !== 'requested') { + throw new Error('release request was not recorded') + } + db.storeWorkerTerminalArchive({ + dispatchId, + resourceId: requested.resource.id, + kind: 'terminal_tail', + content: JSON.stringify({ + lines: ['archive survived the interrupted attempt'], + truncated: false, + terminalStatus: 'running', + warnings: [] + }) + }) + + const release = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + archive: { source: string | null; status: string | null } | null + } + + expect(release.archive).toEqual({ source: 'terminal', status: 'captured' }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)).toMatchObject({ + archive_source: 'terminal', + archive_status: 'captured' + }) + }) + + it('transfers ownership on exact reuse and fences release through the old Dispatch', async () => { + setup() + const first = await startSettledWorker('succeeded') + const originalResource = db.getWorkerTerminalResourceByOwner(first.dispatchId) + expect(originalResource?.ownership_state).toBe('owned') + + const second = await startWorker({ terminal: 'term_reminted' }) + const transferred = db.getWorkerTerminalResourceByOwner(second.dispatchId) + expect(transferred?.id).toBe(originalResource?.id) + expect(transferred?.terminal_handle).toBe('term_reminted') + expect(db.getWorkerTerminalResourceByOwner(first.dispatchId)).toBeUndefined() + + const oldRelease = (await call('orchestration.workerRelease', { + dispatch: first.dispatchId + })) as { state: string; reason?: string } + expect(oldRelease).toMatchObject({ state: 'retained', reason: 'ownership_transferred' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + + settle(second.taskId, second.dispatchId, 'succeeded') + const newRelease = (await call('orchestration.workerRelease', { + dispatch: second.dispatchId + })) as { state: string } + expect(newRelease.state).toBe('released') + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + expect(runtime.closeTerminal).toHaveBeenCalledWith('term_reminted') + }) + + it('rejects exact reuse after release intent instead of closing the new worker', async () => { + setup() + const first = await startSettledWorker('succeeded') + expect(db.requestWorkerTerminalRelease(first.dispatchId).disposition).toBe('requested') + const nextTask = db.createTask({ spec: 'racing reuse', runId: activeRunId }) + + const attempted = (await call('orchestration.workerStart', { + task: nextTask.id, + from: 'term_coord', + terminal: 'term_worker' + })) as { state: string; lastError?: string } + + expect(attempted).toMatchObject({ state: 'failed' }) + expect(attempted.lastError).toMatch(/release.*progress/i) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + await expect( + call('orchestration.workerRelease', { dispatch: first.dispatchId }) + ).resolves.toMatchObject({ state: 'released' }) + expect(runtime.closeTerminal).toHaveBeenCalledTimes(1) + }) + + it('retains when persisted state has another resource for the exact terminal identity', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const raw = ( + db as unknown as { db: { prepare: (sql: string) => { run: (...args: unknown[]) => void } } } + ).db + raw + .prepare( + `INSERT INTO worker_terminal_resources ( + id, origin_dispatch_id, owner_dispatch_id, terminal_handle, pane_key, + process_incarnation, host_scope, ownership_state, release_state, retained_reason + ) VALUES ( + 'wtr_conflict', 'ctx_conflict', 'ctx_conflict', 'term_reminted', ?, ?, ?, + 'external', 'retained', 'legacy_ambiguous' + )` + ) + .run( + workerPaneKey, + 'runtime_test:term_worker:1', + JSON.stringify({ kind: 'local', hostId: 'local' }) + ) + + await expect( + call('orchestration.workerRelease', { dispatch: dispatchId }) + ).resolves.toMatchObject({ state: 'retained', reason: 'identity_unproven' }) + expect(runtime.closeTerminal).not.toHaveBeenCalled() + }) + + it('worker-retain records a durable user exception that release can later replace', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const retained = (await call('orchestration.workerRetain', { dispatch: dispatchId })) as { + state: string + reason?: string + } + expect(retained).toMatchObject({ state: 'retained', reason: 'user_requested' }) + expect(db.getWorkerTerminalResourceByOwner(dispatchId)?.release_state).toBe('retained') + + const release = (await call('orchestration.workerRelease', { dispatch: dispatchId })) as { + state: string + } + expect(release.state).toBe('released') + }) + + it('worker-list separates terminal accounting from Task outcome', async () => { + setup() + const active = await startWorker() + const perWorkerLookup = vi.spyOn(db, 'getWorkerTerminalResourceByOwner') + perWorkerLookup.mockClear() + const result1 = (await call('orchestration.workerList', { run: activeRunId })) as { + workers: { dispatchId: string; terminalState: string | null; workerState: string }[] + counts: Record + } + expect(result1.workers).toHaveLength(1) + expect(result1.workers[0]).toMatchObject({ + dispatchId: active.dispatchId, + terminalState: 'active', + workerState: 'ready' + }) + expect(perWorkerLookup).not.toHaveBeenCalled() + + settle(active.taskId, active.dispatchId, 'succeeded') + const result2 = (await call('orchestration.workerList', { + run: activeRunId, + terminalState: 'reclaimable' + })) as { workers: { dispatchId: string }[]; counts: Record } + expect(result2.workers.map((worker) => worker.dispatchId)).toEqual([active.dispatchId]) + expect(result2.counts).toMatchObject({ reclaimable: 1 }) + + await call('orchestration.workerRelease', { dispatch: active.dispatchId }) + const result3 = (await call('orchestration.workerList', { run: activeRunId })) as { + workers: { terminalState: string | null; workerState: string }[] + } + expect(result3.workers[0]).toMatchObject({ + terminalState: 'released', + workerState: 'succeeded' + }) + }) + + it('reports abandoned workers as retained instead of reclaimable', async () => { + setup() + const { dispatchId } = await startWorker() + await call('orchestration.workerAbandon', { dispatch: dispatchId }) + + const listed = (await call('orchestration.workerList', { run: activeRunId })) as { + workers: { dispatchId: string; terminalState: string | null }[] + } + + expect(listed.workers).toContainEqual( + expect.objectContaining({ dispatchId, terminalState: 'retained' }) + ) + await expect(call('orchestration.workerRelease', { dispatch: dispatchId })).rejects.toThrow( + /only a succeeded or failed worker can release/ + ) + }) + + it('worker-show exposes the terminal resource', async () => { + setup() + const { dispatchId } = await startSettledWorker() + const shown = (await call('orchestration.workerShow', { dispatch: dispatchId })) as { + terminalResource: { ownershipState: string; releaseState: string } | null + } + expect(shown.terminalResource).toMatchObject({ + ownershipState: 'owned', + releaseState: 'not_requested' + }) + }) +}) diff --git a/src/main/runtime/rpc/methods/orchestration-worker-release.ts b/src/main/runtime/rpc/methods/orchestration-worker-release.ts new file mode 100644 index 00000000000..f01cd72de47 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration-worker-release.ts @@ -0,0 +1,161 @@ +import { z } from 'zod' +import { OrchestrationError } from '../../orchestration/orchestration-error' +import type { WorkerTerminalListState } from '../../orchestration/worker-terminal-ownership' +import { defineMethod, type RpcMethod } from '../core' +import { requiredString } from '../schemas' +import { + archiveSummary, + completeWorkerTerminalRelease, + exposeWorkerTerminalResource, + type WorkerReleaseReceipt +} from './orchestration-worker-release-completion' + +const WorkerDispatchParams = z.object({ dispatch: requiredString('Missing --dispatch') }) + +const WORKER_TERMINAL_LIST_STATES = [ + 'active', + 'reclaimable', + 'retained', + 'release_pending', + 'release_unknown', + 'released' +] as const + +const WorkerListParams = z.object({ + run: z.string().min(1).optional(), + terminalState: z.enum(WORKER_TERMINAL_LIST_STATES).optional() +}) + +export const ORCHESTRATION_WORKER_RELEASE_METHODS: RpcMethod[] = [ + defineMethod({ + name: 'orchestration.workerRelease', + params: WorkerDispatchParams, + handler: async (params, { runtime }): Promise => { + const db = runtime.getOrchestrationDb() + if (db.getFederatedDispatch(params.dispatch)) { + // Fail closed: the worker server owns that terminal; a home-side close would be a guess. + return { + dispatchId: params.dispatch, + state: 'retained', + reason: 'federation_unsupported', + processAction: 'none', + archive: null, + recovery: + 'Connected-server workers do not support release yet; inspect the worker server directly.' + } + } + const requested = db.requestWorkerTerminalRelease(params.dispatch) + if (requested.disposition === 'already_released') { + return { + dispatchId: params.dispatch, + state: 'already_released', + processAction: 'none', + archive: archiveSummary(requested.resource) + } + } + if (requested.disposition === 'retained') { + return { + dispatchId: params.dispatch, + state: 'retained', + reason: requested.reason, + processAction: 'none', + archive: archiveSummary(requested.resource) + } + } + return completeWorkerTerminalRelease({ + runtime, + db, + dispatchId: params.dispatch, + resource: requested.resource + }) + } + }), + defineMethod({ + name: 'orchestration.workerRetain', + params: WorkerDispatchParams, + handler: (params, { runtime }) => { + const db = runtime.getOrchestrationDb() + if (!db.getWorkerDispatch(params.dispatch)) { + throw new OrchestrationError( + 'dispatch_not_found', + `Worker Dispatch ${params.dispatch} was not found.` + ) + } + const retained = db.retainWorkerTerminalResource(params.dispatch) + if (retained.disposition === 'already_released') { + return { + dispatchId: params.dispatch, + state: 'already_released' as const, + processAction: 'none' as const, + archive: archiveSummary(retained.resource) + } + } + if (retained.disposition === 'no_owned_resource') { + return { + dispatchId: params.dispatch, + state: 'retained' as const, + reason: 'no_owned_resource' as const, + processAction: 'none' as const, + archive: null + } + } + if (retained.disposition === 'release_committed') { + const unknown = retained.resource.release_state === 'unknown' + return { + dispatchId: params.dispatch, + state: unknown ? ('release_unknown' as const) : ('release_pending' as const), + processAction: 'none' as const, + archive: archiveSummary(retained.resource), + ...(retained.resource.release_error + ? { lastError: retained.resource.release_error } + : {}), + recovery: + 'Terminal release was already committed and could not be changed to retained; inspect worker-show before taking further action.' + } + } + return { + dispatchId: params.dispatch, + state: 'retained' as const, + reason: 'user_requested' as const, + processAction: 'none' as const, + archive: archiveSummary(retained.resource) + } + } + }), + defineMethod({ + name: 'orchestration.workerList', + params: WorkerListParams, + handler: (params, { runtime }) => { + const db = runtime.getOrchestrationDb() + const rows = db.listWorkerTerminalResources({ runId: params.run }) + const workers = rows + .filter((row) => !params.terminalState || row.terminalState === params.terminalState) + .map((row) => ({ + dispatchId: row.dispatchId, + taskId: row.taskId, + runId: row.runId, + workerState: row.workerState, + dispatchStatus: row.dispatchStatus, + agentTerminalHandle: row.agentTerminalHandle, + terminalState: row.terminalState, + resource: row.resource ? exposeWorkerTerminalResource(row.resource) : null + })) + const counts: Partial> = {} + for (const row of rows) { + if (row.terminalState) { + counts[row.terminalState] = (counts[row.terminalState] ?? 0) + 1 + } + } + return { workers, counts } + } + }), + defineMethod({ + name: 'orchestration.workerTerminalUserInput', + params: z.object({ paneKey: requiredString('Missing paneKey') }), + // Real user keystrokes durably relinquish orchestration ownership on the owning runtime, so + // restarts, SSH drops, remote viewing, and renderer remounts cannot erase the takeover. + handler: (params, { runtime }) => ({ + changed: runtime.getOrchestrationDb().markWorkerTerminalUserOwned(params.paneKey) + }) + }) +] diff --git a/src/main/runtime/rpc/methods/orchestration-worker-topology.ts b/src/main/runtime/rpc/methods/orchestration-worker-topology.ts index 474d3cb0316..6ecf8613a9b 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-topology.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-topology.ts @@ -47,7 +47,8 @@ export function requireWorkerAuthority(runtime: OrcaRuntimeService, terminalHand return { paneKey, processIncarnation, - ...(authority?.launchTokenHash ? { launchTokenHash: authority.launchTokenHash } : {}) + ...(authority?.launchTokenHash ? { launchTokenHash: authority.launchTokenHash } : {}), + ...(authority?.hostScope ? { hostScope: JSON.stringify(authority.hostScope) } : {}) } } @@ -59,7 +60,10 @@ export async function createExistingWorktreeWorkerTerminal(args: { effects: WorkerEffect[] }): Promise<{ handle: string; warning?: string }> { const terminal = await args.runtime.createTerminal(`id:${args.worktreeId}`, { - command: args.agent, + // Why: the agent id is not a shell command — `cursor` resolves to the Cursor + // desktop app while its CLI is `cursor-agent`. Let the runtime build the + // configured launcher instead of executing the raw id. + startupAgent: args.agent, title: `worker-${args.taskId}`, // Why: dispatching a worker is background work; it must not pull the sidebar // to the worker's workspace while the user is reading somewhere else. diff --git a/src/main/runtime/rpc/methods/orchestration-workers.ts b/src/main/runtime/rpc/methods/orchestration-workers.ts index 894be342f81..dc659773a8a 100644 --- a/src/main/runtime/rpc/methods/orchestration-workers.ts +++ b/src/main/runtime/rpc/methods/orchestration-workers.ts @@ -243,7 +243,8 @@ export const ORCHESTRATION_WORKER_START_METHODS: RpcMethod[] = [ ...terminalAuthority, worktreeId: resolvedWorktree.id, effects, - setupState: setupReceipt.state + setupState: setupReceipt.state, + terminalOwnership: params.terminal ? 'external' : 'created' }) failedStage = 'dispatch_input' diff --git a/src/main/runtime/rpc/methods/orchestration.test.ts b/src/main/runtime/rpc/methods/orchestration.test.ts index cb79b823255..8ba154c48f7 100644 --- a/src/main/runtime/rpc/methods/orchestration.test.ts +++ b/src/main/runtime/rpc/methods/orchestration.test.ts @@ -108,7 +108,11 @@ describe('orchestration RPC methods', () => { it('registers all expected methods', () => { const registry = buildRegistry(ORCHESTRATION_METHODS) - expect(registry.size).toBe(34) + expect(registry.size).toBe(38) + expect(registry.has('orchestration.workerRelease')).toBe(true) + expect(registry.has('orchestration.workerRetain')).toBe(true) + expect(registry.has('orchestration.workerList')).toBe(true) + expect(registry.has('orchestration.workerTerminalUserInput')).toBe(true) expect(registry.has('orchestration.runCreate')).toBe(true) expect(registry.has('orchestration.runUse')).toBe(true) expect(registry.has('orchestration.runCurrent')).toBe(true) @@ -1759,17 +1763,27 @@ describe('orchestration RPC methods', () => { expect(result.task.status).toBe('pending') }) - it('records the caller terminal handle when creating a task', async () => { + it('records the caller pane, process, and Run generation when creating a task', async () => { setup() vi.spyOn(runtime, 'getTerminalPaneKey').mockImplementation((handle) => handle === 'term_creator' ? coordinatorPaneKey : null ) + vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockReturnValue({ + terminalHandle: 'term_creator', + paneKey: coordinatorPaneKey, + processIncarnation: 'pty-creator:incarnation-a' + } as never) const result = (await call('orchestration.taskCreate', { spec: 'spawn related workspace', callerTerminalHandle: 'term_creator' })) as { task: { id: string } } - expect(db.getTask(result.task.id)?.created_by_terminal_handle).toBe('term_creator') + expect(db.getTask(result.task.id)).toMatchObject({ + created_by_terminal_handle: 'term_creator', + created_by_pane_key: coordinatorPaneKey, + created_by_process_incarnation: 'pty-creator:incarnation-a', + created_by_run_generation: 1 + }) }) it('rejects invalid deps JSON', async () => { @@ -1894,6 +1908,16 @@ describe('orchestration RPC methods', () => { vi.mocked(runtime.getTerminalPaneKey).mockImplementation((candidate) => candidate === handle ? `tab_worker:${handle}` : coordinatorPaneKey ) + vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockImplementation((candidate) => + candidate === handle + ? ({ + terminalHandle: handle, + paneKey: `tab_worker:${handle}`, + processIncarnation: `runtime_test:${handle}:1`, + launchTokenHash: null + } as never) + : null + ) } it('dispatches a task to a terminal', async () => { @@ -1925,7 +1949,7 @@ describe('orchestration RPC methods', () => { expect(db.getDispatchContextById(result.dispatch.id)?.assignee_pane_key).toBe('tab_w:leaf_w') }) - it('commits the target process launch token on a manual dispatch', async () => { + it('commits authenticated process authority on a manual dispatch', async () => { setup() vi.spyOn(runtime, 'getOrchestrationDispatchAuthority').mockReturnValue({ runtimeId: runtime.getRuntimeId(), @@ -1944,9 +1968,24 @@ describe('orchestration RPC methods', () => { to: 'term_a' })) as { dispatch: { id: string } } - expect(db.getDispatchContextById(result.dispatch.id)?.launch_token_hash).toBe( - 'launch-token-hash' - ) + expect(db.getDispatchContextById(result.dispatch.id)).toMatchObject({ + assignee_pane_key: 'tab_w:leaf_w', + process_incarnation: 'runtime_test:term_a:1', + launch_token_hash: 'launch-token-hash' + }) + }) + + it('does not infer manual process authority from an unauthenticated handle', async () => { + setup() + const task = db.createTask({ spec: 'work' }) + + const result = (await call('orchestration.dispatch', { + task: task.id, + to: 'term_a' + })) as { dispatch: { id: string } } + + expect(runtime.getTerminalProcessIncarnation('term_a')).toBe('runtime_test:term_a:1') + expect(db.getDispatchContextById(result.dispatch.id)?.process_incarnation).toBeNull() }) it('rejects dispatch for a pending task', async () => { @@ -2186,7 +2225,7 @@ describe('orchestration RPC methods', () => { // Why: dispatching a worker is background work — surfaceOwner:false adopts // the tab without scrolling the sidebar to the worker's workspace. expect(runtime.createTerminal).toHaveBeenCalledWith('id:repo::worktree', { - command: 'codex', + startupAgent: 'codex', title: `worker-${task.id}`, surfaceOwner: false }) @@ -2196,6 +2235,29 @@ describe('orchestration RPC methods', () => { ) }) + // Why: `cursor` on PATH is the Cursor desktop app; passing the agent id as a + // shell command opened the IDE and left a blank shell (issue #11926). + it('never passes the agent id to the worker terminal as a shell command', async () => { + setup() + mockCurrentWorkerStart() + const task = db.createTask({ spec: 'start a cursor worker' }) + + await call('orchestration.workerStart', { + task: task.id, + from: 'term_coord', + agent: 'cursor' + }) + + expect(runtime.createTerminal).toHaveBeenCalledWith( + 'id:repo::worktree', + expect.objectContaining({ startupAgent: 'cursor' }) + ) + expect(runtime.createTerminal).toHaveBeenCalledWith( + 'id:repo::worktree', + expect.not.objectContaining({ command: expect.anything() }) + ) + }) + it('commits the launched worker token with its durable authority', async () => { setup() mockCurrentWorkerStart() @@ -2289,7 +2351,7 @@ describe('orchestration RPC methods', () => { 'id:repo::other', // Why: starting a worker in an existing worktree must not pull the sidebar // away from whatever the user is looking at. - expect.objectContaining({ command: 'codex', surfaceOwner: false }) + expect.objectContaining({ startupAgent: 'codex', surfaceOwner: false }) ) expect(createWorktree).not.toHaveBeenCalled() }) diff --git a/src/main/runtime/rpc/methods/orchestration.ts b/src/main/runtime/rpc/methods/orchestration.ts index 4e200e1470f..0bdb24543a7 100644 --- a/src/main/runtime/rpc/methods/orchestration.ts +++ b/src/main/runtime/rpc/methods/orchestration.ts @@ -387,18 +387,29 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ params: SendParams, handler: async ( params, - { runtime, orchestrationCapability, legacyCoordinatorRunId, revalidateLegacyCoordinator } + { + runtime, + orchestrationCapability, + legacyCoordinatorRunId, + revalidateLegacyCoordinator, + orchestrationCompatibilityCallerAuthority + } ) => { const db = runtime.getOrchestrationDb() const from = params.from ?? 'unknown' - // Why: caller-supplied pane fields are only compatibility metadata; lifecycle authority uses the runtime-observed pane plus capability. - const senderPaneKey = runtime.getTerminalPaneKey(from) ?? undefined + const attestedCaller = + orchestrationCompatibilityCallerAuthority?.terminalHandle === from + ? orchestrationCompatibilityCallerAuthority + : undefined + // Why: attested hook identity survives graph remount; caller params never supply lifecycle authority. + const senderPaneKey = attestedCaller?.paneKey ?? runtime.getTerminalPaneKey(from) ?? undefined const remoteAttachment = senderPaneKey ? db.findActiveRemoteAttachmentForPane(senderPaneKey) : undefined if (remoteAttachment) { rejectFederatedExplicitTarget(params) - const processIncarnation = runtime.getTerminalProcessIncarnation(from) + const processIncarnation = + attestedCaller?.processIncarnation ?? runtime.getTerminalProcessIncarnation(from) if ( !db.verifyRemoteAttachmentAuthority({ dispatchId: remoteAttachment.dispatch_id, @@ -582,7 +593,10 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ dispatchId: dispatch.id, capability: orchestrationCapability, paneKey: senderPaneKey, - processIncarnation: runtime.getTerminalProcessIncarnation(from) ?? undefined + processIncarnation: + attestedCaller?.processIncarnation ?? + runtime.getTerminalProcessIncarnation(from) ?? + undefined }) if (!authority.valid) { const rejection = @@ -1086,6 +1100,16 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ throw new Error('Invalid --deps: must be a JSON array of task IDs') } } + const run = resolveRunScope(runtime, { + runId: params.run, + callerTerminalHandle: params.callerTerminalHandle, + requireCurrentConsumer: true, + legacyCoordinatorRunId, + callerEvidence: orchestrationCompatibilityEvidence + }) + const creatorAuthority = params.callerTerminalHandle + ? runtime.getOrchestrationDispatchAuthority(params.callerTerminalHandle) + : null const task = db.createTask({ spec: params.spec, taskTitle: params.taskTitle, @@ -1093,13 +1117,14 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ deps, parentId: params.parent, createdByTerminalHandle: params.callerTerminalHandle, - runId: resolveRunScope(runtime, { - runId: params.run, - callerTerminalHandle: params.callerTerminalHandle, - requireCurrentConsumer: true, - legacyCoordinatorRunId, - callerEvidence: orchestrationCompatibilityEvidence - }).id + ...(creatorAuthority?.paneKey && creatorAuthority.processIncarnation + ? { + createdByPaneKey: creatorAuthority.paneKey, + createdByProcessIncarnation: creatorAuthority.processIncarnation, + createdByRunGeneration: run.consumer_generation + } + : {}), + runId: run.id }) return { task } } @@ -1242,9 +1267,9 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ const assigneePaneKey = dispatchAuthority?.paneKey ?? runtime.getTerminalPaneKey(to) ?? undefined const processIncarnation = - dispatchAuthority?.processIncarnation ?? - runtime.getTerminalProcessIncarnation(to) ?? - undefined + dispatchAuthority?.paneKey && dispatchAuthority.processIncarnation + ? dispatchAuthority.processIncarnation + : undefined if (params.inject && (!assigneePaneKey || !processIncarnation)) { throw new OrchestrationError( 'stable_pane_required', @@ -1257,7 +1282,8 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [ params.task, to, assigneePaneKey, - dispatchAuthority?.launchTokenHash ?? undefined + dispatchAuthority?.launchTokenHash ?? undefined, + processIncarnation ) const dispatchCapability = params.inject ? db.mintDispatchCapability({ diff --git a/src/main/runtime/rpc/methods/session-tab-close-methods.ts b/src/main/runtime/rpc/methods/session-tab-close-methods.ts index eabffa24a73..8b17d946bdf 100644 --- a/src/main/runtime/rpc/methods/session-tab-close-methods.ts +++ b/src/main/runtime/rpc/methods/session-tab-close-methods.ts @@ -43,7 +43,11 @@ export const SESSION_TAB_CLOSE_METHODS: RpcAnyMethod[] = [ kind: 'client', attributes: { attribution: 'session-tab-close', + runtimeId: context.runtime.getRuntimeId(), origin: context.clientKind ?? 'in-process', + deviceId: context.pairedDeviceId ?? 'in-process', + worktree: params.worktree, + tabId: params.tabId, closeReason: params.reason ?? (requiresIntent @@ -85,7 +89,12 @@ export const SESSION_TAB_CLOSE_METHODS: RpcAnyMethod[] = [ kind: 'client', attributes: { attribution: 'session-tab-lifecycle-close', + runtimeId: context.runtime.getRuntimeId(), origin: context.clientKind ?? 'in-process', + deviceId: context.pairedDeviceId ?? 'in-process', + worktree: params.worktree, + tabId: params.tabId, + terminal: params.terminal, closeReason: params.reason, connectionGeneration: context.connectionId ?? 'in-process', requestId: context.requestId ?? 'in-process', diff --git a/src/main/runtime/rpc/methods/terminal.ts b/src/main/runtime/rpc/methods/terminal.ts index 450437f58be..edef5f44083 100644 --- a/src/main/runtime/rpc/methods/terminal.ts +++ b/src/main/runtime/rpc/methods/terminal.ts @@ -72,6 +72,7 @@ import { type TerminalOutputSourceRange } from '../../../../shared/terminal-output-source-range' import type { RemoteTerminalSourceRangeReplacementReservation } from '../../remote-terminal-source-range-consumer' +import { withTerminalCloseAttribution } from '../terminal-close-attribution' const REQUESTED_SNAPSHOT_BYTE_BUDGET = 2 * 1024 * 1024 const TERMINAL_OUTPUT_FLUSH_MS = 5 @@ -1499,15 +1500,27 @@ export const TERMINAL_METHODS: RpcAnyMethod[] = [ defineMethod({ name: 'terminal.close', params: TerminalHandle, - handler: async (params, { runtime }) => ({ - close: await runtime.closeTerminal(params.terminal) + handler: async (params, context) => ({ + close: await withTerminalCloseAttribution( + 'terminal.close', + context, + 'terminal', + params.terminal, + () => context.runtime.closeTerminal(params.terminal) + ) }) }), defineMethod({ name: 'terminal.closeTab', params: TerminalHandle, - handler: async (params, { runtime }) => ({ - close: await runtime.closeTerminalTab(params.terminal) + handler: async (params, context) => ({ + close: await withTerminalCloseAttribution( + 'terminal.closeTab', + context, + 'terminal-tab', + params.terminal, + () => context.runtime.closeTerminalTab(params.terminal) + ) }) }), defineMethod({ @@ -2974,8 +2987,10 @@ export const TERMINAL_METHODS: RpcAnyMethod[] = [ serialized: serialized?.data, oscLinks: serialized?.oscLinks, cwd: serialized?.cwd, - cols: serialized?.cols ?? size?.cols, - rows: serialized?.rows ?? size?.rows, + // Why: an empty snapshot with no PTY size must still report the dims the fit + // will produce — dimless frames re-armed the mobile fit loop (STA-3337). + cols: serialized?.cols ?? size?.cols ?? params.viewport?.cols, + rows: serialized?.rows ?? size?.rows ?? params.viewport?.rows, displayMode, seq }) @@ -3381,8 +3396,10 @@ export const TERMINAL_METHODS: RpcAnyMethod[] = [ }) const snapshotStats = sendSnapshotFrames(sendFrame, { kind: 'scrollback', - cols: serialized?.cols ?? size?.cols ?? 80, - rows: serialized?.rows ?? size?.rows ?? 24, + // Why: prefer the subscriber's viewport over the 80x24 stopgap when the PTY has + // no size yet — the mismatch made mobile burn its resubscribe budget (STA-3337). + cols: serialized?.cols ?? size?.cols ?? params.viewport?.cols ?? 80, + rows: serialized?.rows ?? size?.rows ?? params.viewport?.rows ?? 24, displayMode, seq: snapshotFrameSeq, cwd: serialized?.cwd, diff --git a/src/main/runtime/rpc/methods/worktree-rm-pty-waiver.test.ts b/src/main/runtime/rpc/methods/worktree-rm-pty-waiver.test.ts new file mode 100644 index 00000000000..3b51a57d054 --- /dev/null +++ b/src/main/runtime/rpc/methods/worktree-rm-pty-waiver.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, it, vi } from 'vitest' +import { RpcDispatcher } from '../dispatcher' +import type { RpcRequest } from '../core' +import type { OrcaRuntimeService } from '../../orca-runtime' +import { WORKTREE_METHODS } from './worktree' + +function makeRuntime(): OrcaRuntimeService { + return { + getRuntimeId: () => 'test-runtime', + dedupeWorktreeCreate: (_repo: string, _id: string | undefined, run: () => Promise) => + run(), + removeManagedWorktree: vi.fn().mockResolvedValue({}) + } as unknown as OrcaRuntimeService +} + +// Why (#11960): waiving the proof that every PTY stopped must ride its own field. +// The desktop sets `force` for an ordinary confirmed delete, so keying the waiver +// off `force` would silently disable the gate on the primary delete path. +describe('worktree.rm PTY-stop waiver', () => { + it('forwards an explicit waiver to the runtime', async () => { + const runtime = makeRuntime() + const dispatcher = new RpcDispatcher({ runtime, methods: WORKTREE_METHODS }) + + await dispatcher.dispatch({ + id: 'req-1', + authToken: 'tok', + method: 'worktree.rm', + params: { worktree: 'id:wt-1', force: true, allowUnverifiedPtyStop: true, runHooks: false } + } satisfies RpcRequest) + + expect(runtime.removeManagedWorktree).toHaveBeenCalledWith('id:wt-1', true, false, true) + }) + + it('does not infer a waiver from force alone', async () => { + const runtime = makeRuntime() + const dispatcher = new RpcDispatcher({ runtime, methods: WORKTREE_METHODS }) + + await dispatcher.dispatch({ + id: 'req-1', + authToken: 'tok', + method: 'worktree.rm', + params: { worktree: 'id:wt-1', force: true, runHooks: false } + } satisfies RpcRequest) + + expect(runtime.removeManagedWorktree).toHaveBeenCalledWith('id:wt-1', true, false, false) + }) +}) diff --git a/src/main/runtime/rpc/methods/worktree-schemas.ts b/src/main/runtime/rpc/methods/worktree-schemas.ts index 069a8499d18..57b8a9202a5 100644 --- a/src/main/runtime/rpc/methods/worktree-schemas.ts +++ b/src/main/runtime/rpc/methods/worktree-schemas.ts @@ -276,6 +276,10 @@ export const WorktreeSet = WorktreeSelector.extend({ export const WorktreeRemove = WorktreeSelector.extend({ force: OptionalBoolean, + // Why (#11960): the CLI's --force is an unambiguous force affordance, but the + // desktop sets `force` for an ordinary confirmed delete too, so the PTY-stop + // waiver travels on its own field. + allowUnverifiedPtyStop: OptionalBoolean, runHooks: OptionalBoolean }) diff --git a/src/main/runtime/rpc/methods/worktree.test.ts b/src/main/runtime/rpc/methods/worktree.test.ts index 10271681dc4..3fe4b5da15c 100644 --- a/src/main/runtime/rpc/methods/worktree.test.ts +++ b/src/main/runtime/rpc/methods/worktree.test.ts @@ -92,7 +92,8 @@ describe('worktree RPC methods', () => { }) ) - expect(runtime.removeManagedWorktree).toHaveBeenCalledWith('id:wt-1', true, false) + // Why (#11960): dirty-file force alone must not waive the PTY-stop proof. + expect(runtime.removeManagedWorktree).toHaveBeenCalledWith('id:wt-1', true, false, false) expect(response).toMatchObject({ ok: true, result: { removed: true } }) }) diff --git a/src/main/runtime/rpc/methods/worktree.ts b/src/main/runtime/rpc/methods/worktree.ts index dfa81dde1f5..758e6b83891 100644 --- a/src/main/runtime/rpc/methods/worktree.ts +++ b/src/main/runtime/rpc/methods/worktree.ts @@ -274,7 +274,8 @@ export const WORKTREE_METHODS: RpcMethod[] = [ const result = await runtime.removeManagedWorktree( params.worktree, params.force === true, - params.runHooks === true + params.runHooks === true, + params.allowUnverifiedPtyStop === true ) return { removed: true, ...result } } diff --git a/src/main/runtime/rpc/orchestration-legacy-compatibility.ts b/src/main/runtime/rpc/orchestration-legacy-compatibility.ts index 52b0fd0535b..f163b4e4278 100644 --- a/src/main/runtime/rpc/orchestration-legacy-compatibility.ts +++ b/src/main/runtime/rpc/orchestration-legacy-compatibility.ts @@ -65,11 +65,14 @@ export class OrchestrationLegacyCompatibility { return { handled: false } } const values = params as Record - if ( - CURRENT_AUTHORITY_PREFLIGHT_METHODS.has(request.method) && - this.usesCurrentAuthority(request, values) - ) { - return { handled: false } + if (CURRENT_AUTHORITY_PREFLIGHT_METHODS.has(request.method)) { + const callerAuthority = this.resolveCurrentAuthority(request, values) + if (callerAuthority) { + return { + handled: false, + orchestrationCompatibilityCallerAuthority: callerAuthority + } + } } const result = await this.route(request, params, signal) if (result !== undefined) { @@ -122,45 +125,48 @@ export class OrchestrationLegacyCompatibility { : undefined } - private usesCurrentAuthority(request: RpcRequest, params: Record): boolean { + private resolveCurrentAuthority( + request: RpcRequest, + params: Record + ): OrchestrationCompatibilityCallerAuthority | undefined { const db = this.runtime.getOrchestrationDb() const adoption = db.getLegacyAdoption() if (!adoption || stringValue(params.run) || request.method === 'orchestration.runUse') { - return false + return undefined } const evidence = request.orchestrationCompatibilityEvidence if (!evidence?.terminalHandle || !evidence.paneKey) { - return false + return undefined } const claimedHandle = currentCallerHandle(request.method, params) if (claimedHandle && claimedHandle !== evidence.terminalHandle) { - return false + return undefined } const dispatch = db.getActiveDispatchForIdentity(evidence.terminalHandle, evidence.paneKey) if (dispatch) { if (dispatch.contract_version !== CURRENT_CONTRACT_VERSION) { - return false + return undefined } const caller = this.runtime.verifyOrchestrationCompatibilityCaller(evidence) - return Boolean( - caller && + return caller && caller.terminalHandle === evidence.terminalHandle && db.getActiveDispatchForIdentity(caller.terminalHandle, caller.paneKey)?.id === dispatch.id - ) + ? caller + : undefined } const remoteAttachment = db.findActiveRemoteAttachmentForPane(evidence.paneKey) if (remoteAttachment) { const caller = this.runtime.verifyOrchestrationCompatibilityCaller(evidence) - return Boolean( - caller && + return caller && caller.terminalHandle === evidence.terminalHandle && db.findActiveRemoteAttachmentForPane(caller.paneKey)?.dispatch_id === remoteAttachment.dispatch_id - ) + ? caller + : undefined } const boundRun = db.getCurrentRunForPane(evidence.paneKey) if (!boundRun) { - return false + return undefined } const legacyCandidate = boundRun.id === adoption.adopted_run_id @@ -171,7 +177,7 @@ export class OrchestrationLegacyCompatibility { }) : undefined if (legacyCandidate) { - return false + return undefined } const caller = this.runtime.verifyOrchestrationCompatibilityCaller(evidence) if ( @@ -179,16 +185,18 @@ export class OrchestrationLegacyCompatibility { caller.terminalHandle !== evidence.terminalHandle || db.getCurrentRunForPane(caller.paneKey)?.id !== boundRun.id ) { - return false + return undefined } if (boundRun.id !== adoption.adopted_run_id) { - return true + return caller } return !db.resolveLegacyCoordinatorCandidate({ runId: adoption.adopted_run_id, terminalHandle: caller.terminalHandle, paneKey: caller.paneKey }) + ? caller + : undefined } private async route( diff --git a/src/main/runtime/rpc/orchestration-legacy-coordinator-race.test.ts b/src/main/runtime/rpc/orchestration-legacy-coordinator-race.test.ts index be5628df496..468f261b725 100644 --- a/src/main/runtime/rpc/orchestration-legacy-coordinator-race.test.ts +++ b/src/main/runtime/rpc/orchestration-legacy-coordinator-race.test.ts @@ -628,6 +628,16 @@ describe('legacy coordinator takeover races', () => { handle === COORDINATOR_HANDLE ? COORDINATOR_PANE : handle === targetHandle ? targetPane : null ) vi.spyOn(harness.runtime, 'getTerminalProcessIncarnation').mockReturnValue('current-process') + vi.spyOn(harness.runtime, 'getOrchestrationDispatchAuthority').mockImplementation((handle) => + handle === targetHandle + ? ({ + terminalHandle: targetHandle, + paneKey: targetPane, + processIncarnation: 'current-process', + launchTokenHash: null + } as never) + : null + ) let resolveDetection: ((detected: boolean) => void) | undefined let signalDetectionStarted: (() => void) | undefined const detectionStarted = new Promise((resolve) => { diff --git a/src/main/runtime/rpc/orchestration-mutation-executor.ts b/src/main/runtime/rpc/orchestration-mutation-executor.ts index 66918510b56..2334cd709eb 100644 --- a/src/main/runtime/rpc/orchestration-mutation-executor.ts +++ b/src/main/runtime/rpc/orchestration-mutation-executor.ts @@ -54,6 +54,8 @@ export class OrchestrationMutationExecutor { return { disposition: row.state, row } })() : db.beginMutationReceipt(identity) + const resumedPendingMutation = + begun.disposition === 'pending' && request.method === 'orchestration.workerRelease' if (begun.disposition === 'completed') { const active = this.inFlight.get(key) @@ -67,33 +69,35 @@ export class OrchestrationMutationExecutor { if (active) { return attachMutationReceipt(await active, requestId, true) } - const recovery = getPendingWorkerStartRecovery(request.method, begun.row.receipt) - throw new OrchestrationError( - 'operation_unknown', - recovery - ? `Worker start ${requestId} was accepted as Dispatch ${recovery.dispatchId} before restart. Inspect that Dispatch; do not start another worker.` - : `Mutation ${requestId} may have been accepted before restart. Retry inspection or recovery with the same request ID.`, - recovery - ? { - requestId, - dispatchId: recovery.dispatchId, - recoveryCommand: `orca orchestration worker-show --dispatch ${recovery.dispatchId} --json` - } - : { requestId } - ) + if (request.method !== 'orchestration.workerRelease') { + const recovery = getPendingWorkerStartRecovery(request.method, begun.row.receipt) + throw new OrchestrationError( + 'operation_unknown', + recovery + ? `Worker start ${requestId} was accepted as Dispatch ${recovery.dispatchId} before restart. Inspect that Dispatch; do not start another worker.` + : `Mutation ${requestId} may have been accepted before restart. Retry inspection or recovery with the same request ID.`, + recovery + ? { + requestId, + dispatchId: recovery.dispatchId, + recoveryCommand: `orca orchestration worker-show --dispatch ${recovery.dispatchId} --json` + } + : { requestId } + ) + } } const recordReceipt = (result: unknown): void => { db.completeMutationReceipt({ ...identity, - receipt: JSON.stringify(attachMutationReceipt(result, requestId, false)) + receipt: JSON.stringify(attachMutationReceipt(result, requestId, resumedPendingMutation)) }) } const active = Promise.resolve().then(() => invoke({ identity, recordReceipt })) this.inFlight.set(key, active) try { const result = await active - const receipted = attachMutationReceipt(result, requestId, false) + const receipted = attachMutationReceipt(result, requestId, resumedPendingMutation) db.completeMutationReceipt({ ...identity, receipt: JSON.stringify(receipted) }) return receipted } catch (error) { diff --git a/src/main/runtime/rpc/orchestration-mutation-ledger.test.ts b/src/main/runtime/rpc/orchestration-mutation-ledger.test.ts index 8e02d9c8e24..4062dacf9a1 100644 --- a/src/main/runtime/rpc/orchestration-mutation-ledger.test.ts +++ b/src/main/runtime/rpc/orchestration-mutation-ledger.test.ts @@ -196,6 +196,54 @@ describe('durable orchestration mutation ledger', () => { db.close() }) + it('resumes a pending idempotent worker release after restart', async () => { + const db = new OrchestrationDb(':memory:') + const runtime = new OrcaRuntimeService() + runtime.setOrchestrationDb(db) + const params = { dispatch: 'ctx_release' } + const callerFingerprint = createHash('sha256').update('caller-token').digest('hex') + const payloadHash = createHash('sha256') + .update(JSON.stringify({ method: 'orchestration.workerRelease', params })) + .digest('hex') + db.beginMutationReceipt({ + callerFingerprint, + requestId: 'mutation_release', + method: 'orchestration.workerRelease', + payloadHash + }) + const effect = vi.fn().mockReturnValue({ state: 'release_pending' }) + const dispatcher = new RpcDispatcher({ + runtime, + methods: [ + defineMethod({ + name: 'orchestration.workerRelease', + params: z.object({ dispatch: z.string() }), + handler: effect + }) + ] + }) + + const result = await dispatcher.dispatch({ + id: 'rpc_release_retry', + authToken: 'caller-token', + method: 'orchestration.workerRelease', + params, + orchestrationContractVersion: ORCHESTRATION_CONTRACT_VERSION, + orchestrationRequestId: 'mutation_release' + }) + + expect(result).toMatchObject({ + ok: true, + result: { + state: 'release_pending', + mutation: { requestId: 'mutation_release', replayed: true } + } + }) + expect(effect).toHaveBeenCalledTimes(1) + expect(db.getMutationReceipt(callerFingerprint, 'mutation_release')?.state).toBe('completed') + db.close() + }) + it('returns the accepted Dispatch when worker-start was interrupted by restart', async () => { const db = new OrchestrationDb(':memory:') const runtime = new OrcaRuntimeService() diff --git a/src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts b/src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts new file mode 100644 index 00000000000..57ac1b014ff --- /dev/null +++ b/src/main/runtime/rpc/orchestration-runtime-update-settlement.test.ts @@ -0,0 +1,428 @@ +import { createHash } from 'node:crypto' +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it, vi } from 'vitest' +import { ORCHESTRATION_CONTRACT_VERSION } from '../../../shared/protocol-version' +import Database from '../../sqlite/sync-database' +import { OrcaRuntimeService } from '../orca-runtime' +import { OrchestrationDb } from '../orchestration/db' +import type { RpcRequest, RpcResponse } from './core' +import { RpcDispatcher } from './dispatcher' +import { ORCHESTRATION_METHODS } from './methods/orchestration' + +const WORKER_HANDLE = 'term_pre_update_worker' +const WORKER_PANE = 'tab_pre_update:33333333-3333-4333-8333-333333333333' +const COORDINATOR_HANDLE = 'term_pre_update_coordinator' +const CURRENT_COORDINATOR_HANDLE = 'term_current_coordinator' +const CURRENT_COORDINATOR_PANE = 'tab_current:44444444-4444-4444-8444-444444444444' +const PROCESS_INCARNATION = 'pty-stable:incarnation-stable' +const CURRENT_COORDINATOR_PROCESS_INCARNATION = + 'pty-current-coordinator:incarnation-current-coordinator' +const WORK_BYTES = Buffer.from('preserved filesystem work\n', 'utf8') + +type Harness = { + db: OrchestrationDb + createDispatcher: () => RpcDispatcher + taskId: string + dispatchId: string + capability: string + adoptedRunId: string + markerPath: string +} + +type UpdateRpcRequest = RpcRequest & { + compatibilityInvocationId?: string + orchestrationCompatibilityEvidence?: { + terminalHandle?: string + paneKey?: string + launchToken?: string + } +} + +const harnesses: Harness[] = [] +const tempDirs: string[] = [] + +afterEach(() => { + for (const harness of harnesses.splice(0)) { + harness.db.close() + } + for (const dir of tempDirs.splice(0)) { + rmSync(dir, { recursive: true, force: true }) + } +}) + +function createUpdateHarness(): Harness { + const dir = mkdtempSync(join(tmpdir(), 'orca-update-settlement-')) + tempDirs.push(dir) + const markerPath = join(dir, 'worker-result.txt') + const dbPath = join(dir, 'orchestration.db') + writeFileSync(markerPath, WORK_BYTES) + + const oldRuntimeDb = new OrchestrationDb(dbPath) + const task = oldRuntimeDb.createTask({ + spec: 'finish work across an app update', + createdByTerminalHandle: COORDINATOR_HANDLE + }) + const dispatch = oldRuntimeDb.createDispatchContext(task.id, WORKER_HANDLE, WORKER_PANE) + const capability = oldRuntimeDb.mintDispatchCapability({ + dispatchId: dispatch.id, + paneKey: WORKER_PANE, + processIncarnation: PROCESS_INCARNATION + }) + oldRuntimeDb.close() + + const raw = new Database(dbPath) + raw.exec(` + DROP INDEX IF EXISTS idx_messages_delivery_contract; + DROP TABLE IF EXISTS legacy_mail_receipts; + DROP TABLE IF EXISTS legacy_operation_receipts; + DROP TABLE IF EXISTS legacy_compatibility_principals; + DROP TABLE IF EXISTS legacy_adoptions; + `) + raw.pragma('user_version = 18') + raw.close() + + const db = new OrchestrationDb(dbPath) + const adoptedRunId = db.getTask(task.id)?.run_id + expect(adoptedRunId).toBeTruthy() + const createDispatcher = (): RpcDispatcher => { + const authorities = [ + { + handle: WORKER_HANDLE, + paneKey: WORKER_PANE, + ptyId: 'pty-stable', + incarnationId: 'incarnation-stable', + launchToken: 'worker-launch-token' + }, + { + handle: CURRENT_COORDINATOR_HANDLE, + paneKey: CURRENT_COORDINATOR_PANE, + ptyId: 'pty-current-coordinator', + incarnationId: 'incarnation-current-coordinator', + launchToken: 'current-coordinator-launch-token' + } + ] + const runtime = new OrcaRuntimeService(null, undefined, { + attestAgentHookCompatibilityAuthority: ({ paneKey, launchTokenHash }) => { + const authority = authorities.find((candidate) => candidate.paneKey === paneKey) + return authority && + createHash('sha256').update(authority.launchToken).digest('hex') === launchTokenHash + ? { paneKey, source: 'hydrated_commitment' } + : null + } + }) + const internals = runtime as unknown as { + recordPtyWorktree: (ptyId: string, worktreeId: string, state: Record) => void + issuePtyHandle: (pty: unknown) => string + ptysById: Map + handleByPtyId: Map + restoredOrchestrationAuthorityByPtyId: Map> + } + for (const authority of authorities) { + internals.recordPtyWorktree(authority.ptyId, 'repo::/retained-worktree', { + connected: true, + paneKey: authority.paneKey, + incarnationId: authority.incarnationId + }) + internals.handleByPtyId.set(authority.ptyId, authority.handle) + internals.issuePtyHandle(internals.ptysById.get(authority.ptyId)) + internals.restoredOrchestrationAuthorityByPtyId.set(authority.ptyId, { + ptyId: authority.ptyId, + worktreeId: 'repo::/retained-worktree', + terminalHandle: authority.handle, + paneKey: authority.paneKey, + processIncarnation: `${authority.ptyId}:${authority.incarnationId}`, + hostScope: { kind: 'local', hostId: 'local' } + }) + } + runtime.setOrchestrationDb(db) + vi.spyOn(runtime, 'getTerminalPaneKey').mockReturnValue(null) + const getProcessIncarnation = runtime.getTerminalProcessIncarnation.bind(runtime) + vi.spyOn(runtime, 'getTerminalProcessIncarnation') + .mockImplementationOnce(getProcessIncarnation) + .mockReturnValue(null) + vi.spyOn(runtime, 'notifyMessageArrived').mockImplementation(() => {}) + return new RpcDispatcher({ runtime, methods: ORCHESTRATION_METHODS }) + } + const harness = { + db, + createDispatcher, + taskId: task.id, + dispatchId: dispatch.id, + capability, + adoptedRunId: adoptedRunId as string, + markerPath + } + harnesses.push(harness) + return harness +} + +function request( + method: string, + params: Record, + role: 'worker' | 'current-coordinator', + invocationId: string +): UpdateRpcRequest { + const worker = role === 'worker' + return { + id: `rpc_${invocationId}`, + authToken: 'caller-token', + method, + params, + orchestrationContractVersion: ORCHESTRATION_CONTRACT_VERSION, + orchestrationRequestId: invocationId, + compatibilityInvocationId: invocationId, + orchestrationCompatibilityEvidence: { + terminalHandle: worker ? WORKER_HANDLE : CURRENT_COORDINATOR_HANDLE, + paneKey: worker ? WORKER_PANE : CURRENT_COORDINATOR_PANE, + launchToken: `${role}-launch-token` + } + } as unknown as UpdateRpcRequest +} + +function entityCounts(db: OrchestrationDb): Record { + const sqlite = (db as unknown as { db: Database.Database }).db + return Object.fromEntries( + ['tasks', 'dispatch_contexts', 'messages', 'legacy_compatibility_principals'].map((table) => [ + table, + (sqlite.prepare(`SELECT COUNT(*) AS count FROM ${table}`).get() as { count: number }).count + ]) + ) +} + +function resultOf(response: RpcResponse): Record { + expect(response.ok).toBe(true) + if (!response.ok) { + throw new Error(response.error.message) + } + return response.result as Record +} + +function expectIdentityAndWorkPreserved(harness: Harness): void { + expect(harness.db.getDispatchContextById(harness.dispatchId)).toMatchObject({ + id: harness.dispatchId, + task_id: harness.taskId, + assignee_handle: WORKER_HANDLE, + assignee_pane_key: WORKER_PANE, + process_incarnation: PROCESS_INCARNATION + }) + expect(readFileSync(harness.markerPath)).toEqual(WORK_BYTES) +} + +describe('orchestration runtime update settlement', () => { + it('settles one retained worker report exactly once after its pane handle is orphaned', async () => { + const harness = createUpdateHarness() + const completion = request( + 'orchestration.send', + { + from: WORKER_HANDLE, + to: COORDINATOR_HANDLE, + type: 'worker_done', + subject: 'Completed', + body: 'work survived the update', + payload: JSON.stringify({ + taskId: harness.taskId, + dispatchId: harness.dispatchId, + outcome: 'succeeded', + filesModified: ['worker-result.txt'] + }) + }, + 'worker', + 'retained-worker-done' + ) + completion.orchestrationCapability = harness.capability + + const first = await harness.createDispatcher().dispatch(completion) + const replay = await harness.createDispatcher().dispatch({ ...completion, id: 'rpc_replay' }) + const firstResult = resultOf(first) + const replayResult = resultOf(replay) + + expect(firstResult).toMatchObject({ message: { type: 'worker_done' } }) + expect(replayResult).toMatchObject({ + message: firstResult.message, + mutation: { requestId: 'retained-worker-done', replayed: true } + }) + expect(harness.db.getTask(harness.taskId)).toMatchObject({ status: 'completed' }) + expect(harness.db.getDispatchContextById(harness.dispatchId)).toMatchObject({ + status: 'completed' + }) + expect(entityCounts(harness.db)).toEqual({ + tasks: 1, + dispatch_contexts: 1, + messages: 1, + legacy_compatibility_principals: 0 + }) + expectIdentityAndWorkPreserved(harness) + }) + + it('allows only the attested current coordinator to take over retained live work', async () => { + const harness = createUpdateHarness() + const takeover = request( + 'orchestration.runUse', + { + id: harness.adoptedRunId, + from: CURRENT_COORDINATOR_HANDLE, + takeoverLegacy: true + }, + 'current-coordinator', + 'authenticated-takeover' + ) + + const spoofed = await harness.createDispatcher().dispatch({ + ...takeover, + id: 'rpc_spoofed', + params: { ...(takeover.params as Record), from: COORDINATOR_HANDLE } + }) + const first = await harness.createDispatcher().dispatch(takeover) + const replay = await harness + .createDispatcher() + .dispatch({ ...takeover, id: 'rpc_takeover_replay' }) + const firstResult = resultOf(first) + const replayResult = resultOf(replay) + + expect(spoofed).toMatchObject({ ok: false, error: { code: 'stable_pane_required' } }) + expect(firstResult).toMatchObject({ + run: { + id: harness.adoptedRunId, + coordinator_handle: CURRENT_COORDINATOR_HANDLE, + coordinator_pane_key: CURRENT_COORDINATOR_PANE + } + }) + expect(replayResult).toMatchObject({ + run: firstResult.run, + mutation: { requestId: 'authenticated-takeover', replayed: true } + }) + expect(harness.db.getTask(harness.taskId)).toMatchObject({ status: 'dispatched' }) + expect(harness.db.getDispatchContextById(harness.dispatchId)).toMatchObject({ + status: 'dispatched' + }) + expect(entityCounts(harness.db)).toEqual({ + tasks: 1, + dispatch_contexts: 1, + messages: 0, + legacy_compatibility_principals: 0 + }) + expectIdentityAndWorkPreserved(harness) + }) + + it('rejects a current worker whose claimed pane lacks exact attestation', async () => { + const harness = createUpdateHarness() + const completion = request( + 'orchestration.send', + { + from: WORKER_HANDLE, + to: COORDINATOR_HANDLE, + type: 'worker_done', + subject: 'Completed', + body: 'forged completion', + payload: JSON.stringify({ + taskId: harness.taskId, + dispatchId: harness.dispatchId, + outcome: 'succeeded' + }) + }, + 'worker', + 'forged-worker-done' + ) + completion.orchestrationCapability = harness.capability + completion.orchestrationCompatibilityEvidence = { + ...completion.orchestrationCompatibilityEvidence!, + paneKey: 'tab_foreign:99999999-9999-4999-8999-999999999999' + } + + const response = await harness.createDispatcher().dispatch(completion) + + expect(response).toMatchObject({ + ok: true, + result: { + lifecycle: { + action: 'rejected', + code: 'dispatch_capability_invalid', + reason: 'The caller is not the Dispatch pane.' + } + } + }) + expect(harness.db.getTask(harness.taskId)).toMatchObject({ status: 'dispatched' }) + expect(harness.db.getDispatchContextById(harness.dispatchId)).toMatchObject({ + status: 'dispatched' + }) + expectIdentityAndWorkPreserved(harness) + }) + + it('routes ordinary mail with the same attested authority without settling work', async () => { + const harness = createUpdateHarness() + const response = await harness.createDispatcher().dispatch( + request( + 'orchestration.send', + { + from: WORKER_HANDLE, + to: COORDINATOR_HANDLE, + type: 'status', + subject: 'Retained worker checkpoint', + body: readFileSync(harness.markerPath, 'utf8') + }, + 'worker', + 'retained-worker-status' + ) + ) + + expect(resultOf(response)).toMatchObject({ + message: { type: 'status', body: WORK_BYTES.toString('utf8') } + }) + expect(harness.db.getTask(harness.taskId)).toMatchObject({ status: 'dispatched' }) + expect(harness.db.getDispatchContextById(harness.dispatchId)).toMatchObject({ + status: 'dispatched' + }) + expect(entityCounts(harness.db)).toEqual({ + tasks: 1, + dispatch_contexts: 1, + messages: 1, + legacy_compatibility_principals: 0 + }) + expectIdentityAndWorkPreserved(harness) + }) + + it('uses attested process authority when a remote attachment loses runtime lookup', async () => { + const harness = createUpdateHarness() + const attachment = { + dispatch_id: 'dispatch-remote-retained', + task_id: 'task-remote-retained', + process_incarnation: CURRENT_COORDINATOR_PROCESS_INCARNATION + } + vi.spyOn(harness.db, 'findActiveRemoteAttachmentForPane').mockReturnValue(attachment as never) + const verifyAuthority = vi + .spyOn(harness.db, 'verifyRemoteAttachmentAuthority') + .mockReturnValue(true) + vi.spyOn(harness.db, 'enqueueFederationRelay').mockReturnValue({ + message_id: 'relay-retained-status', + sequence: 1, + dispatch_id: attachment.dispatch_id + } as never) + + const response = await harness.createDispatcher().dispatch({ + ...request( + 'orchestration.send', + { + from: CURRENT_COORDINATOR_HANDLE, + type: 'status', + subject: 'Retained remote checkpoint', + body: 'remote work survived' + }, + 'current-coordinator', + 'retained-remote-status' + ), + orchestrationCapability: 'dcap_remote_retained' + }) + + expect(resultOf(response)).toMatchObject({ + relay: { dispatchId: attachment.dispatch_id, accepted: true } + }) + expect(verifyAuthority).toHaveBeenCalledWith({ + dispatchId: attachment.dispatch_id, + capability: 'dcap_remote_retained', + paneKey: CURRENT_COORDINATOR_PANE, + processIncarnation: CURRENT_COORDINATOR_PROCESS_INCARNATION + }) + }) +}) diff --git a/src/main/runtime/rpc/runtime-close-attribution-topology.test.ts b/src/main/runtime/rpc/runtime-close-attribution-topology.test.ts new file mode 100644 index 00000000000..4e1232e7358 --- /dev/null +++ b/src/main/runtime/rpc/runtime-close-attribution-topology.test.ts @@ -0,0 +1,211 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { _resetTracerForTests, setActiveSink, type TracerSink } from '../../observability/tracer' +import type { OrcaRuntimeService } from '../orca-runtime' +import type { RpcRequest } from './core' +import { RpcDispatcher } from './dispatcher' +import { SESSION_TAB_METHODS } from './methods/session-tabs' +import { TERMINAL_METHODS } from './methods/terminal' + +const BEARER_CLIENT_ID = 'secret-bearer-client-id' + +type SpanRecord = { + name: string + attributes: Record + exit: { _tag: string } +} + +function request(id: string, method: string, params: unknown): RpcRequest { + return { id, authToken: 'test-token', method, params } +} + +describe('runtime close attribution topology', () => { + const records: SpanRecord[] = [] + + beforeEach(() => { + records.length = 0 + setActiveSink({ + push: (record) => records.push(record as SpanRecord), + flush: vi.fn(), + close: vi.fn() + } satisfies TracerSink) + }) + + afterEach(() => _resetTracerForTests()) + + it('identifies the authoritative runtime and target for remote, stale, and legacy closes', async () => { + const closeMobileSessionTab = vi + .fn() + .mockResolvedValueOnce({ closed: true, refused: true, refusalReason: 'stale-terminal' }) + .mockResolvedValue({ closed: true }) + const runtime = { + getRuntimeId: () => 'runtime-owner-1', + closeMobileSessionTab, + refuseUnattributedMobileSessionTabClose: vi.fn().mockResolvedValue({ closed: true }) + } as unknown as OrcaRuntimeService + const dispatcher = new RpcDispatcher({ runtime, methods: SESSION_TAB_METHODS }) + + await dispatcher.dispatchStreaming( + request('stale-1', 'session.tabs.closeLifecycle', { + worktree: 'id:worktree-a', + tabId: 'tab-a', + reason: 'cleanup', + publicationEpoch: 'epoch-old', + terminal: 'terminal-old' + }), + vi.fn(), + { + clientId: BEARER_CLIENT_ID, + pairedDeviceId: 'device-1', + connectionId: 'connection-before-reconnect', + clientKind: 'runtime' + } + ) + await dispatcher.dispatchStreaming( + request('legacy-1', 'session.tabs.close', { + worktree: 'id:worktree-b', + tabId: 'tab-b' + }), + vi.fn(), + { + clientId: BEARER_CLIENT_ID, + pairedDeviceId: 'device-1', + connectionId: 'connection-after-reconnect', + clientKind: 'runtime', + clientCapabilities: [] + } + ) + + expect(records).toHaveLength(2) + expect(records[0]).toMatchObject({ + name: 'runtime.session-tabs.close-lifecycle', + attributes: { + runtimeId: 'runtime-owner-1', + worktree: 'id:worktree-a', + tabId: 'tab-a', + terminal: 'terminal-old', + deviceId: 'device-1', + connectionGeneration: 'connection-before-reconnect', + requestId: 'stale-1', + decision: 'refused-stale-terminal' + }, + exit: { _tag: 'Success' } + }) + expect(records[1]).toMatchObject({ + name: 'runtime.session-tabs.close', + attributes: { + runtimeId: 'runtime-owner-1', + worktree: 'id:worktree-b', + tabId: 'tab-b', + deviceId: 'device-1', + connectionGeneration: 'connection-after-reconnect', + requestId: 'legacy-1', + closeReason: 'legacy-runtime-user', + decision: 'allowed' + } + }) + expect(JSON.stringify(records)).not.toContain(BEARER_CLIENT_ID) + }) + + it('keeps concurrent cross-worktree request and target identities distinct', async () => { + const closeMobileSessionTab = vi.fn().mockResolvedValue({ closed: true }) + const runtime = { + getRuntimeId: () => 'runtime-owner-2', + closeMobileSessionTab + } as unknown as OrcaRuntimeService + const dispatcher = new RpcDispatcher({ runtime, methods: SESSION_TAB_METHODS }) + + await Promise.all( + ( + [ + ['request-a', 'device-a', 'connection-a', 'worktree-a', 'tab-a'], + ['request-b', 'device-b', 'connection-b', 'worktree-b', 'tab-b'] + ] as const + ).map(([id, deviceId, connectionId, worktree, tabId]) => + dispatcher.dispatchStreaming( + request(id, 'session.tabs.close', { + worktree: `id:${worktree}`, + tabId, + reason: 'user' + }), + vi.fn(), + { clientKind: 'runtime', pairedDeviceId: deviceId, connectionId } + ) + ) + ) + + expect(records.map((record) => record.attributes)).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + runtimeId: 'runtime-owner-2', + worktree: 'id:worktree-a', + tabId: 'tab-a', + deviceId: 'device-a', + connectionGeneration: 'connection-a', + requestId: 'request-a' + }), + expect.objectContaining({ + runtimeId: 'runtime-owner-2', + worktree: 'id:worktree-b', + tabId: 'tab-b', + deviceId: 'device-b', + connectionGeneration: 'connection-b', + requestId: 'request-b' + }) + ]) + ) + expect(closeMobileSessionTab).toHaveBeenCalledTimes(2) + }) + + it('records resolved terminal outcome and failed unowned requests without extra inventory', async () => { + const closeTerminal = vi + .fn() + .mockResolvedValueOnce({ handle: 'terminal-live', tabId: 'tab-live', ptyKilled: true }) + .mockRejectedValueOnce(new Error('terminal_handle_stale')) + const listSessions = vi.fn() + const runtime = { + getRuntimeId: () => 'runtime-owner-3', + closeTerminal, + listSessions + } as unknown as OrcaRuntimeService + const dispatcher = new RpcDispatcher({ runtime, methods: TERMINAL_METHODS }) + const context = { + clientKind: 'runtime' as const, + pairedDeviceId: 'device-terminal', + connectionId: 'connection-terminal' + } + + await dispatcher.dispatchStreaming( + request('terminal-live-request', 'terminal.close', { terminal: 'terminal-live' }), + vi.fn(), + context + ) + await dispatcher.dispatchStreaming( + request('terminal-stale-request', 'terminal.close', { terminal: 'terminal-stale' }), + vi.fn(), + context + ) + + expect(records[0]).toMatchObject({ + attributes: { + runtimeId: 'runtime-owner-3', + terminal: 'terminal-live', + tabId: 'tab-live', + ptyKilled: true, + decision: 'allowed', + outcome: 'succeeded' + }, + exit: { _tag: 'Success' } + }) + expect(records[1]).toMatchObject({ + attributes: { + runtimeId: 'runtime-owner-3', + terminal: 'terminal-stale', + decision: 'allowed', + outcome: 'failed' + }, + exit: { _tag: 'Failure' } + }) + expect(closeTerminal).toHaveBeenCalledTimes(2) + expect(listSessions).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/runtime/rpc/runtime-close-attribution.test.ts b/src/main/runtime/rpc/runtime-close-attribution.test.ts new file mode 100644 index 00000000000..0073348ec56 --- /dev/null +++ b/src/main/runtime/rpc/runtime-close-attribution.test.ts @@ -0,0 +1,129 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { _resetTracerForTests, setActiveSink, type TracerSink } from '../../observability/tracer' +import type { OrcaRuntimeService } from '../orca-runtime' +import { RpcDispatcher } from './dispatcher' +import type { RpcRequest } from './core' +import { SESSION_TAB_METHODS } from './methods/session-tabs' +import { TERMINAL_METHODS } from './methods/terminal' + +const BEARER_CLIENT_ID = 'secret-bearer-client-id' + +type CapturingSink = TracerSink & { records: unknown[] } + +function capturingSink(): CapturingSink { + const records: unknown[] = [] + return { + records, + push: (record) => records.push(record), + flush: vi.fn(), + close: vi.fn() + } +} + +function request(method: string, params: unknown): RpcRequest { + return { id: 'close-request-1', authToken: 'test-token', method, params } +} + +describe('runtime close attribution', () => { + let sink: CapturingSink + + beforeEach(() => { + sink = capturingSink() + setActiveSink(sink) + }) + + afterEach(() => { + _resetTracerForTests() + }) + + it.each([ + ['terminal.close', 'closeTerminal', 'terminal'], + ['terminal.closeTab', 'closeTerminalTab', 'terminal-tab'] + ] as const)( + 'records %s with the device identity and without the bearer credential', + async (method, call, targetKind) => { + const close = vi.fn().mockResolvedValue({ handle: 'term-1', ptyKilled: true }) + const runtime = { + getRuntimeId: () => 'test-runtime', + [call]: close + } as unknown as OrcaRuntimeService + const dispatcher = new RpcDispatcher({ runtime, methods: TERMINAL_METHODS }) + const replies: string[] = [] + + await dispatcher.dispatchStreaming( + request(method, { terminal: 'term-1' }), + (reply) => replies.push(reply), + { + clientId: BEARER_CLIENT_ID, + pairedDeviceId: 'device-uuid-123', + connectionId: 'connection-7', + clientKind: 'runtime' + } + ) + + expect(JSON.parse(replies[0]!)).toMatchObject({ ok: true }) + expect(close).toHaveBeenCalledWith('term-1') + expect(sink.records).toEqual([ + expect.objectContaining({ + type: 'effect-span', + name: method, + attributes: expect.objectContaining({ + attribution: 'terminal-close', + origin: 'runtime', + deviceId: 'device-uuid-123', + connectionGeneration: 'connection-7', + requestId: 'close-request-1', + targetKind, + terminal: 'term-1', + decision: 'allowed' + }), + exit: { _tag: 'Success' } + }) + ]) + expect(JSON.stringify(sink.records)).not.toContain(BEARER_CLIENT_ID) + } + ) + + it.each([ + [ + 'session.tabs.close', + { worktree: 'id:wt-1', tabId: 'tab-1', reason: 'user' }, + 'runtime.session-tabs.close' + ], + [ + 'session.tabs.closeLifecycle', + { + worktree: 'id:wt-1', + tabId: 'tab-1', + reason: 'pty-exit', + publicationEpoch: 'epoch-1', + terminal: 'term-1' + }, + 'runtime.session-tabs.close-lifecycle' + ] + ] as const)( + 'records the device identity for %s without the bearer credential', + async (method, params, spanName) => { + const runtime = { + getRuntimeId: () => 'test-runtime', + closeMobileSessionTab: vi.fn().mockResolvedValue({ closed: true }) + } as unknown as OrcaRuntimeService + const dispatcher = new RpcDispatcher({ runtime, methods: SESSION_TAB_METHODS }) + + await dispatcher.dispatchStreaming(request(method, params), vi.fn(), { + clientId: BEARER_CLIENT_ID, + pairedDeviceId: 'device-uuid-123', + connectionId: 'connection-7', + clientKind: 'runtime' + }) + + expect(sink.records).toEqual([ + expect.objectContaining({ + name: spanName, + attributes: expect.objectContaining({ deviceId: 'device-uuid-123' }) + }) + ]) + expect(JSON.stringify(sink.records)).not.toContain(BEARER_CLIENT_ID) + } + ) +}) diff --git a/src/main/runtime/rpc/terminal-close-attribution.ts b/src/main/runtime/rpc/terminal-close-attribution.ts new file mode 100644 index 00000000000..01eaa4e05a4 --- /dev/null +++ b/src/main/runtime/rpc/terminal-close-attribution.ts @@ -0,0 +1,50 @@ +import { withSpan } from '../../observability/tracer' +import type { RuntimeTerminalClose } from '../../../shared/runtime-types' +import type { RpcContext } from './core' + +type TerminalCloseMethod = 'terminal.close' | 'terminal.closeTab' +type TerminalCloseTargetKind = 'terminal' | 'terminal-tab' + +export function withTerminalCloseAttribution( + method: TerminalCloseMethod, + context: Pick< + RpcContext, + 'runtime' | 'clientKind' | 'pairedDeviceId' | 'connectionId' | 'requestId' + >, + targetKind: TerminalCloseTargetKind, + terminal: string, + close: () => Promise +): Promise { + return withSpan( + method, + async (span) => { + span.setAttribute('decision', 'allowed') + try { + const result = await close() + span.setAttribute('outcome', 'succeeded') + span.setAttribute('tabId', result.tabId) + span.setAttribute('ptyKilled', result.ptyKilled) + if (result.closeMode) { + span.setAttribute('closeMode', result.closeMode) + } + return result + } catch (error) { + span.setAttribute('outcome', 'failed') + throw error + } + }, + { + kind: 'client', + attributes: { + attribution: 'terminal-close', + runtimeId: context.runtime.getRuntimeId(), + origin: context.clientKind ?? 'in-process', + deviceId: context.pairedDeviceId ?? 'in-process', + connectionGeneration: context.connectionId ?? 'in-process', + requestId: context.requestId ?? 'in-process', + targetKind, + terminal + } + } + ) +} diff --git a/src/main/runtime/rpc/ws-transport.ts b/src/main/runtime/rpc/ws-transport.ts index 8d4a765de01..1444813fd65 100644 --- a/src/main/runtime/rpc/ws-transport.ts +++ b/src/main/runtime/rpc/ws-transport.ts @@ -127,6 +127,12 @@ export class WebSocketTransport implements RpcTransport { return this.port } + // Why: the actual OS-reported bind interface, so callers can verify loopback vs all-interfaces (STA-2370). + get resolvedHost(): string | null { + const addr = this.httpServer?.address() + return addr && typeof addr === 'object' ? addr.address : null + } + async start(): Promise { if (this.wss) { return diff --git a/src/main/runtime/runtime-rpc.test.ts b/src/main/runtime/runtime-rpc.test.ts index fe44dc64b22..609079305c5 100644 --- a/src/main/runtime/runtime-rpc.test.ts +++ b/src/main/runtime/runtime-rpc.test.ts @@ -24,6 +24,7 @@ import { encodeTerminalStreamText } from '../../shared/terminal-stream-protocol' import { decrypt, deriveSharedKey, encrypt, generateKeyPair } from './rpc/e2ee-crypto' +import { WebSocketTransport } from './rpc/ws-transport' import { DeviceRegistry } from './device-registry' import { DEVICE_REGISTRY_FILENAME, E2EE_KEYPAIR_FILENAME } from './mobile-pairing-files' import { ORCHESTRATION_CONTRACT_VERSION } from '../../shared/protocol-version' @@ -5481,3 +5482,377 @@ describe('OrcaRuntimeRpcServer', () => { }) }) }) + +describe('OrcaRuntimeRpcServer WebSocket bind host (STA-2370)', () => { + const wsTransportOf = (server: OrcaRuntimeRpcServer): WebSocketTransport | undefined => + (server['activeTransports'] as unknown[]).find( + (transport): transport is WebSocketTransport => transport instanceof WebSocketTransport + ) + + it('binds the listener to loopback on a fresh desktop with no paired device', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + expect(server.getDeviceRegistry()?.listDevices()).toHaveLength(0) + // Why: the exposure regression — before STA-2370 this bound 0.0.0.0 with zero devices paired. + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + expect(new URL(server.getWebSocketEndpoint()!).hostname).toBe('127.0.0.1') + } finally { + await server.stop() + } + }) + + it('widens the listener to all interfaces when a mobile pairing offer is created', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + const loopbackPort = wsTransportOf(server)?.resolvedPort + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + + const offer = await server.createMobilePairingOffer({ + address: '100.64.1.20', + connectionMode: 'local-only' + }) + expect(offer.available).toBe(true) + + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + expect(new URL(server.getWebSocketEndpoint()!).hostname).toBe('0.0.0.0') + // Why: the widen reuses the same port so the QR's already-advertised endpoint stays valid. + expect(wsTransportOf(server)?.resolvedPort).toBe(loopbackPort) + } finally { + await server.stop() + } + }) + + it('binds all interfaces at startup when exposeNetworkByDefault is set (orca serve)', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0, + exposeNetworkByDefault: true + }) + + await server.start() + try { + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + expect(new URL(server.getWebSocketEndpoint()!).hostname).toBe('0.0.0.0') + } finally { + await server.stop() + } + }) + + it('binds all interfaces at startup when a previously-connected device can reconnect', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + // Why: a device that has actually connected (lastSeenAt > 0) may reconnect, so the listener must be + // reachable at startup without waiting for a new pairing action. + const registry = new DeviceRegistry(userDataPath) + const device = registry.getOrCreatePendingDevice('Paired phone', 'mobile') + registry.updateLastSeen(device.deviceId) + + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + expect( + server + .getDeviceRegistry() + ?.listDevices() + .some((d) => d.lastSeenAt > 0) + ).toBe(true) + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + } finally { + await server.stop() + } + }) + + it('stays on loopback at startup for a pending device that has never connected', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + // Why: a pending device (offer created but never connected: lastSeenAt === 0) is not a reconnect, so + // the listener must stay loopback — this distinguishes the reconnect widen from a blanket any-device + // widen (a revert to listDevices().length > 0 would wrongly expose the LAN here). + const registry = new DeviceRegistry(userDataPath) + registry.getOrCreatePendingDevice('Pending phone', 'mobile') + + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + expect(server.getDeviceRegistry()?.listDevices()).toHaveLength(1) + expect( + server + .getDeviceRegistry() + ?.listDevices() + .every((d) => d.lastSeenAt === 0) + ).toBe(true) + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + } finally { + await server.stop() + } + }) + + it('keeps the same MobileSocketWiring instance across a pairing widen (relay capture stays valid)', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + const wiringBeforeWiden = server.getMobileSocketWiring() + expect(wiringBeforeWiden).not.toBeNull() + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + + const offer = await server.createMobilePairingOffer({ + address: '100.64.1.20', + connectionMode: 'local-only' + }) + expect(offer.available).toBe(true) + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + + // Why: DesktopRelayService captures the wiring once at construction and hands it to every relay + // broker, so the widen must swap the transport under the SAME wiring — replacing the wiring would + // strand relay sockets on a dead object (lost connection IDs, binary handling, revocation targeting). + expect(server.getMobileSocketWiring()).toBe(wiringBeforeWiden) + + // Why: object identity alone would pass even if the post-widen transport were never re-attached to the + // captured wiring. Prove the swap functionally — route a revocation through the pre-widen wiring and + // assert it reaches the NEW (0.0.0.0) transport, confirming attachTransport ran on the same wiring + // after the rebind. A revert that leaves the wiring pointed at the stopped loopback transport fails here. + const widenedTransport = wsTransportOf(server) + expect(widenedTransport).toBeDefined() + const terminateSpy = vi.spyOn(widenedTransport!, 'terminateClientConnections') + wiringBeforeWiden!.terminateDeviceConnections('device-token-xyz') + expect(terminateSpy).toHaveBeenCalledWith('device-token-xyz') + } finally { + await server.stop() + } + }) + + it('coalesces concurrent pairing widens into a single rebind', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + const widenSpy = vi.spyOn( + server as unknown as { widenWebSocketBind: () => Promise }, + 'widenWebSocketBind' + ) + + await Promise.all([server.ensureNetworkExposure(), server.ensureNetworkExposure()]) + + // Why: two racing pairing offers must share one rebind via networkExposurePromise — two competing + // stop/start races would fight for the port and could strand the listener on a random one. + expect(widenSpy).toHaveBeenCalledTimes(1) + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + } finally { + await server.stop() + } + }) + + it('reports pairing unavailable but keeps a serving loopback listener when the widen bind fails', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + const loopbackPort = wsTransportOf(server)?.resolvedPort + // Why: force the wide bind to throw AFTER the loopback listener is stopped, then let the loopback + // recovery bind through — proving no stranded/closed socket and a retry-able state. + const target = server as unknown as { + startWebSocketTransport: (opts: { host: string }) => Promise + wsBoundHost: string | null + } + const original = target.startWebSocketTransport.bind(server) + vi.spyOn(target, 'startWebSocketTransport').mockImplementation(async (opts) => { + if (opts.host === '0.0.0.0') { + throw new Error('injected wide bind failure') + } + return original(opts) + }) + + const offer = await server.createMobilePairingOffer({ + address: '100.64.1.20', + connectionMode: 'local-only' + }) + // Why: a failed widen must NOT advertise a LAN endpoint with no LAN listener behind it — the offer is + // reported unavailable (STA-2370). A revert that swallows the widen failure would return available:true. + expect(offer.available).toBe(false) + if (!offer.available) { + expect(offer.reason).toBe('network_exposure_failed') + } + // Why: the listener must keep serving on loopback (same port) rather than being left stranded/closed. + expect(wsTransportOf(server)?.resolvedHost).toBe('127.0.0.1') + expect(wsTransportOf(server)?.resolvedPort).toBe(loopbackPort) + // Why: wsBoundHost stays loopback so a later pairing offer retries the widen. + expect(target.wsBoundHost).toBe('127.0.0.1') + } finally { + await server.stop() + errorSpy.mockRestore() + } + }) + + it('keeps the widened listener tracked when persisting pairing metadata fails', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + try { + // Why: fail metadata publication AFTER the wide bind already succeeded. The live 0.0.0.0 listener must + // stay tracked in activeTransports — a revert that runs loopback recovery here orphans a running wide + // listener (an untracked 0.0.0.0 socket outside stop(): the exact STA-2370 exposure). + const target = server as unknown as { + writeMetadata: () => void + wsBoundHost: string | null + activeTransports: unknown[] + } + let injected = false + const originalWrite = target.writeMetadata.bind(server) + vi.spyOn(target, 'writeMetadata').mockImplementation(() => { + if (!injected && target.wsBoundHost === '0.0.0.0') { + injected = true + throw new Error('injected metadata write failure') + } + return originalWrite() + }) + + const offer = await server.createMobilePairingOffer({ + address: '100.64.1.20', + connectionMode: 'local-only' + }) + expect(injected).toBe(true) + // Why: only metadata persistence failed; the wide bind succeeded, so pairing is available and the wide + // listener is tracked (not orphaned) — bound to all interfaces, exactly one WebSocket transport. + expect(offer.available).toBe(true) + expect(wsTransportOf(server)?.resolvedHost).toBe('0.0.0.0') + expect(target.activeTransports.filter((t) => t instanceof WebSocketTransport)).toHaveLength(1) + } finally { + await server.stop() + errorSpy.mockRestore() + } + }) + + it('does not strand a wide listener when stop() races an in-flight widen', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + + const target = server as unknown as { + startWebSocketTransport: (opts: { + host: string + }) => Promise<{ transport: WebSocketTransport; endpoint: string }> + activeTransports: unknown[] + } + const original = target.startWebSocketTransport.bind(server) + let releaseWideStart: () => void = () => {} + const wideStartGate = new Promise((resolve) => { + releaseWideStart = resolve + }) + let wideStopSpy: ReturnType | null = null + vi.spyOn(target, 'startWebSocketTransport').mockImplementation(async (opts) => { + if (opts.host === '0.0.0.0') { + // Why: hold the widen mid-flight (loopback already stopped) so stop() must race the rebind. + await wideStartGate + const result = await original(opts) + wideStopSpy = vi.spyOn(result.transport, 'stop') + return result + } + return original(opts) + }) + + // Why: begin a pairing widen but do not await it, then start shutdown while it is still in-flight. + const widen = server.ensureNetworkExposure() + const stopping = server.stop() + releaseWideStart() + await Promise.all([widen.catch(() => {}), stopping]) + + try { + // Why: STA-2370 — stop() must fence and await the in-flight widen so the freshly-bound wide listener is + // snapshotted and stopped, never written back into the cleared arrays as a live 0.0.0.0 leak. A revert + // (no fence) leaves the wide transport in activeTransports after stop() and never calls its stop(). + expect(target.activeTransports).toHaveLength(0) + expect(wideStopSpy).not.toBeNull() + expect(wideStopSpy).toHaveBeenCalled() + } finally { + errorSpy.mockRestore() + } + }) + + it('refuses to widen a pairing offer that arrives after the server has stopped', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-rpc-')) + const server = new OrcaRuntimeRpcServer({ + runtime: new OrcaRuntimeService(), + userDataPath, + enableWebSocket: true, + wsPort: 0 + }) + + await server.start() + const widenSpy = vi.spyOn( + server as unknown as { widenWebSocketBind: () => Promise }, + 'widenWebSocketBind' + ) + await server.stop() + + // Why: STA-2370 — the `stopping` fence must reject a widen that arrives on its own AFTER shutdown, not + // only one already in-flight during stop() (covered above via the pending-exposure await). Reverting the + // `stopping` guard alone still passes the race test, but here ensureNetworkExposure would re-enter + // widenWebSocketBind and re-open a 0.0.0.0 listener on a server that is supposed to be down. + await server.ensureNetworkExposure() + expect(widenSpy).not.toHaveBeenCalled() + }) +}) diff --git a/src/main/runtime/runtime-rpc.ts b/src/main/runtime/runtime-rpc.ts index 48903b5a1fe..f6274c3a996 100644 --- a/src/main/runtime/runtime-rpc.ts +++ b/src/main/runtime/runtime-rpc.ts @@ -5,6 +5,7 @@ import { readdirSync, rmSync } from 'node:fs' import { join } from 'node:path' import type { RuntimeMetadata, RuntimeTransportMetadata } from '../../shared/runtime-bootstrap' import type { OrcaRuntimeService } from './orca-runtime' +import { NETWORK_EXPOSURE_FAILED_GUIDANCE } from './network-exposure-guidance' import { writeRuntimeMetadata } from './runtime-metadata' import { RUNTIME_METADATA_OWNERSHIP_POLL_MS, @@ -53,6 +54,11 @@ import { const DEFAULT_WS_PORT = 6768 +// Why: STA-2370 — the WS listener defaults to loopback so a desktop with no paired device is not +// reachable from the LAN; it widens to all interfaces only on explicit pairing (or `orca serve`). +const WS_BIND_HOST_LOOPBACK = '127.0.0.1' +const WS_BIND_HOST_ALL_INTERFACES = '0.0.0.0' + type OrcaRuntimeRpcServerOptions = { runtime: OrcaRuntimeService userDataPath: string @@ -62,6 +68,9 @@ type OrcaRuntimeRpcServerOptions = { wsPort?: number // Why: true when the caller pinned a port (`orca serve --port`) so bind order prefers it over a stale STA-1511 fallback (#8535). preferPinnedWsPort?: boolean + // Why: STA-2370 — bind the WS listener to all interfaces at startup instead of loopback-until-paired. + // Only `orca serve` (explicit remote opt-in) and E2E set this; the desktop app widens lazily on pairing. + exposeNetworkByDefault?: boolean webClientRoot?: string // Why: test-only overrides for the two constants below; production must not pass these (defaults set by §3.1). keepaliveIntervalMs?: number @@ -76,6 +85,7 @@ export type PairingOfferUnavailableReason = | 'e2ee_key_unavailable' | 'invalid_advertised_endpoint' | 'relay_mint_failed' + | 'network_exposure_failed' export type PairingOfferUnavailable = { available: false @@ -472,7 +482,15 @@ export class OrcaRuntimeRpcServer { private readonly enableWebSocket: boolean private readonly wsPort: number private readonly preferPinnedWsPort: boolean + private readonly exposeNetworkByDefault: boolean private readonly webClientRoot: string | undefined + // Why: STA-2370 — the host the WS listener is currently bound to, so pairing can widen loopback→all-interfaces once. + private wsBoundHost: string | null = null + // Why: STA-2370 — in-flight widen so concurrent pairing requests share a single rebind. + private networkExposurePromise: Promise | null = null + // Why: STA-2370 — set by stop() so a racing pairing widen can't recreate a live wide listener into the + // cleared transport arrays after shutdown; stop() also awaits any in-flight widen before snapshotting. + private stopping = false private readonly authToken = randomBytes(24).toString('hex') private readonly keepaliveIntervalMs: number private readonly longPollCap: number @@ -487,6 +505,9 @@ export class OrcaRuntimeRpcServer { private transports: RuntimeTransportMetadata[] = [] private metadataOwnershipWatch: RuntimeMetadataOwnershipWatch | null = null private mobileSocketWiring: MobileSocketWiring | null = null + // Why: detaches the current WebSocketTransport from the session wiring so a pairing rebind can swap + // transports under the SAME wiring (see ensureMobileSocketWiring) instead of orphaning relay sockets. + private detachWebSocketWiring: (() => void) | null = null private mobileRelayPairingProvider: MobileRelayPairingProvider | null = null private mobileRelayPairingOfferQueue: Promise = Promise.resolve() private mobileRelayPairingOfferInFlight: { @@ -519,6 +540,7 @@ export class OrcaRuntimeRpcServer { enableWebSocket = false, wsPort = DEFAULT_WS_PORT, preferPinnedWsPort = false, + exposeNetworkByDefault = false, webClientRoot, keepaliveIntervalMs = KEEPALIVE_INTERVAL_MS, longPollCap = LONG_POLL_CAP, @@ -532,6 +554,7 @@ export class OrcaRuntimeRpcServer { this.enableWebSocket = enableWebSocket this.wsPort = wsPort this.preferPinnedWsPort = preferPinnedWsPort + this.exposeNetworkByDefault = exposeNetworkByDefault this.webClientRoot = webClientRoot this.keepaliveIntervalMs = keepaliveIntervalMs this.longPollCap = longPollCap @@ -704,6 +727,18 @@ export class OrcaRuntimeRpcServer { name?: string rotate?: boolean }): Promise { + // Why: STA-2370 — creating a mobile pairing offer is the user's explicit opt-in to LAN reach, so + // widen the loopback listener before advertising its LAN endpoint in the QR. If the widen fails the + // listener stays on loopback, so report unavailable rather than advertise a dead LAN endpoint. + try { + await this.ensureNetworkExposure() + } catch (error) { + console.error( + '[runtime] Network exposure failed while creating a mobile pairing offer:', + error + ) + return pairingUnavailable('network_exposure_failed', NETWORK_EXPOSURE_FAILED_GUIDANCE) + } if (args.connectionMode === 'local-only') { this.mobilePairingOfferGeneration += 1 return this.createMobilePairingOfferSerial(args, this.mobilePairingOfferGeneration) @@ -1136,74 +1171,19 @@ export class OrcaRuntimeRpcServer { this.e2eeKeypair = pairingIdentity.e2eeKeypair this.pairingInitializationFailure = null try { - const wsTransport = new WebSocketTransport({ - host: '0.0.0.0', + const host = this.resolveInitialWebSocketBindHost() + const { transport, endpoint } = await this.startWebSocketTransport({ + host, port: this.wsPort, - staticRoot: this.webClientRoot, + preferPinnedPort: this.preferPinnedWsPort, // Why: stable fallback port across restarts keeps paired devices' endpoints valid (STA-1511); wsPort 0 = random (E2E). - ...(this.wsPort !== 0 ? { fallbackPort: readWsFallbackPort(this.userDataPath) } : {}), - ...(this.preferPinnedWsPort ? { preferPinnedPort: true } : {}) + ...(this.wsPort !== 0 ? { fallbackPort: readWsFallbackPort(this.userDataPath) } : {}) }) - // Why: session-scoped (recreated per start) so each desktop launch may notify once. - this.unpairedDeviceAuthThrottle = new UnpairedDeviceAuthThrottle({ - onTrigger: () => this.onUnpairedDeviceAuthFailure?.() - }) - const mobileSocketWiring = new MobileSocketWiring({ - deviceRegistry: pairingIdentity.deviceRegistry, - e2eeKeypair: pairingIdentity.e2eeKeypair, - onText: (socket, plaintext, reply, sendBinary) => { - void this.handleWebSocketMessage( - plaintext, - reply, - sendBinary, - undefined, - socket.ws, - socket.device.deviceToken, - socket - ) - }, - onBinary: (socket, bytes) => this.handleWebSocketBinaryMessage(bytes, socket.ws), - onReady: () => { - // Why: first authenticated mobile/remote client (direct WS and - // cloud relay both attach here) starts path-candidate tracking. - // Activation is a local-host concern: candidate buffers live on the - // buffer-owning host's runtime, so a remote runtime proxy may - // legitimately lack this method (its own server activates it). - this.runtime.activateRecentPtyPathCandidateTracking?.() - this.mobileRelayPairingProvider?.onDemandStateChanged?.() - }, - onClose: (socket, hasOtherConnections) => { - if (!socket) { - return - } - this.abortWebSocketDispatches(socket.ws) - // Why: subscriptions and binary streams are socket-scoped, but disconnect state is device-scoped across transports. - this.runtime.cleanupSubscriptionsForConnection(socket.connectionId) - this.runtime.cancelMobileDictationForConnection(socket.connectionId) - this.binaryStreamHandlers.delete(socket.connectionId) - if (!hasOtherConnections) { - this.runtime.onClientDisconnected(socket.device.deviceToken) - } - }, - // Why: relay attempts are authorized upstream; only direct failures should prompt local re-pairing. - onUnpairedDeviceAuthFailure: (metadata) => { - if (metadata.transport === 'direct') { - this.unpairedDeviceAuthThrottle?.recordFailure() - } - } - }) - mobileSocketWiring.attachTransport(wsTransport) - this.mobileSocketWiring = mobileSocketWiring - - await wsTransport.start() - if (this.wsPort !== 0 && wsTransport.resolvedPort !== this.wsPort) { - writeWsFallbackPort(this.userDataPath, wsTransport.resolvedPort) + if (this.wsPort !== 0 && transport.resolvedPort !== this.wsPort) { + writeWsFallbackPort(this.userDataPath, transport.resolvedPort) } - activeTransports.push(wsTransport) - transportsMeta.push({ - kind: 'websocket', - endpoint: `ws://0.0.0.0:${wsTransport.resolvedPort}` - }) + activeTransports.push(transport) + transportsMeta.push({ kind: 'websocket', endpoint }) } catch (error) { // Why: WebSocket transport is supplementary; on failure (e.g. port in use) continue with Unix socket only. console.error('[runtime] Failed to start WebSocket transport:', error) @@ -1246,18 +1226,267 @@ export class OrcaRuntimeRpcServer { }) } + // Why: STA-2370 — a desktop with no previously-connected device stays on loopback until the user + // explicitly pairs; `orca serve`/E2E (exposeNetworkByDefault) and a reconnecting paired device bind wide. + private resolveInitialWebSocketBindHost(): string { + if (this.exposeNetworkByDefault) { + return WS_BIND_HOST_ALL_INTERFACES + } + const hasConnectedDevice = + this.deviceRegistry?.listDevices().some((device) => device.lastSeenAt > 0) ?? false + return hasConnectedDevice ? WS_BIND_HOST_ALL_INTERFACES : WS_BIND_HOST_LOOPBACK + } + + // Why: builds and starts a WS transport bound to `host`, wiring the session-scoped mobile socket + // handlers. Shared by initial start() and the pairing-time widen so both paths stay identical. + private async startWebSocketTransport(options: { + host: string + port: number + preferPinnedPort: boolean + fallbackPort?: number + }): Promise<{ transport: WebSocketTransport; endpoint: string }> { + const deviceRegistry = this.deviceRegistry + const e2eeKeypair = this.e2eeKeypair + if (!deviceRegistry || !e2eeKeypair) { + throw new Error('WebSocket transport requires an initialized pairing identity') + } + const wsTransport = new WebSocketTransport({ + host: options.host, + port: options.port, + staticRoot: this.webClientRoot, + ...(options.fallbackPort !== undefined ? { fallbackPort: options.fallbackPort } : {}), + ...(options.preferPinnedPort ? { preferPinnedPort: true } : {}) + }) + const mobileSocketWiring = this.ensureMobileSocketWiring(deviceRegistry, e2eeKeypair) + this.detachWebSocketWiring = mobileSocketWiring.attachTransport(wsTransport) + + try { + await wsTransport.start() + } catch (error) { + // Why: a listener that never bound must not stay attached to the session wiring (it would leak into + // terminateDeviceConnections); detach before propagating so the wiring only tracks live transports. + this.detachWebSocketWiring?.() + this.detachWebSocketWiring = null + throw error + } + this.wsBoundHost = options.host + return { + transport: wsTransport, + endpoint: `ws://${options.host}:${wsTransport.resolvedPort}` + } + } + + // Why: one MobileSocketWiring per server session. Direct WS and cloud relay both attach to it, and + // DesktopRelayService captures it once at construction, so a loopback→wide pairing rebind must swap the + // transport under the SAME wiring — replacing the wiring would strand relay sockets (lost connection IDs, + // binary handling, and revocation targeting) on a dead object. + private ensureMobileSocketWiring( + deviceRegistry: DeviceRegistry, + e2eeKeypair: E2EEKeypair + ): MobileSocketWiring { + if (this.mobileSocketWiring) { + return this.mobileSocketWiring + } + // Why: session-scoped so each desktop launch may notify once (a mid-session rebind must not reset it). + this.unpairedDeviceAuthThrottle = new UnpairedDeviceAuthThrottle({ + onTrigger: () => this.onUnpairedDeviceAuthFailure?.() + }) + const mobileSocketWiring = new MobileSocketWiring({ + deviceRegistry, + e2eeKeypair, + onText: (socket, plaintext, reply, sendBinary) => { + void this.handleWebSocketMessage( + plaintext, + reply, + sendBinary, + undefined, + socket.ws, + socket.device.deviceToken, + socket + ) + }, + onBinary: (socket, bytes) => this.handleWebSocketBinaryMessage(bytes, socket.ws), + onReady: () => { + // Why: first authenticated mobile/remote client (direct WS and + // cloud relay both attach here) starts path-candidate tracking. + // Activation is a local-host concern: candidate buffers live on the + // buffer-owning host's runtime, so a remote runtime proxy may + // legitimately lack this method (its own server activates it). + this.runtime.activateRecentPtyPathCandidateTracking?.() + this.mobileRelayPairingProvider?.onDemandStateChanged?.() + }, + onClose: (socket, hasOtherConnections) => { + if (!socket) { + return + } + this.abortWebSocketDispatches(socket.ws) + // Why: subscriptions and binary streams are socket-scoped, but disconnect state is device-scoped across transports. + this.runtime.cleanupSubscriptionsForConnection(socket.connectionId) + this.runtime.cancelMobileDictationForConnection(socket.connectionId) + this.binaryStreamHandlers.delete(socket.connectionId) + if (!hasOtherConnections) { + this.runtime.onClientDisconnected(socket.device.deviceToken) + } + }, + // Why: relay attempts are authorized upstream; only direct failures should prompt local re-pairing. + onUnpairedDeviceAuthFailure: (metadata) => { + if (metadata.transport === 'direct') { + this.unpairedDeviceAuthThrottle?.recordFailure() + } + } + }) + this.mobileSocketWiring = mobileSocketWiring + return mobileSocketWiring + } + + // Why: STA-2370 — widen the loopback listener to all interfaces so a freshly generated pairing + // offer's advertised LAN endpoint is reachable. Idempotent and only ever runs on the first opt-in + // (before any device has connected), so no live socket is disrupted; the resolved port is reused so + // an already-issued endpoint stays valid. + async ensureNetworkExposure(): Promise { + if ( + !this.enableWebSocket || + this.stopping || + this.wsBoundHost === WS_BIND_HOST_ALL_INTERFACES + ) { + return + } + // Why: concurrent pairing requests must share one rebind — two simultaneous stop/start races would + // fight for the port and strand the listener on a random one. + if (!this.networkExposurePromise) { + this.networkExposurePromise = this.widenWebSocketBind().finally(() => { + this.networkExposurePromise = null + }) + } + return this.networkExposurePromise + } + + private async widenWebSocketBind(): Promise { + const current = this.activeTransports.find( + (transport): transport is WebSocketTransport => transport instanceof WebSocketTransport + ) + if (!current) { + return + } + const index = this.activeTransports.indexOf(current) + const previousPort = current.resolvedPort + let widened: { transport: WebSocketTransport; endpoint: string } + try { + // Why: detach the loopback listener from the session wiring before stopping it so terminateDevice- + // Connections never iterates a dead transport; the new listener re-attaches to the SAME wiring. + this.detachWebSocketWiring?.() + await current.stop() + widened = await this.startWebSocketTransport({ + host: WS_BIND_HOST_ALL_INTERFACES, + port: previousPort, + preferPinnedPort: true + }) + } catch (error) { + // Why: the wide bind failed after the loopback listener was already stopped. Restore a serving + // loopback listener on the same port (wsBoundHost stays loopback so a later offer retries), then + // propagate — the caller must not advertise a LAN endpoint with no LAN listener behind it (STA-2370). + console.error('[runtime] Failed to widen WebSocket transport for pairing:', error) + await this.recoverWebSocketBindAfterFailedWiden(index, previousPort) + throw error + } + // Why: register the live wide transport BEFORE persisting metadata so a metadata-write failure can + // never orphan a running 0.0.0.0 listener outside activeTransports (and thus outside stop()). + this.activeTransports[index] = widened.transport + const metaIndex = this.transports.findIndex((meta) => meta.kind === 'websocket') + if (metaIndex >= 0) { + this.transports[metaIndex] = { kind: 'websocket', endpoint: widened.endpoint } + } + try { + // Why: a rebind that lands on a different port (same-port bind refused) must be persisted so a + // later reconnect from a device paired to this port matches on the next launch (STA-1511). + if (this.wsPort !== 0 && widened.transport.resolvedPort !== this.wsPort) { + writeWsFallbackPort(this.userDataPath, widened.transport.resolvedPort) + } + this.writeMetadata() + } catch (persistError) { + // Why: the wide listener is live and tracked; a persistence failure must not tear it down. Keep + // serving — the in-memory endpoint is already correct. + console.error( + '[runtime] Widened WebSocket listener but failed to persist pairing metadata:', + persistError + ) + } + } + + // Why: a failed widen already tore down the loopback listener; bring one back on the same host/port so the + // runtime keeps serving locally (wsBoundHost stays loopback, so the next pairing offer retries the widen). + private async recoverWebSocketBindAfterFailedWiden( + index: number, + previousPort: number + ): Promise { + let restored: { transport: WebSocketTransport; endpoint: string } + try { + restored = await this.startWebSocketTransport({ + host: WS_BIND_HOST_LOOPBACK, + port: previousPort, + preferPinnedPort: true + }) + } catch (recoveryError) { + // Why: even the loopback restore failed — drop the dead WebSocket transport so we never advertise an + // endpoint with no listener. The Unix socket keeps serving and a restart re-establishes the listener. + console.error( + '[runtime] Failed to restore WebSocket transport after widen failure:', + recoveryError + ) + this.activeTransports.splice(index, 1) + const metaIndex = this.transports.findIndex((meta) => meta.kind === 'websocket') + if (metaIndex >= 0) { + this.transports.splice(metaIndex, 1) + } + this.wsBoundHost = null + try { + this.writeMetadata() + } catch { + // Why: metadata already reflects the torn-down listener; nothing else to recover here. + } + return + } + // Why: register the restored loopback listener BEFORE persisting metadata so a write failure can never + // orphan a live transport outside activeTransports (and thus outside stop()). + this.activeTransports[index] = restored.transport + const metaIndex = this.transports.findIndex((meta) => meta.kind === 'websocket') + if (metaIndex >= 0) { + this.transports[metaIndex] = { kind: 'websocket', endpoint: restored.endpoint } + } + try { + this.writeMetadata() + } catch (persistError) { + // Why: the loopback listener is live and tracked; a persistence failure must not tear it down. + console.error( + '[runtime] Restored loopback WebSocket listener but failed to persist metadata:', + persistError + ) + } + } + /** Why: test-only seam — runs one ownership check instead of waiting out the poll interval. */ checkRuntimeMetadataOwnership(): void { this.metadataOwnershipWatch?.check() } async stop(): Promise { + // Why: STA-2370 — refuse new widens, then let any in-flight pairing widen settle into the live + // transport arrays before snapshotting them, so a racing rebind can't strand a wide 0.0.0.0 listener + // by writing it back into a cleared array after shutdown (see widenWebSocketBind). + this.stopping = true + const pendingExposure = this.networkExposurePromise + if (pendingExposure) { + await pendingExposure.catch(() => { + // Why: a failed widen already recovered/logged; we only need it to finish mutating the arrays. + }) + } const transports = this.activeTransports this.activeTransports = [] this.transports = [] this.metadataOwnershipWatch?.stop() this.metadataOwnershipWatch = null this.mobileSocketWiring = null + this.detachWebSocketWiring = null if (transports.length === 0) { return } diff --git a/src/main/runtime/settle-before-deadline.ts b/src/main/runtime/settle-before-deadline.ts new file mode 100644 index 00000000000..4ae98e87f05 --- /dev/null +++ b/src/main/runtime/settle-before-deadline.ts @@ -0,0 +1,54 @@ +/** + * Races `run()` against an absolute deadline (epoch ms). + * + * Without `failClosedError` the call is best-effort: a timeout or a rejection + * resolves to `fallback`. With it, both surface as a rejection so destructive + * callers can block on unproven work — `failClosedOnRunError` narrows which + * rejections count (some are benign sentinels). + */ +export async function settleBeforeDeadline( + run: () => Promise, + fallback: T, + deadline: number, + failClosedError?: Error, + failClosedOnRunError: (error: unknown) => boolean = () => true +): Promise { + const remaining = deadline - Date.now() + if (remaining <= 0) { + if (failClosedError) { + throw failClosedError + } + return fallback + } + return new Promise((resolve, reject) => { + let settled = false + const finish = (value: T): void => { + if (settled) { + return + } + settled = true + clearTimeout(timer) + resolve(value) + } + const fail = (error: unknown): void => { + if (settled) { + return + } + settled = true + clearTimeout(timer) + reject(error) + } + const timer = setTimeout( + () => (failClosedError ? fail(failClosedError) : finish(fallback)), + remaining + ) + timer.unref?.() + // Why: `.then(run)` rather than `run()` so a synchronous throw is routed + // through the same fail-closed filter instead of escaping the executor. + void Promise.resolve() + .then(run) + .then(finish, (error: unknown) => + failClosedError && failClosedOnRunError(error) ? fail(error) : finish(fallback) + ) + }) +} diff --git a/src/main/runtime/terminal-focus-navigation-coalescer.test.ts b/src/main/runtime/terminal-focus-navigation-coalescer.test.ts new file mode 100644 index 00000000000..cf3fb1aa4de --- /dev/null +++ b/src/main/runtime/terminal-focus-navigation-coalescer.test.ts @@ -0,0 +1,202 @@ +import { describe, expect, it, vi } from 'vitest' +import { TerminalFocusNavigationCoalescer } from './terminal-focus-navigation-coalescer' + +function deferred(): { + promise: Promise + resolve: (value: T) => void + reject: (error: unknown) => void +} { + let resolve!: (value: T) => void + let reject!: (error: unknown) => void + const promise = new Promise((res, rej) => { + resolve = res + reject = rej + }) + return { promise, resolve, reject } +} + +describe('TerminalFocusNavigationCoalescer', () => { + it('runs a single job to completion', async () => { + const coalescer = new TerminalFocusNavigationCoalescer() + const result = await coalescer.run({ + key: 'term_a', + run: async () => 'full-a', + resolveSuperseded: () => 'superseded-a' + }) + expect(result).toBe('full-a') + expect(coalescer.getState()).toMatchObject({ + running: false, + activeKey: null, + pendingKey: null + }) + }) + + it('serializes concurrent focuses and latest-wins drops intermediate pending', async () => { + const coalescer = new TerminalFocusNavigationCoalescer() + const aGate = deferred() + let aStarted = false + + const runA = vi.fn(async (ctx: { isCurrent: () => boolean }) => { + aStarted = true + await aGate.promise + if (!ctx.isCurrent()) { + return 'obsolete-a' + } + return 'full-a' + }) + const runB = vi.fn(async () => 'full-b') + const runC = vi.fn(async () => 'full-c') + const superB = vi.fn(() => 'super-b') + + const pA = coalescer.run({ + key: 'term_a', + run: runA, + resolveSuperseded: (completed) => completed ?? 'super-a' + }) + await vi.waitFor(() => { + expect(aStarted).toBe(true) + }) + + const pB = coalescer.run({ + key: 'term_b', + run: runB, + resolveSuperseded: superB + }) + const pC = coalescer.run({ + key: 'term_c', + run: runC, + resolveSuperseded: () => 'super-c' + }) + + await expect(pB).resolves.toBe('super-b') + expect(superB).toHaveBeenCalledTimes(1) + expect(runB).not.toHaveBeenCalled() + + aGate.resolve() + await expect(pA).resolves.toBe('obsolete-a') + await expect(pC).resolves.toBe('full-c') + expect(runC).toHaveBeenCalledTimes(1) + }) + + it('bounds host navigation to one full run under a parallel storm', async () => { + const coalescer = new TerminalFocusNavigationCoalescer() + let inFlight = 0 + let maxInFlight = 0 + let fullRuns = 0 + + const makeJob = (key: string) => + coalescer.run({ + key, + run: async (ctx) => { + if (!ctx.isCurrent()) { + return -1 + } + inFlight += 1 + maxInFlight = Math.max(maxInFlight, inFlight) + fullRuns += 1 + await new Promise((r) => setTimeout(r, 5)) + inFlight -= 1 + if (!ctx.isCurrent()) { + return -1 + } + return fullRuns + }, + resolveSuperseded: () => -1 + }) + + const results = await Promise.all(Array.from({ length: 16 }, (_, i) => makeJob(`term_${i}`))) + + expect(maxInFlight).toBe(1) + expect(fullRuns).toBeLessThanOrEqual(2) + expect(fullRuns).toBeGreaterThanOrEqual(1) + expect(results.filter((r) => r === -1).length).toBeGreaterThanOrEqual(14) + expect(results.some((r) => r > 0)).toBe(true) + }) + + it('skips claiming navigation when a newer focus arrives mid-run', async () => { + const coalescer = new TerminalFocusNavigationCoalescer<{ id: string; navigated: boolean }>() + const aGate = deferred() + let aStarted = false + + const pA = coalescer.run({ + key: 'term_a', + run: async (ctx) => { + aStarted = true + await aGate.promise + return { id: 'a', navigated: ctx.isCurrent() } + }, + resolveSuperseded: () => ({ id: 'a', navigated: false }) + }) + await vi.waitFor(() => { + expect(aStarted).toBe(true) + }) + + const pB = coalescer.run({ + key: 'term_b', + run: async () => ({ id: 'b', navigated: true }), + resolveSuperseded: () => ({ id: 'b', navigated: false }) + }) + + aGate.resolve() + await expect(pA).resolves.toEqual({ id: 'a', navigated: false }) + await expect(pB).resolves.toEqual({ id: 'b', navigated: true }) + }) + + it('marks a synchronous run superseded when it queues a newer job before settling', async () => { + const coalescer = new TerminalFocusNavigationCoalescer<{ + id: string + navigated: boolean + }>() + let latest!: Promise<{ id: string; navigated: boolean }> + + const first = coalescer.run({ + key: 'term_a', + run: async () => { + latest = coalescer.run({ + key: 'term_b', + run: async () => ({ id: 'b', navigated: true }), + resolveSuperseded: () => ({ id: 'b', navigated: false }) + }) + return { id: 'a', navigated: true } + }, + resolveSuperseded: (completed) => ({ + id: completed?.id ?? 'a', + navigated: false + }) + }) + + await expect(first).resolves.toEqual({ id: 'a', navigated: false }) + await expect(latest).resolves.toEqual({ id: 'b', navigated: true }) + }) + + it('propagates run failures without stranding the queue', async () => { + const coalescer = new TerminalFocusNavigationCoalescer() + const aGate = deferred() + let aStarted = false + + const pA = coalescer.run({ + key: 'term_a', + run: async () => { + aStarted = true + await aGate.promise + throw new Error('boom') + }, + resolveSuperseded: () => 'super-a' + }) + await vi.waitFor(() => { + expect(aStarted).toBe(true) + }) + + const pB = coalescer.run({ + key: 'term_b', + run: async () => 'full-b', + resolveSuperseded: () => 'super-b' + }) + + aGate.resolve() + // A is obsolete when it fails after B enqueued — settles as superseded, not boom. + await expect(pA).resolves.toBe('super-a') + await expect(pB).resolves.toBe('full-b') + expect(coalescer.getState().running).toBe(false) + }) +}) diff --git a/src/main/runtime/terminal-focus-navigation-coalescer.ts b/src/main/runtime/terminal-focus-navigation-coalescer.ts new file mode 100644 index 00000000000..bf69ef6a409 --- /dev/null +++ b/src/main/runtime/terminal-focus-navigation-coalescer.ts @@ -0,0 +1,126 @@ +/** + * Latest-wins single-flight coalescer for exclusive host terminal focus navigation. + * + * Scope: concurrent `terminal.focus` / host-nav storms (CLI switch fan-out, bulk open). + * Not a substitute for cheaper activation or reconnect-scan bounding. + * + * Why: only one host terminal can be focused. Intermediate navigations are waste; + * running them in parallel freezes large remote fleets. Pending jobs collapse to + * the newest; in-flight work re-checks a generation so obsolete runs do not claim + * a successful host navigation after a newer focus arrived. + */ + +export type TerminalFocusNavigationContext = { + /** True while this job is still the newest focus request. */ + isCurrent: () => boolean +} + +export type TerminalFocusNavigationJob = { + /** Stable key for diagnostics (usually terminal handle). */ + key: string + /** + * Full navigation work (reveal/focus host UI). + * Must consult `ctx.isCurrent()` before/after expensive host work and avoid + * claiming navigation when false. + */ + run: (ctx: TerminalFocusNavigationContext) => Promise + /** + * Result when this job is dropped (pending superseded) or becomes obsolete + * mid-flight. Must not perform host navigation. Should set navigated: false. + */ + resolveSuperseded: (completed?: TResult) => TResult +} + +type PendingJob = { + key: string + generation: number + run: (ctx: TerminalFocusNavigationContext) => Promise + resolve: (value: TResult) => void + reject: (error: unknown) => void + resolveSuperseded: (completed?: TResult) => TResult +} + +export class TerminalFocusNavigationCoalescer { + private running = false + private pending: PendingJob | null = null + private activeKey: string | null = null + private generation = 0 + + getState(): { + running: boolean + activeKey: string | null + pendingKey: string | null + generation: number + } { + return { + running: this.running, + activeKey: this.activeKey, + pendingKey: this.pending?.key ?? null, + generation: this.generation + } + } + + run(job: TerminalFocusNavigationJob): Promise { + return new Promise((resolve, reject) => { + if (this.pending) { + try { + this.pending.resolve(this.pending.resolveSuperseded()) + } catch (error) { + this.pending.reject(error) + } + } + const generation = ++this.generation + this.pending = { + key: job.key, + generation, + run: job.run, + resolve, + reject, + resolveSuperseded: job.resolveSuperseded + } + void this.pump() + }) + } + + private async pump(): Promise { + if (this.running) { + return + } + this.running = true + try { + while (this.pending) { + const job = this.pending + this.pending = null + this.activeKey = job.key + const ctx: TerminalFocusNavigationContext = { + isCurrent: () => job.generation === this.generation + } + try { + if (!ctx.isCurrent()) { + job.resolve(job.resolveSuperseded()) + continue + } + const result = await job.run(ctx) + job.resolve(ctx.isCurrent() ? result : job.resolveSuperseded(result)) + } catch (error) { + if (ctx.isCurrent()) { + job.reject(error) + } else { + try { + job.resolve(job.resolveSuperseded()) + } catch (supersedeError) { + job.reject(supersedeError) + } + } + } finally { + this.activeKey = null + } + } + } finally { + this.running = false + if (this.pending) { + void this.pump() + } + } + } +} diff --git a/src/main/runtime/unstopped-pty-verification.ts b/src/main/runtime/unstopped-pty-verification.ts new file mode 100644 index 00000000000..b0df601f133 --- /dev/null +++ b/src/main/runtime/unstopped-pty-verification.ts @@ -0,0 +1,70 @@ +import type { IPtyProvider } from '../providers/types' +import { UNSTOPPED_PTY_REMOVAL_PREFIX } from '../../shared/worktree-removal' +import { settleBeforeDeadline } from './settle-before-deadline' + +// Floor for the verification window when the sweep ran on a very short budget. +export const WORKTREE_TEARDOWN_VERIFY_GRACE_MS = 2_000 + +export type UnstoppedPtyVerdict = + | { status: 'exited' } + | { status: 'live'; ptyIds: string[] } + | { status: 'unverifiable'; reason: string } + +/** + * Re-lists the provider's processes to decide what a failed stop RPC actually + * meant. The three verdicts stay distinct on purpose: "we could not ask" is not + * evidence that a PTY survived, and callers word their errors differently. + * + * Why (#11960): this re-list used to run on the sweep's own deadline, which the + * sweeps had normally just spent. An inventory that answers perfectly well in + * 1s then "timed out" against a 0ms budget, so a PTY that had already exited + * read as unverifiable and the workspace could never be removed. Verification + * gets a budget of its own, sized like the sweep's rather than its leftovers. + */ +export async function verifyUnstoppedPtys( + failedPtyIds: readonly string[], + provider: IPtyProvider, + sweepBudgetMs: number +): Promise { + const verifyBudgetMs = Math.max(WORKTREE_TEARDOWN_VERIFY_GRACE_MS, sweepBudgetMs) + const verifyDeadline = Date.now() + verifyBudgetMs + let listError: unknown + const sessions = await settleBeforeDeadline( + async () => { + try { + return await provider.listProcesses({ deadlineMs: verifyDeadline }) + } catch (error) { + listError = error + return null + } + }, + null, + verifyDeadline + ) + if (!sessions) { + return { + status: 'unverifiable', + reason: listError instanceof Error ? listError.message : 'the process list timed out' + } + } + const livePtyIds = new Set(sessions.map((session) => session.id)) + const stillLive = failedPtyIds.filter((ptyId) => livePtyIds.has(ptyId)) + return stillLive.length > 0 ? { status: 'live', ptyIds: stillLive } : { status: 'exited' } +} + +/** Names the blocking PTYs so a wedged removal is diagnosable, not just refused. */ +export function describeUnstoppedPtys( + worktreeId: string, + failedPtyIds: readonly string[], + verdict: Exclude +): string { + const detail = + verdict.status === 'live' + ? `still live: ${verdict.ptyIds.join(', ')}` + : `could not verify these exited: ${failedPtyIds.join(', ')} (${verdict.reason})` + return `${UNSTOPPED_PTY_REMOVAL_PREFIX} ${worktreeId} — ${detail}` +} + +export function describeError(error: unknown): string { + return error instanceof Error ? error.message : String(error) +} diff --git a/src/main/runtime/worktree-teardown-unstopped-pty.test.ts b/src/main/runtime/worktree-teardown-unstopped-pty.test.ts new file mode 100644 index 00000000000..47852b45985 --- /dev/null +++ b/src/main/runtime/worktree-teardown-unstopped-pty.test.ts @@ -0,0 +1,368 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const { listRegisteredPtysMock } = vi.hoisted(() => ({ + listRegisteredPtysMock: vi.fn() +})) + +vi.mock('../memory/pty-registry', () => ({ + listRegisteredPtys: listRegisteredPtysMock +})) + +import { killAllProcessesForWorktree, WORKTREE_PROCESS_SWEEP_TIMEOUT_MS } from './worktree-teardown' +import type { IPtyProvider, PtyProcessInfo } from '../providers/types' + +// Why: these tests advance fake timers *before* awaiting the teardown, so a +// rejection mid-advance had no handler yet — Node reported it as an unhandled +// rejection and vitest surfaced it inside whichever test happened to be running. +// Attaching a no-op handler at creation keeps the original semantics while +// making failures land as clean assertion failures in their own test. +function settleTeardown(promise: Promise): Promise { + void promise.catch(() => undefined) + return promise +} + +function createProviderStub(listProcesses: () => Promise): IPtyProvider { + return { + shutdown: vi.fn().mockResolvedValue(undefined), + listProcesses: vi.fn(listProcesses), + onData: vi.fn().mockReturnValue(() => {}), + onReplay: vi.fn().mockReturnValue(() => {}), + onExit: vi.fn().mockReturnValue(() => {}) + } as unknown as IPtyProvider +} + +// A worktree whose PTY teardown cannot be proven must still be removable: the +// gate that blocks Git work is the same one that made #11960 permanent. +describe('destructive teardown when a PTY stop cannot be proven', () => { + beforeEach(() => { + listRegisteredPtysMock.mockReset() + }) + + // Why (#11960): the sweeps routinely burn the whole budget, so re-listing on + // the same exhausted deadline returned "unverifiable" for a PTY that had in + // fact exited — wedging the workspace on every retry. + it('verifies a failed stop against a fresh budget when the sweeps spent the deadline', async () => { + vi.useFakeTimers() + try { + const localProvider = createProviderStub( + () => new Promise((resolve) => setTimeout(() => resolve([]), 90)) + ) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('Session not found: stale-1') + ) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'stale-1', worktreeId: 'w1', sessionId: null, paneKey: null, pid: 100 } + ]) + + const teardown = settleTeardown( + killAllProcessesForWorktree('w1', { + localProvider, + timeoutMs: 100, + requirePhysicalStop: true + }) + ) + await vi.runAllTimersAsync() + + await expect(teardown).resolves.toEqual({ + runtimeStopped: 0, + providerStopped: 0, + registryStopped: 0 + }) + } finally { + vi.useRealTimers() + } + }) + + // The reported shape: an automation workspace whose only trace is a stale + // registry row the daemon 404s on, behind an inventory slow enough to consume + // the sweep budget. Verification must still get far enough to prove absence. + it('removes the reported wedged automation workspace without --force', async () => { + const worktreeId = 'repo-1::C:/Users/admin/orca/workspaces/repo/auto-review-run-28' + // Slow enough that a fixed 2s grace could not absorb it, but far enough from + // the budget that the list-completion and timeout timers can't land in the + // same tick — a 100ms margin here raced under parallel load. + const listDelayMs = WORKTREE_PROCESS_SWEEP_TIMEOUT_MS / 2 + vi.useFakeTimers() + try { + const localProvider = createProviderStub( + () => new Promise((resolve) => setTimeout(() => resolve([]), listDelayMs)) + ) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('Session not found: term_abab11ee') + ) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'term_abab11ee', worktreeId, sessionId: null, paneKey: null, pid: 4242 } + ]) + + const teardown = settleTeardown( + killAllProcessesForWorktree(worktreeId, { + localProvider, + requirePhysicalStop: true + }) + ) + await vi.runAllTimersAsync() + + await expect(teardown).resolves.toEqual({ + runtimeStopped: 0, + providerStopped: 0, + registryStopped: 0 + }) + } finally { + vi.useRealTimers() + } + }) + + it('names the blocking PTYs and the escape hatch when one is still live', async () => { + const localProvider = createProviderStub(async () => [ + { id: 'w1@@live-1', cwd: '/tmp/w1', title: 'shell' } + ]) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('kill failed') + ) + listRegisteredPtysMock.mockReturnValue([]) + + await expect( + killAllProcessesForWorktree('w1', { localProvider, requirePhysicalStop: true }) + ).rejects.toThrow(/still live: w1@@live-1[\s\S]*--force/) + }) + + // Why: the memory/registry rows this drops are the reason clearStoppedPtyState + // exists; commit 3 moved that loop, so pin it before it can silently vanish. + it('clears PTY state once a failed stop is proven to have exited', async () => { + const localProvider = createProviderStub(async () => []) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('Session not found: stale-1') + ) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'stale-1', worktreeId: 'w1', sessionId: null, paneKey: null, pid: 100 } + ]) + const onPtyStopped = vi.fn() + + await expect( + killAllProcessesForWorktree('w1', { + localProvider, + onPtyStopped, + requirePhysicalStop: true + }) + ).resolves.toBeDefined() + expect(onPtyStopped).toHaveBeenCalledWith('stale-1') + }) + + it('names only the PTYs that are actually live, not every failed stop', async () => { + const localProvider = createProviderStub(async () => [ + { id: 'w1@@live-1', cwd: '/tmp/w1', title: 'shell' } + ]) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('kill failed') + ) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'w1@@gone-2', worktreeId: 'w1', sessionId: null, paneKey: null, pid: 101 } + ]) + + const error = await killAllProcessesForWorktree('w1', { + localProvider, + requirePhysicalStop: true + }).then( + () => new Error('expected a rejection'), + (rejection: Error) => rejection + ) + expect(error.message).toContain('w1@@live-1') + expect(error.message).not.toContain('w1@@gone-2') + }) + + it('reports unverifiable separately from live when the process list fails', async () => { + const localProvider = createProviderStub(async () => { + throw new Error('daemon socket closed') + }) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'stale-1', worktreeId: 'w1', sessionId: null, paneKey: null, pid: 100 } + ]) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('Session not found: stale-1') + ) + + await expect( + killAllProcessesForWorktree('w1', { + localProvider, + includeProviderInventory: false, + requirePhysicalStop: true + }) + ).rejects.toThrow(/could not verify[\s\S]*stale-1[\s\S]*daemon socket closed/) + }) + + // A gate that force cannot cross is the bug, wherever it sits. These two cover + // the sweep-level failures that reject before the unproven-stop gate is reached. + it('lets force through a provider whose inventory rejects outright', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + try { + listRegisteredPtysMock.mockReturnValue([]) + const localProvider = createProviderStub(async () => { + throw new Error('ssh channel closed') + }) + + await expect( + killAllProcessesForWorktree('w1', { + localProvider, + requirePhysicalStop: true, + allowUnverifiedStop: true + }) + ).resolves.toEqual({ runtimeStopped: 0, providerStopped: 0, registryStopped: 0 }) + expect(warn).toHaveBeenCalledWith(expect.stringContaining('ssh channel closed')) + } finally { + warn.mockRestore() + } + }) + + it('lets force through a sweep that never settles before the deadline', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + vi.useFakeTimers() + // Why: hand the stub a resolver instead of a permanently dangling promise, so + // this test leaves no in-flight continuation to interleave into a later one. + let releaseList: (sessions: PtyProcessInfo[]) => void = () => {} + try { + listRegisteredPtysMock.mockReturnValue([]) + const localProvider = createProviderStub( + () => + new Promise((resolve) => { + releaseList = resolve + }) + ) + + const teardown = settleTeardown( + killAllProcessesForWorktree('w1', { + localProvider, + timeoutMs: 100, + requirePhysicalStop: true, + allowUnverifiedStop: true + }) + ) + await vi.runAllTimersAsync() + + await expect(teardown).resolves.toEqual({ + runtimeStopped: 0, + providerStopped: 0, + registryStopped: 0 + }) + } finally { + releaseList([]) + await vi.advanceTimersByTimeAsync(0) + vi.useRealTimers() + warn.mockRestore() + } + }) + + // Why: the caller deletes files the moment this resolves. Returning while another + // sweep is still inside shutdown() would race the delete against a PTY that was + // about to release its handles — EBUSY for a process ~300ms from exiting. + it('waits for in-flight sweeps before force returns', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + try { + const localProvider = createProviderStub(async () => { + throw new Error('ssh channel closed') + }) + let shutdownFinished = false + ;(localProvider.shutdown as unknown as ReturnType).mockImplementation( + async () => { + await new Promise((resolve) => setTimeout(resolve, 20)) + shutdownFinished = true + } + ) + listRegisteredPtysMock.mockReturnValue([ + { ptyId: 'reg-1', worktreeId: 'w1', sessionId: null, paneKey: null, pid: 100 } + ]) + + const result = await killAllProcessesForWorktree('w1', { + localProvider, + requirePhysicalStop: true, + allowUnverifiedStop: true + }) + + expect(shutdownFinished).toBe(true) + // And the surviving sweep's work is reported, not flattened to zero. + expect(result.registryStopped).toBe(1) + } finally { + warn.mockRestore() + } + }) + + // Why: the deadline sentinel only says *something* timed out. Picking the + // rejection by array position let a hung runtime sweep mask the provider error + // that actually explains the failure, in the log the user is left with. + it('warns with the specific sweep failure, not the generic deadline', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + vi.useFakeTimers() + try { + listRegisteredPtysMock.mockReturnValue([]) + const localProvider = createProviderStub(async () => { + throw new Error('ssh channel closed') + }) + const runtime = { + stopTerminalsForWorktree: () => new Promise(() => {}) + } as unknown as Parameters[1]['runtime'] + + const teardown = settleTeardown( + killAllProcessesForWorktree('w1', { + runtime, + localProvider, + timeoutMs: 100, + requirePhysicalStop: true, + allowUnverifiedStop: true + }) + ) + await vi.runAllTimersAsync() + await teardown + + const warning = warn.mock.calls.at(-1)?.[0] as string + expect(warning).toContain('ssh channel closed') + // Both are reported — losing the timeout would trade one blind spot for + // another — but the specific cause must lead, not be buried behind it. + expect(warning).toContain('Timed out waiting') + expect(warning.indexOf('ssh channel closed')).toBeLessThan( + warning.indexOf('Timed out waiting') + ) + } finally { + vi.useRealTimers() + warn.mockRestore() + } + }) + + it('still fails closed on a sweep-level failure without force', async () => { + listRegisteredPtysMock.mockReturnValue([]) + const localProvider = createProviderStub(async () => { + throw new Error('ssh channel closed') + }) + + await expect( + killAllProcessesForWorktree('w1', { localProvider, requirePhysicalStop: true }) + ).rejects.toThrow('ssh channel closed') + }) + + it('lets an explicit force removal proceed past PTYs it could not stop', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + try { + const localProvider = createProviderStub(async () => [ + { id: 'w1@@live-1', cwd: '/tmp/w1', title: 'shell' } + ]) + ;(localProvider.shutdown as unknown as ReturnType).mockRejectedValue( + new Error('kill failed') + ) + listRegisteredPtysMock.mockReturnValue([]) + const onPtyStopped = vi.fn() + + await expect( + killAllProcessesForWorktree('w1', { + localProvider, + onPtyStopped, + requirePhysicalStop: true, + allowUnverifiedStop: true + }) + ).resolves.toMatchObject({ providerStopped: 0 }) + expect(warn).toHaveBeenCalledWith(expect.stringContaining('w1@@live-1')) + // Why: unregistering a PTY we just watched stay alive would hide it from + // the next sweep and from the user — the discoverability half of #11960. + expect(onPtyStopped).not.toHaveBeenCalled() + } finally { + warn.mockRestore() + } + }) +}) diff --git a/src/main/runtime/worktree-teardown.ts b/src/main/runtime/worktree-teardown.ts index 64b6a09703f..45929e21f98 100644 --- a/src/main/runtime/worktree-teardown.ts +++ b/src/main/runtime/worktree-teardown.ts @@ -4,6 +4,14 @@ import { listRegisteredPtys } from '../memory/pty-registry' import { isPathInsideOrEqual } from '../../shared/cross-platform-path' import { splitWorktreeId, splitWorktreeIdForFilesystem } from '../../shared/worktree-id' import { mapWithConcurrency } from '../../shared/map-with-concurrency' +import { WORKTREE_TEARDOWN_FORCE_HINT } from '../../shared/worktree-removal' +import { settleBeforeDeadline } from './settle-before-deadline' +import { + describeError, + describeUnstoppedPtys, + verifyUnstoppedPtys, + type UnstoppedPtyVerdict +} from './unstopped-pty-verification' // Why: normal inventories still coalesce into one process scan, while a stale // or pathological inventory cannot fan out unbounded provider/RPC shutdowns. @@ -21,6 +29,8 @@ export type WorktreeTeardownDeps = { onPtyStopped?: (ptyId: string) => void timeoutMs?: number requirePhysicalStop?: boolean + /** Explicit Force Delete only: warn instead of throwing when a stop stays unproven (#11960). */ + allowUnverifiedStop?: boolean includeProviderInventory?: boolean includeLocalRegistry?: boolean } @@ -33,8 +43,10 @@ export type WorktreeTeardownResult = { export const WORKTREE_PROCESS_SWEEP_TIMEOUT_MS = 10_000 -// Why: reserve time after bounded stop RPCs to recheck whether a reported -// failure actually left a live PTY before the outer sweep deadline. +// Why: keep each bounded stop RPC settling before the sweep deadline itself, so +// a wedged provider surfaces as a stop failure rather than as the outer timeout. +// (The recheck this margin once also reserved time for now runs on its own +// budget — see verifyUnstoppedPtys — because sharing this one wedged #11960.) export const WORKTREE_TEARDOWN_RPC_MARGIN_MS = 500 // Absolute deadline (epoch ms) threaded into provider RPCs on the destructive @@ -64,12 +76,17 @@ export function teardownRpcDeadline(sweepDeadline: number): number { * * Sweeps are best-effort by default. Destructive removal callers set * `requirePhysicalStop` so a timeout or unproven stop blocks filesystem work. + * `allowUnverifiedStop` waives that proof so the gate can never wedge a + * workspace permanently (#11960) — it must come only from an explicit Force + * Delete or `--force`, never from the `force` an ordinary confirmed delete + * already sets to skip the dirty-file prompt. */ export async function killAllProcessesForWorktree( worktreeId: string, deps: WorktreeTeardownDeps ): Promise { - const deadline = Date.now() + Math.max(1, deps.timeoutMs ?? WORKTREE_PROCESS_SWEEP_TIMEOUT_MS) + const sweepBudgetMs = Math.max(1, deps.timeoutMs ?? WORKTREE_PROCESS_SWEEP_TIMEOUT_MS) + const deadline = Date.now() + sweepBudgetMs const deadlineError = new Error(`Timed out waiting for physical PTY teardown: ${worktreeId}`) const stopAttempts = new Map>() const stopPty = ( @@ -154,90 +171,93 @@ export async function killAllProcessesForWorktree( deadline, deps.requirePhysicalStop ? deadlineError : undefined ) - const [runtimeResult, providerStopped, registryStopped] = await Promise.all([ - runtimeSweep, - providerSweep, - registrySweep - ]) + // Why: a rejection here can outlive this call, and only one of the two paths + // below observes every promise, so mark them all handled up front. + for (const sweep of [runtimeSweep, providerSweep, registrySweep]) { + void sweep.catch(() => undefined) + } + let runtimeResult: { stopped: number } + let providerStopped: number + let registryStopped: number + if (deps.allowUnverifiedStop) { + // Why: force goes on to delete files, so every sweep must finish releasing + // handles first — Promise.all would abandon the siblings of the first + // rejection while they were still inside shutdown(), racing the delete. + const settled = await Promise.allSettled([runtimeSweep, providerSweep, registrySweep]) + const [runtimeSettled, providerSettled, registrySettled] = settled + const reasons = settled.flatMap((result) => + result.status === 'rejected' ? [result.reason as unknown] : [] + ) + if (reasons.length > 0) { + // Why (#11960): a sweep that cannot even complete — unresponsive daemon, + // dropped SSH channel — fails before the unproven-stop gate below could + // offer its escape hatch, so an explicit Force Delete has to survive it. + // Report every reason, specific ones first: the shared deadline sentinel + // only says that *something* timed out, so leading with it would bury the + // provider error that actually explains the failure. This warning is the + // only trace of a removal that deleted files without proving a single stop. + const detail = [ + ...reasons.filter((candidate) => candidate !== deadlineError), + ...reasons.filter((candidate) => candidate === deadlineError) + ] + .map(describeError) + .join('; ') + console.warn( + `[worktree-teardown] forcing removal after an incomplete PTY sweep for ${worktreeId} — ${detail}` + ) + // Returning here does skip the verdict below, which could still have named + // live PTYs when only one sweep failed — accepted for now because this path + // is behind an explicit Force Delete, deletes either way, and clears no + // registry rows, so the cost is diagnosability rather than safety. + // Report what the surviving sweeps actually stopped rather than a flat zero. + return { + runtimeStopped: runtimeSettled.status === 'fulfilled' ? runtimeSettled.value.stopped : 0, + providerStopped: providerSettled.status === 'fulfilled' ? providerSettled.value : 0, + registryStopped: registrySettled.status === 'fulfilled' ? registrySettled.value : 0 + } + } + runtimeResult = (runtimeSettled as PromiseFulfilledResult<{ stopped: number }>).value + providerStopped = (providerSettled as PromiseFulfilledResult).value + registryStopped = (registrySettled as PromiseFulfilledResult).value + } else { + // Why: without the waiver a rejection aborts the removal and nothing is + // deleted, so failing fast is safe — and keeps a dead host reporting + // immediately instead of after the full sweep budget. + ;[runtimeResult, providerStopped, registryStopped] = await Promise.all([ + runtimeSweep, + providerSweep, + registrySweep + ]) + } if (deps.requirePhysicalStop) { const stopResults = await Promise.all( [...stopAttempts].map(async ([ptyId, stopped]) => [ptyId, await stopped] as const) ) const failedPtyIds = stopResults.filter(([, stopped]) => !stopped).map(([ptyId]) => ptyId) - const failedPtysExited = - failedPtyIds.length === 0 || - (await verifyFailedPtysExited(failedPtyIds, deps.localProvider, deadline)) - if (!failedPtysExited) { - throw new Error(`Failed to physically stop every PTY for worktree: ${worktreeId}`) - } - for (const ptyId of failedPtyIds) { - clearStoppedPtyState(ptyId, deps.onPtyStopped) + const verdict: UnstoppedPtyVerdict = + failedPtyIds.length === 0 + ? { status: 'exited' } + : await verifyUnstoppedPtys(failedPtyIds, deps.localProvider, sweepBudgetMs) + if (verdict.status === 'exited') { + for (const ptyId of failedPtyIds) { + clearStoppedPtyState(ptyId, deps.onPtyStopped) + } + } else { + const summary = describeUnstoppedPtys(worktreeId, failedPtyIds, verdict) + if (!deps.allowUnverifiedStop) { + throw new Error(`${summary}. ${WORKTREE_TEARDOWN_FORCE_HINT}`) + } + // Why: force is the documented escape hatch, so removal continues — but the + // registry rows stay put. Dropping them would unregister a PTY we just saw + // alive, so a retry could no longer find it and the user could never see it + // (the discoverability half of #11960). + console.warn(`[worktree-teardown] forcing removal despite unstopped PTYs — ${summary}`) } } return { runtimeStopped: runtimeResult.stopped, providerStopped, registryStopped } } -async function verifyFailedPtysExited( - failedPtyIds: readonly string[], - provider: IPtyProvider, - deadline: number -): Promise { - const sessions = await settleBeforeDeadline( - () => provider.listProcesses({ deadlineMs: deadline }), - null, - deadline - ).catch(() => null) - if (!sessions) { - return false - } - const livePtyIds = new Set(sessions.map((session) => session.id)) - return failedPtyIds.every((ptyId) => !livePtyIds.has(ptyId)) -} - -async function settleBeforeDeadline( - run: () => Promise, - fallback: T, - deadline: number, - failClosedError?: Error, - failClosedOnRunError: (error: unknown) => boolean = () => true -): Promise { - const remaining = deadline - Date.now() - if (remaining <= 0) { - if (failClosedError) { - throw failClosedError - } - return fallback - } - return new Promise((resolve, reject) => { - let settled = false - const finish = (value: T): void => { - if (settled) { - return - } - settled = true - clearTimeout(timer) - resolve(value) - } - const fail = (error: unknown): void => { - if (settled) { - return - } - settled = true - clearTimeout(timer) - reject(error) - } - const timer = setTimeout( - () => (failClosedError ? fail(failClosedError) : finish(fallback)), - remaining - ) - timer.unref?.() - void run().then(finish, (error: unknown) => - failClosedError && failClosedOnRunError(error) ? fail(error) : finish(fallback) - ) - }) -} - async function sweepProviderByPrefix( worktreeId: string, provider: IPtyProvider, diff --git a/src/main/ssh/relay-protocol.test.ts b/src/main/ssh/relay-protocol.test.ts index 459eaef88df..6a63bef5b50 100644 --- a/src/main/ssh/relay-protocol.test.ts +++ b/src/main/ssh/relay-protocol.test.ts @@ -84,9 +84,14 @@ describe('frame encoding', () => { }) describe('FrameDecoder', () => { + // Framing correctness should not depend on wall-clock turn budgeting; the + // default 4ms maxTurnMs can defer later frames via setImmediate under CI load. + // Time-sliced drain is covered by relay-protocol-backpressure.test.ts. + const frozenClock = { now: () => 0 } + it('decodes a complete frame', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) const payload = Buffer.from('test') const encoded = encodeFrame(MessageType.Regular, 1, 0, payload) @@ -101,7 +106,7 @@ describe('FrameDecoder', () => { it('handles partial frames across multiple feeds', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) const payload = Buffer.from('hello world') const encoded = encodeFrame(MessageType.Regular, 2, 1, payload) @@ -117,7 +122,7 @@ describe('FrameDecoder', () => { it('decodes multiple frames from a single chunk', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) const frame1 = encodeFrame(MessageType.Regular, 1, 0, Buffer.from('a')) const frame2 = encodeFrame(MessageType.Regular, 2, 1, Buffer.from('b')) @@ -131,7 +136,7 @@ describe('FrameDecoder', () => { it('decodes keepalive frames', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) decoder.feed(encodeKeepAliveFrame(5, 3)) expect(frames).toHaveLength(1) @@ -144,7 +149,8 @@ describe('FrameDecoder', () => { const frames: DecodedFrame[] = [] const decoder = new FrameDecoder( (f) => frames.push(f), - (err) => errors.push(err) + (err) => errors.push(err), + frozenClock ) const oversizedLength = 17 * 1024 * 1024 @@ -165,7 +171,7 @@ describe('FrameDecoder', () => { it('reset clears internal buffer', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) // Feed a partial frame const encoded = encodeFrame(MessageType.Regular, 1, 0, Buffer.from('test')) @@ -180,7 +186,7 @@ describe('FrameDecoder', () => { it('decodes frames fed one byte at a time (worst-case boundary straddling)', () => { const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) const frame1 = encodeFrame(MessageType.Regular, 1, 0, Buffer.from('first payload')) const frame2 = encodeFrame(MessageType.Regular, 2, 1, Buffer.from('second')) @@ -201,7 +207,8 @@ describe('FrameDecoder', () => { const frames: DecodedFrame[] = [] const decoder = new FrameDecoder( (f) => frames.push(f), - (err) => errors.push(err) + (err) => errors.push(err), + frozenClock ) const oversizedLength = 17 * 1024 * 1024 @@ -229,7 +236,7 @@ describe('FrameDecoder', () => { // re-copying the whole backlog for every TCP chunk — O(n²) memcpy on the // Electron main thread while fs.streamChunk frames arrive (SSH typing lag). const frames: DecodedFrame[] = [] - const decoder = new FrameDecoder((f) => frames.push(f)) + const decoder = new FrameDecoder((f) => frames.push(f), undefined, frozenClock) const frame = encodeFrame(MessageType.Regular, 1, 0, Buffer.alloc(512 * 1024, 0x61)) const concatSpy = vi.spyOn(Buffer, 'concat') diff --git a/src/main/ssh/ssh-channel-multiplexer.ts b/src/main/ssh/ssh-channel-multiplexer.ts index 575decba730..206d008c151 100644 --- a/src/main/ssh/ssh-channel-multiplexer.ts +++ b/src/main/ssh/ssh-channel-multiplexer.ts @@ -48,6 +48,24 @@ const MAX_UNACKED_TIMESTAMPS = MAX_ORDINARY_UNACKED_TIMESTAMPS + 1 // (system sleep, App Nap timer throttling) — not that the link is dead (#7773). const WAKE_GAP_MS = KEEPALIVE_SEND_MS * 3 +// Why: callers branch on "the request timed out" (fall back to a slower path, +// report a host issue). Matching the message text made every unrelated error +// carrying the same phrase take the timeout branch. +export const SSH_MUX_REQUEST_TIMEOUT_CODE = 'SSH_MUX_REQUEST_TIMEOUT' + +function sshMuxRequestTimeoutError(method: string, timeoutMs: number): Error { + return Object.assign(new Error(`Request "${method}" timed out after ${timeoutMs}ms`), { + code: SSH_MUX_REQUEST_TIMEOUT_CODE + }) +} + +export function isSshMuxRequestTimeoutError(error: unknown): boolean { + return ( + error instanceof Error && + (error as Error & { code?: unknown }).code === SSH_MUX_REQUEST_TIMEOUT_CODE + ) +} + export class SshChannelMultiplexer { private decoder: FrameDecoder private transport: MultiplexerTransport @@ -231,7 +249,7 @@ export class SshChannelMultiplexer { this.notify('rpc.cancel', { id }) } this.pendingRequests.delete(id) - reject(new Error(`Request "${method}" timed out after ${timeoutMs}ms`)) + reject(sshMuxRequestTimeoutError(method, timeoutMs)) }, timeoutMs) if (options?.signal) { diff --git a/src/main/ssh/ssh-config-host-picker.test.ts b/src/main/ssh/ssh-config-host-picker.test.ts new file mode 100644 index 00000000000..4d7666fa457 --- /dev/null +++ b/src/main/ssh/ssh-config-host-picker.test.ts @@ -0,0 +1,198 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import type * as SshConfigParser from './ssh-config-parser' +import type { SshConfigHost } from './ssh-config-parser' + +const loadUserSshConfigMock = vi.hoisted(() => vi.fn<() => SshConfigHost[]>(() => [])) +vi.mock('./ssh-config-parser', async (importOriginal) => ({ + ...(await importOriginal()), + loadUserSshConfig: loadUserSshConfigMock +})) + +import { SSH_CONFIG_HOST_RESULT_LIMIT } from '../../shared/ssh-types' +import { + invalidateUserSshConfigHostCache, + listUserSshConfigHostSummaries, + resolveUserSshConfigHost, + searchSshConfigHosts +} from './ssh-config-host-picker' +import type { SshResolvedConfig } from './ssh-g-config-resolution' + +function resolved(overrides: Partial = {}): SshResolvedConfig { + return { + hostname: 'prod.internal', + user: 'deploy', + port: 2222, + identityFile: ['/keys/first', '/keys/second'], + identitiesOnly: true, + forwardAgent: false, + gssapiAuthentication: true, + proxyUseFdpass: false, + controlMaster: 'no', + controlPersist: 'no', + ...overrides + } +} + +describe('SSH config host picker search', () => { + it('bounds results while searching aliases beyond the first page', () => { + const hosts = Array.from({ length: 150_000 }, (_, index) => ({ + host: `generated-${index}` + })) + const initial = searchSshConfigHosts(hosts, []) + const last = searchSshConfigHosts(hosts, [], 'generated-149999') + + expect(initial.hosts).toHaveLength(SSH_CONFIG_HOST_RESULT_LIMIT) + expect(initial).toMatchObject({ + totalHostCount: 150_000, + newHostCount: 150_000, + matchCount: 150_000, + hasMore: true + }) + expect(last.hosts.map((host) => host.alias)).toEqual(['generated-149999']) + expect(last.hasMore).toBe(false) + }) + + it('counts de-duplicated and existing aliases while matching effective display fields', () => { + const result = searchSshConfigHosts( + [ + { host: 'prod', hostname: 'prod.internal', user: 'deploy' }, + { host: 'prod', hostname: 'ignored.internal' }, + { host: 'stage', hostname: 'stage.internal', user: 'ops' } + ], + [{ configHost: 'prod', label: 'Production' }], + 'internal' + ) + + expect(result).toMatchObject({ + totalHostCount: 2, + newHostCount: 1, + matchCount: 2, + hasMore: false + }) + expect(result.hosts[0]).toMatchObject({ alias: 'prod', alreadyInOrca: true }) + }) + + it('marks a case-only alias variant as already in Orca', () => { + const result = searchSshConfigHosts([{ host: 'prod' }], [{ configHost: 'Prod', label: 'Prod' }]) + + expect(result).toMatchObject({ totalHostCount: 1, newHostCount: 0 }) + expect(result.hosts[0]).toMatchObject({ alias: 'prod', alreadyInOrca: true }) + }) + + it('lists suppressed aliases for re-pick but excludes them from Add-all newHostCount', () => { + const result = searchSshConfigHosts([{ host: 'removed' }, { host: 'active' }], [], '', [ + 'removed' + ]) + + expect(result).toMatchObject({ totalHostCount: 2, newHostCount: 1, matchCount: 2 }) + expect(result.hosts).toEqual([ + expect.objectContaining({ alias: 'removed', previouslyRemoved: true, alreadyInOrca: false }), + expect.objectContaining({ alias: 'active', alreadyInOrca: false }) + ]) + expect(result.hosts.find((host) => host.alias === 'active')?.previouslyRemoved).toBeUndefined() + }) + + it('does not mark a host as previously removed when it is already in Orca', () => { + const result = searchSshConfigHosts( + [{ host: 'prod' }], + [{ configHost: 'prod', label: 'Production' }], + '', + ['prod'] + ) + + expect(result.hosts[0]).toMatchObject({ + alias: 'prod', + alreadyInOrca: true + }) + expect(result.hosts[0]?.previouslyRemoved).toBeUndefined() + expect(result.newHostCount).toBe(0) + }) +}) + +describe('listUserSshConfigHostSummaries caching', () => { + beforeEach(() => { + loadUserSshConfigMock.mockClear() + loadUserSshConfigMock.mockReturnValue([{ host: 'prod' }, { host: 'stage' }]) + invalidateUserSshConfigHostCache() + }) + + it('parses ~/.ssh/config once per picker session and filters in memory', () => { + listUserSshConfigHostSummaries([], '', [], { refresh: true }) + const filtered = listUserSshConfigHostSummaries([], 'stage') + listUserSshConfigHostSummaries([], 'sta') + + expect(loadUserSshConfigMock).toHaveBeenCalledTimes(1) + expect(filtered.hosts.map((host) => host.alias)).toEqual(['stage']) + }) + + it('re-reads the file when the picker reopens', () => { + listUserSshConfigHostSummaries([], '', [], { refresh: true }) + loadUserSshConfigMock.mockReturnValue([{ host: 'prod' }, { host: 'stage' }, { host: 'added' }]) + const reopened = listUserSshConfigHostSummaries([], '', [], { refresh: true }) + + expect(loadUserSshConfigMock).toHaveBeenCalledTimes(2) + expect(reopened.totalHostCount).toBe(3) + }) +}) + +describe('resolveUserSshConfigHost', () => { + it('returns effective endpoint and the complete authentication contract', async () => { + const resolver = vi.fn().mockResolvedValue(resolved()) + + await expect( + resolveUserSshConfigHost('prod', resolver, () => [ + { host: 'prod', gssapiAuthentication: true } + ]) + ).resolves.toEqual({ + alias: 'prod', + hostname: 'prod.internal', + username: 'deploy', + port: 2222, + identityFiles: ['/keys/first', '/keys/second'], + identitiesOnly: true, + forwardAgent: false, + gssapiAuthentication: true, + proxyUseFdpass: false + }) + expect(resolver).toHaveBeenCalledWith('prod') + }) + + it('ignores the system-wide GSSAPIAuthentication default that ssh -G reports', async () => { + const resolver = vi.fn().mockResolvedValue(resolved()) + + await expect( + resolveUserSshConfigHost('prod', resolver, () => [ + { host: 'prod', hostname: 'prod.internal' } + ]) + ).resolves.toMatchObject({ gssapiAuthentication: false }) + }) + + it('honours a case-only variant of the Host entry that requests GSSAPI', async () => { + const resolver = vi.fn().mockResolvedValue(resolved()) + + await expect( + resolveUserSshConfigHost('PROD', resolver, () => [ + { host: 'prod', gssapiAuthentication: true } + ]) + ).resolves.toMatchObject({ gssapiAuthentication: true }) + }) + + it('returns null for an alias the config no longer declares, even though ssh -G answers', async () => { + const resolver = vi.fn().mockResolvedValue(resolved({ hostname: 'deleted' })) + + await expect( + resolveUserSshConfigHost('deleted', resolver, () => [{ host: 'prod' }]) + ).resolves.toBeNull() + expect(resolver).not.toHaveBeenCalled() + }) + + it('returns null when OpenSSH cannot resolve an endpoint', async () => { + await expect( + resolveUserSshConfigHost( + 'missing', + async () => null, + () => [{ host: 'missing' }] + ) + ).resolves.toBeNull() + }) +}) diff --git a/src/main/ssh/ssh-config-host-picker.ts b/src/main/ssh/ssh-config-host-picker.ts new file mode 100644 index 00000000000..d1870ad1b69 --- /dev/null +++ b/src/main/ssh/ssh-config-host-picker.ts @@ -0,0 +1,167 @@ +import type { + SshConfigHostListResult, + SshConfigHostResolution, + SshConfigHostSummary, + SshTarget +} from '../../shared/ssh-types' +import { SSH_CONFIG_HOST_RESULT_LIMIT } from '../../shared/ssh-types' +import { normalizeSshConfigAlias } from '../../shared/ssh-config-alias' +import { loadUserSshConfig, type SshConfigHost } from './ssh-config-parser' +import { resolveWithSshG, type SshResolvedConfig } from './ssh-g-config-resolution' + +// Why: every keystroke in the picker filter re-queries the main process. Parsing (and +// Include-expanding) ~/.ssh/config per keystroke is the whole cost, and the file cannot +// change between them, so hold the parse for the picker session and refresh on reopen. +let cachedConfigHosts: SshConfigHost[] | null = null + +export function invalidateUserSshConfigHostCache(): void { + cachedConfigHosts = null +} + +function getUserSshConfigHosts(refresh: boolean): SshConfigHost[] { + if (refresh || cachedConfigHosts === null) { + cachedConfigHosts = loadUserSshConfig() + } + return cachedConfigHosts +} + +export function searchSshConfigHosts( + hosts: SshConfigHost[], + existingTargets: readonly Pick[], + query = '', + suppressedAliases: readonly string[] = [] +): SshConfigHostListResult { + const existingAliases = new Set( + existingTargets.flatMap((target) => + [target.configHost, target.label].map(normalizeSshConfigAlias).filter(Boolean) + ) + ) + const normalizedQuery = query.trim().toLowerCase() + const suppressedAliasSet = new Set(suppressedAliases.map(normalizeSshConfigAlias)) + const summaries: SshConfigHostSummary[] = [] + const seenAliases = new Set() + let totalHostCount = 0 + let newHostCount = 0 + let matchCount = 0 + + for (const entry of hosts) { + const normalizedAlias = normalizeSshConfigAlias(entry.host) + if (seenAliases.has(normalizedAlias)) { + continue + } + seenAliases.add(normalizedAlias) + const alreadyInOrca = existingAliases.has(normalizedAlias) + // Why: tombstones only block passive bulk import — the picker still lists the + // Host so deleting one Orca target never looks like "~/.ssh/config is empty". + const previouslyRemoved = !alreadyInOrca && suppressedAliasSet.has(normalizedAlias) + totalHostCount += 1 + // Why: "Add all" must match importFromSshConfig without reAdopt (tombstones stay). + newHostCount += alreadyInOrca || previouslyRemoved ? 0 : 1 + if (!matchesQuery(entry, normalizedQuery)) { + continue + } + matchCount += 1 + if (summaries.length < SSH_CONFIG_HOST_RESULT_LIMIT) { + summaries.push(toSummary(entry, alreadyInOrca, previouslyRemoved)) + } + } + + return { + hosts: summaries, + totalHostCount, + newHostCount, + matchCount, + hasMore: matchCount > summaries.length + } +} + +export function listUserSshConfigHostSummaries( + existingTargets: readonly Pick[], + query?: string, + suppressedAliases?: readonly string[], + options?: { refresh?: boolean } +): SshConfigHostListResult { + return searchSshConfigHosts( + getUserSshConfigHosts(options?.refresh === true), + existingTargets, + query, + suppressedAliases + ) +} + +export async function resolveUserSshConfigHost( + alias: string, + resolver: (host: string) => Promise = resolveWithSshG, + // Why: read the file again rather than the picker-session cache — the point of the check + // below is to catch a row the user edited out of ~/.ssh/config after opening the picker. + loadConfigHosts: () => SshConfigHost[] = () => getUserSshConfigHosts(true) +): Promise { + const configHosts = loadConfigHosts() + // Why: `ssh -G` answers for unknown aliases too, echoing the alias back as the hostname. + // Resolving one would mint a target for a host that is no longer configured. + if (!configHostMatches(configHosts, alias)) { + return null + } + const resolved = await resolver(alias) + if (!resolved?.hostname) { + return null + } + return { + alias, + hostname: resolved.hostname, + port: resolved.port, + username: resolved.user ?? '', + identityFiles: resolved.identityFile, + ...(resolved.identityAgent ? { identityAgent: resolved.identityAgent } : {}), + identitiesOnly: resolved.identitiesOnly, + forwardAgent: resolved.forwardAgent, + // Why: `ssh -G` reports the effective value, which on many distros is the /etc/ssh + // default `GSSAPIAuthentication yes`. Stamping that onto a manual target would force + // a GSSAPI-first handshake the user never asked for, so honour the Host entry only. + gssapiAuthentication: configHostRequestsGssapi(configHosts, alias), + ...(resolved.proxyCommand ? { proxyCommand: resolved.proxyCommand } : {}), + proxyUseFdpass: resolved.proxyUseFdpass, + ...(resolved.proxyJump ? { jumpHost: resolved.proxyJump } : {}) + } +} + +function configHostMatches(hosts: readonly SshConfigHost[], alias: string): boolean { + const normalized = normalizeSshConfigAlias(alias) + return Boolean(normalized) && hosts.some((entry) => matchesAlias(entry, normalized)) +} + +function configHostRequestsGssapi(hosts: readonly SshConfigHost[], alias: string): boolean { + const normalized = normalizeSshConfigAlias(alias) + return hosts.some((entry) => matchesAlias(entry, normalized) && entry.gssapiAuthentication) +} + +function matchesAlias(entry: SshConfigHost, normalizedAlias: string): boolean { + return normalizeSshConfigAlias(entry.host) === normalizedAlias +} + +function toSummary( + entry: SshConfigHost, + alreadyInOrca: boolean, + previouslyRemoved = false +): SshConfigHostSummary { + return { + alias: entry.host, + hostname: entry.hostname || entry.host, + port: entry.port ?? 22, + username: entry.user ?? '', + ...(entry.identityFile ? { identityFile: entry.identityFile } : {}), + ...(entry.proxyCommand ? { proxyCommand: entry.proxyCommand } : {}), + ...(entry.proxyJump ? { jumpHost: entry.proxyJump } : {}), + alreadyInOrca, + ...(previouslyRemoved ? { previouslyRemoved: true } : {}) + } +} + +function matchesQuery(entry: SshConfigHost, query: string): boolean { + return ( + !query || + entry.host.toLowerCase().includes(query) || + (entry.hostname ?? entry.host).toLowerCase().includes(query) || + (entry.user ?? '').toLowerCase().includes(query) + ) +} diff --git a/src/main/ssh/ssh-config-parser.test.ts b/src/main/ssh/ssh-config-parser.test.ts index e48b77baab9..8625a553ad1 100644 --- a/src/main/ssh/ssh-config-parser.test.ts +++ b/src/main/ssh/ssh-config-parser.test.ts @@ -1,6 +1,12 @@ import { describe, expect, it, vi } from 'vitest' import { join } from 'node:path' import { parseSshConfig, sshConfigHostsToTargets, parseSshGOutput } from './ssh-config-parser' +import { searchSshConfigHosts } from './ssh-config-host-picker' + +const sshConfigHostsToSummaries = ( + hosts: Parameters[0], + targets: Parameters[1] +) => searchSshConfigHosts(hosts, targets).hosts vi.mock('os', () => ({ homedir: () => '/home/testuser' @@ -460,6 +466,60 @@ describe('sshConfigHostsToTargets', () => { }) }) +describe('sshConfigHostsToSummaries', () => { + it('maps hosts for the picker and flags aliases already in Orca', () => { + const hosts = [ + { + host: 'staging', + hostname: 'staging.internal', + user: 'ubuntu', + port: 22, + identityFile: '/home/me/.ssh/staging' + }, + { host: 'prod', hostname: 'prod.example', user: 'ops', port: 2222, proxyJump: 'bastion' } + ] + const summaries = sshConfigHostsToSummaries(hosts, [ + { label: 'staging', configHost: 'staging' } + ]) + expect(summaries).toEqual([ + { + alias: 'staging', + hostname: 'staging.internal', + port: 22, + username: 'ubuntu', + identityFile: '/home/me/.ssh/staging', + alreadyInOrca: true + }, + { + alias: 'prod', + hostname: 'prod.example', + port: 2222, + username: 'ops', + jumpHost: 'bastion', + alreadyInOrca: false + } + ]) + }) + + it('de-dupes aliases and defaults missing fields', () => { + const hosts = [ + { host: 'box' }, + { host: 'box', hostname: 'second.example' }, + { host: 'other', user: 'me' } + ] + const summaries = sshConfigHostsToSummaries(hosts, []) + expect(summaries).toHaveLength(2) + expect(summaries[0]).toEqual({ + alias: 'box', + hostname: 'box', + port: 22, + username: '', + alreadyInOrca: false + }) + expect(summaries[1].alias).toBe('other') + }) +}) + // ── parseSshGOutput ────────────────────────────────────────────────── describe('parseSshGOutput', () => { diff --git a/src/main/ssh/ssh-connection-store.test.ts b/src/main/ssh/ssh-connection-store.test.ts index 90d92a1499e..9acba4d18eb 100644 --- a/src/main/ssh/ssh-connection-store.test.ts +++ b/src/main/ssh/ssh-connection-store.test.ts @@ -85,6 +85,22 @@ describe('SshConnectionStore', () => { expect(mockStore.getSshTargets).toHaveBeenCalled() }) + it('lists picker suppression aliases without consulting re-adoption tombstones', () => { + mockStore.addDeletedSshConfigAlias('config-removed') + mockStore.addRemovedSshTargetTombstone({ + oldTargetId: 'ssh-manual', + configHost: 'manual-removed', + host: 'manual.internal', + port: 22, + username: 'deploy', + label: 'Manual', + removedAt: 1 + }) + + expect(sshStore.listSuppressedSshConfigAliases()).toEqual(['config-removed']) + expect(mockStore.getRemovedSshTargetTombstones).not.toHaveBeenCalled() + }) + it('getTarget delegates to store', () => { sshStore.getTarget('test-id') expect(mockStore.getSshTarget).toHaveBeenCalledWith('test-id') @@ -357,6 +373,65 @@ describe('SshConnectionStore', () => { expect(result).toEqual([]) }) + // SSH matches Host patterns case-insensitively, so `Prod` and `prod` are one host + // everywhere else in the picker — import ownership must agree. + it('treats a case-only alias variant as owned by the existing manual target', () => { + mockStore.addSshTarget({ + id: 'ssh-m', + label: 'Prod', + configHost: 'Prod', + host: 'manual.example.com', + port: 22, + username: 'me', + source: 'manual' + }) + loadUserSshConfigMock.mockReturnValue([{ host: 'prod' }]) + sshConfigHostsToTargetsMock.mockReturnValue([candidate({ configHost: 'prod' })]) + + const result = sshStore.importFromSshConfig() + + expect(mockStore.addSshTarget).toHaveBeenCalledTimes(1) + expect(result).toEqual([]) + }) + + it('keeps a case-only alias variant suppressed after the host was deleted', () => { + const added = sshStore.addTarget({ + label: 'Prod', + configHost: 'Prod', + host: 'prod.example.com', + port: 22, + username: 'me' + }) + sshStore.removeTarget(added.id) + loadUserSshConfigMock.mockReturnValue([{ host: 'prod' }]) + sshConfigHostsToTargetsMock.mockReturnValue([candidate({ configHost: 'prod' })]) + + const result = sshStore.importFromSshConfig() + + expect(result).toEqual([]) + expect(mockStore.addSshTarget).toHaveBeenCalledTimes(1) + }) + + it('lifts a tombstone stored under different casing when the host is re-added', () => { + const added = sshStore.addTarget({ + label: 'Prod', + configHost: 'Prod', + host: 'prod.example.com', + port: 22, + username: 'me' + }) + sshStore.removeTarget(added.id) + sshStore.addTarget({ + label: 'prod', + configHost: 'prod', + host: 'prod.example.com', + port: 22, + username: 'me' + }) + + expect(sshStore.listSuppressedSshConfigAliases()).toEqual([]) + }) + it('does not rewrite an unchanged config-sourced target', () => { mockStore.addSshTarget({ id: 'ssh-1', @@ -423,7 +498,7 @@ describe('SshConnectionStore', () => { expect(result).toEqual([]) }) - it('does not tombstone a manual target on delete', () => { + it('suppresses a deleted manual target from config discovery', () => { mockStore.addSshTarget({ id: 'ssh-1', label: 'mini', @@ -435,7 +510,7 @@ describe('SshConnectionStore', () => { }) sshStore.removeTarget('ssh-1') - expect(mockStore.addDeletedSshConfigAlias).not.toHaveBeenCalled() + expect(mockStore.addDeletedSshConfigAlias).toHaveBeenCalledWith('mini') }) it('re-adding a deleted host reclaims its alias so sync stops suppressing it', () => { @@ -557,6 +632,7 @@ describe('SshConnectionStore', () => { sshStore.removeTarget('runtime-ssh-abc') expect(mockStore.addRemovedSshTargetTombstone).not.toHaveBeenCalled() + expect(mockStore.addDeletedSshConfigAlias).not.toHaveBeenCalled() }) it('re-adopts orphaned repos when the same host is re-added', () => { diff --git a/src/main/ssh/ssh-connection-store.ts b/src/main/ssh/ssh-connection-store.ts index 408b4522afa..97fc2e3b32e 100644 --- a/src/main/ssh/ssh-connection-store.ts +++ b/src/main/ssh/ssh-connection-store.ts @@ -1,6 +1,7 @@ import type { Store } from '../persistence' import type { SshRepoReadoption, SshTarget } from '../../shared/ssh-types' import { RUNTIME_OWNED_SSH_TARGET_ID_PREFIX } from '../../shared/execution-host' +import { normalizeSshConfigAlias } from '../../shared/ssh-config-alias' import { loadUserSshConfig, sshConfigHostsToTargets } from './ssh-config-parser' import { buildRemovedSshTargetTombstone, @@ -25,6 +26,10 @@ export class SshConnectionStore { return labels } + listSuppressedSshConfigAliases(): string[] { + return this.store.getDeletedSshConfigAliases() + } + getTarget(id: string): SshTarget | undefined { return this.store.getSshTarget(id) } @@ -87,29 +92,29 @@ export class SshConnectionStore { removeTarget(id: string): void { const target = this.store.getSshTarget(id) - // Why: deleting a config-managed target must record a tombstone; otherwise - // the next ~/.ssh/config sync re-inserts it verbatim (the config entry still - // exists on disk) and the host reappears. Manual targets need no tombstone — - // sync never re-adds them. - if (target && isConfigManagedTarget(target)) { + if (target && !isRuntimeOwnedSshTarget(target)) { const alias = target.configHost ?? target.label if (alias) { + // Why: tombstone so passive ~/.ssh/config sync does not resurrect the host. + // The config picker still lists it so re-pick/save can reclaim the alias. this.store.addDeletedSshConfigAlias(alias) } - } - // Why: record the removed target's host identity (for ALL user-facing - // targets, config-managed or manual) so a later re-add of the same host can - // re-adopt any workspaces orphaned on this id. Runtime-owned targets manage - // their own lifecycle and are never re-adopted. - if (target && !isRuntimeOwnedSshTarget(target)) { this.store.addRemovedSshTargetTombstone(buildRemovedSshTargetTombstone(target, Date.now())) } this.store.removeSshTarget(id) } private reclaimAlias(alias: string | undefined): void { - if (alias) { - this.store.removeDeletedSshConfigAlias(alias) + const normalized = normalizeSshConfigAlias(alias) + if (!normalized) { + return + } + // Why: tombstones persisted before alias folding (and hosts written with different + // casing) must all be lifted, or a re-add stays suppressed for its case variants. + for (const stored of this.store.getDeletedSshConfigAliases()) { + if (normalizeSshConfigAlias(stored) === normalized) { + this.store.removeDeletedSshConfigAlias(stored) + } } } @@ -126,7 +131,11 @@ export class SshConnectionStore { if (options?.reAdopt) { this.store.clearDeletedSshConfigAliases() } - const deletedAliases = new Set(this.store.getDeletedSshConfigAliases()) + // Why: aliases are compared case-insensitively everywhere else (picker, duplicate + // check, tombstones); a case-sensitive Set here would double-insert `Prod` vs `prod`. + const deletedAliases = new Set( + this.store.getDeletedSshConfigAliases().map((alias) => normalizeSshConfigAlias(alias)) + ) const configHosts = loadUserSshConfig() const existingTargets = this.store.getSshTargets() // Map config-managed targets (and legacy targets that strongly look like @@ -136,7 +145,7 @@ export class SshConnectionStore { const syncableByAlias = new Map() const manualAliases = new Set() for (const existing of existingTargets) { - const alias = existing.configHost ?? existing.label + const alias = normalizeSshConfigAlias(existing.configHost ?? existing.label) if ( existing.source === 'manual' || (existing.source === undefined && !isLegacyConfigImportTarget(existing)) @@ -160,7 +169,7 @@ export class SshConnectionStore { const processedAliases = new Set() for (const candidate of candidates) { - const alias = candidate.configHost ?? candidate.label + const alias = normalizeSshConfigAlias(candidate.configHost ?? candidate.label) if (manualAliases.has(alias)) { // A manual target owns this alias — never clobber it. continue @@ -230,16 +239,6 @@ export function isRuntimeOwnedSshTarget(target: SshTarget): boolean { return target.owner?.type === 'on-demand-runtime' } -function isConfigManagedTarget(target: SshTarget): boolean { - // Why: a target is subject to config sync (and therefore needs a tombstone on - // delete) when it is explicitly config-sourced, or a legacy import that sync - // still adopts. Manual targets are excluded — sync never re-adds them. - return ( - target.source === 'ssh-config' || - (target.source === undefined && isLegacyConfigImportTarget(target)) - ) -} - function isLegacyConfigImportTarget(target: SshTarget): boolean { const alias = target.configHost ?? target.label // Why: legacy manual and imported targets both lack `source`. Only adopt the diff --git a/src/main/ssh/ssh-connection-utils.test.ts b/src/main/ssh/ssh-connection-utils.test.ts index eba0de23087..72dd7991d71 100644 --- a/src/main/ssh/ssh-connection-utils.test.ts +++ b/src/main/ssh/ssh-connection-utils.test.ts @@ -1,16 +1,7 @@ -import { EventEmitter } from 'node:events' import { afterEach, describe, expect, it, vi, beforeEach } from 'vitest' import { join } from 'node:path' import { BaseAgent, utils, type ParsedKey } from 'ssh2' -const { spawnMock } = vi.hoisted(() => ({ - spawnMock: vi.fn() -})) - -vi.mock('child_process', () => ({ - spawn: spawnMock -})) - vi.mock('os', () => ({ homedir: () => '/home/testuser' })) @@ -39,32 +30,15 @@ import { findDefaultKeyFile, buildConnectConfig, resolveAgentSocket, - resolveEffectiveProxy, CONNECT_TIMEOUT_MS, INITIAL_RETRY_ATTEMPTS, INITIAL_RETRY_DELAY_MS, - RECONNECT_BACKOFF_MS, - spawnProxyCommand + RECONNECT_BACKOFF_MS } from './ssh-connection-utils' +import { resolveEffectiveProxy } from './ssh-proxy-command' import type { SshTarget } from '../../shared/ssh-types' import type { SshResolvedConfig } from './ssh-config-parser' -type MockProxyProcess = EventEmitter & { - stdin: EventEmitter & { write: ReturnType } - stdout: EventEmitter - stderr: EventEmitter -} - -function createMockProxyProcess(): MockProxyProcess { - const proc = new EventEmitter() as MockProxyProcess - proc.stdin = Object.assign(new EventEmitter(), { - write: vi.fn((_chunk, cb?: (error?: Error | null) => void) => cb?.()) - }) - proc.stdout = new EventEmitter() - proc.stderr = new EventEmitter() - return proc -} - // ── Constants ──────────────────────────────────────────────────────── describe('SSH connection constants', () => { @@ -803,35 +777,3 @@ describe('resolveEffectiveProxy', () => { expect(resolveEffectiveProxy(makeTarget(), null)).toBeUndefined() }) }) - -// ── spawnProxyCommand ─────────────────────────────────────────────── - -describe('spawnProxyCommand', () => { - beforeEach(() => { - spawnMock.mockReset() - }) - - it('removes proxy process listeners when the socket is destroyed', () => { - const proc = createMockProxyProcess() - spawnMock.mockReturnValue(proc) - - const { sock } = spawnProxyCommand( - { kind: 'jump-host', jumpHost: 'bastion.example.com' }, - 'target.example.com', - 22, - 'deploy' - ) - - expect(proc.stdout.listenerCount('data')).toBe(1) - expect(proc.stdout.listenerCount('end')).toBe(1) - expect(proc.stdin.listenerCount('error')).toBe(1) - expect(proc.listenerCount('error')).toBe(1) - - sock.destroy() - - expect(proc.stdout.listenerCount('data')).toBe(0) - expect(proc.stdout.listenerCount('end')).toBe(0) - expect(proc.stdin.listenerCount('error')).toBe(0) - expect(proc.listenerCount('error')).toBe(0) - }) -}) diff --git a/src/main/ssh/ssh-connection-utils.ts b/src/main/ssh/ssh-connection-utils.ts index 77cb5ab07a5..6b0cac00770 100644 --- a/src/main/ssh/ssh-connection-utils.ts +++ b/src/main/ssh/ssh-connection-utils.ts @@ -1,6 +1,3 @@ -import { spawn, type ChildProcess } from 'node:child_process' -import { Duplex } from 'node:stream' -import type { Socket as NetSocket } from 'node:net' import type { ConnectConfig } from 'ssh2' import type { SshTarget, SshConnectionState } from '../../shared/ssh-types' import type { SshResolvedConfig } from './ssh-config-parser' @@ -52,7 +49,9 @@ export function isAuthError(err: Error): boolean { msg.includes('all configured authentication methods failed') || msg.includes('authentication failed') || msg.includes('too many authentication failures') || - /permission denied(?:, please try again\.?| \([^)]*(?:publickey|password|keyboard-interactive|gssapi|hostbased)[^)]*\))/.test(msg) || + /permission denied(?:, please try again\.?| \([^)]*(?:publickey|password|keyboard-interactive|gssapi|hostbased)[^)]*\))/.test( + msg + ) || (err as { level?: string }).level === 'client-authentication' ) } @@ -165,10 +164,6 @@ export function createSshOperationAbortError(): Error & { name: string } { return error } -function cmdEscape(s: string): string { - return `"${s.replace(/"/g, '""')}"` -} - type BuildConnectConfigOptions = { includeAgent?: boolean includePrivateKey?: boolean @@ -251,112 +246,3 @@ function shouldUseResolvedEndpoint(target: SshTarget, resolved: SshResolvedConfi const host = target.host.trim() return host === '' || host === target.configHost || host === target.label } - -// Why: ProxyJump and jumpHost are syntactic sugar for ProxyCommand. -// OpenSSH internally converts `ProxyJump bastion` to -// `ProxyCommand ssh -W %h:%p bastion`. We do the same so that ssh2 -// gets a single proxy spawn path regardless of how the tunnel was configured. -export type EffectiveProxy = - | { kind: 'proxy-command'; command: string } - | { kind: 'jump-host'; jumpHost: string } - -export function resolveEffectiveProxy( - target: SshTarget, - resolved: SshResolvedConfig | null -): EffectiveProxy | undefined { - if (isOpenSshConfigBackedTarget(target) && resolved) { - if (resolved.proxyCommand) { - return { kind: 'proxy-command', command: resolved.proxyCommand } - } - return resolved.proxyJump ? { kind: 'jump-host', jumpHost: resolved.proxyJump } : undefined - } - if (target.proxyCommand) { - return { kind: 'proxy-command', command: target.proxyCommand } - } - if (resolved?.proxyCommand) { - return { kind: 'proxy-command', command: resolved.proxyCommand } - } - const jump = target.jumpHost || resolved?.proxyJump - if (jump) { - return { kind: 'jump-host', jumpHost: jump } - } - return undefined -} - -// Why: ssh2 doesn't natively support ProxyCommand. When the SSH config -// specifies one (e.g. `cloudflared access ssh --hostname %h`), we spawn -// the command and bridge its stdin/stdout into a Duplex stream that ssh2 -// uses as its transport socket via `config.sock`. -function getShellSpawnConfig(command: string): { file: string; args: string[] } { - if (process.platform === 'win32') { - const comspec = process.env.ComSpec || 'cmd.exe' - return { file: comspec, args: ['/d', '/s', '/c', command] } - } - return { file: '/bin/sh', args: ['-c', command] } -} - -export function spawnProxyCommand( - proxy: EffectiveProxy, - host: string, - port: number, - user: string -): { process: ChildProcess; sock: NetSocket } { - const proc = - proxy.kind === 'jump-host' - ? // Why: ProxyJump is structured input, not a shell snippet. Spawn ssh - // directly so jump-host values cannot escape through shell parsing. - spawn('ssh', ['-W', `${host}:${port}`, '--', proxy.jumpHost], { - stdio: ['pipe', 'pipe', 'pipe'] - }) - : (() => { - const escape = process.platform === 'win32' ? cmdEscape : shellEscape - const expanded = proxy.command - .replace(/%h/g, escape(host)) - .replace(/%p/g, escape(String(port))) - .replace(/%r/g, escape(user)) - const shell = getShellSpawnConfig(expanded) - return spawn(shell.file, shell.args, { stdio: ['pipe', 'pipe', 'pipe'] }) - })() - - // Why: a single PassThrough for both directions creates a feedback loop. - // Reads come from the proxy's stdout; writes go to its stdin. - let cleanedUp = false - const cleanup = (): void => { - if (cleanedUp) { - return - } - cleanedUp = true - proc.stdout!.off('data', onStdoutData) - proc.stdout!.off('end', onStdoutEnd) - proc.stdin!.off('error', onInputError) - proc.off('error', onProcessError) - } - const onStdoutData = (data: Buffer): void => { - stream.push(data) - } - const onStdoutEnd = (): void => { - stream.push(null) - } - const onInputError = (err: Error): void => { - stream.destroy(err) - } - const onProcessError = (err: Error): void => { - stream.destroy(err) - } - const stream = new Duplex({ - read() {}, - write(chunk, _encoding, cb) { - proc.stdin!.write(chunk, cb) - }, - destroy(err, cb) { - cleanup() - cb(err) - } - }) - proc.stdout!.on('data', onStdoutData) - proc.stdout!.on('end', onStdoutEnd) - proc.stdin!.on('error', onInputError) - proc.on('error', onProcessError) - - return { process: proc, sock: stream as unknown as NetSocket } -} diff --git a/src/main/ssh/ssh-connection.test.ts b/src/main/ssh/ssh-connection.test.ts index c4bb13fce53..589c0d8e798 100644 --- a/src/main/ssh/ssh-connection.test.ts +++ b/src/main/ssh/ssh-connection.test.ts @@ -172,7 +172,9 @@ const { removeControlSocketPathMock: vi.fn(), // Why mock: attemptConnect probes real ~/.ssh defaults; under fake timers that I/O races the // wall-clock budget helper and flakes as status 'connecting' (CI: tests node 24 shard). - requiresSystemSshForSecurityKeyMock: vi.fn(async () => false), + requiresSystemSshForSecurityKeyMock: vi.fn< + typeof SshTransportSelection.requiresSystemSshForSecurityKey + >(async () => false), spawnSystemSshMock: vi.fn(), spawnSystemSshCommandMock: vi.fn() })) @@ -2239,6 +2241,30 @@ describe('SshConnection', () => { ) }) + it('tries GSSAPI first for a manually owned config-picker target', async () => { + vi.mocked(resolveWithSshG).mockResolvedValue( + createResolvedConfig({ proxyUseFdpass: false, gssapiAuthentication: true }) + ) + const conn = new SshConnection( + createTarget({ + source: 'manual', + configHost: 'prod', + host: 'prod.internal', + gssapiAuthentication: true + }), + createCallbacks() + ) + + await conn.connect() + + expect(spawnSystemSshCommandMock).toHaveBeenCalledWith( + expect.objectContaining({ source: 'manual', configHost: 'prod' }), + 'echo ORCA-SYSTEM-SSH-OK', + expect.objectContaining({ gssapiOnly: true, wrapCommand: false }) + ) + expect(clientInstances).toHaveLength(0) + }) + it('falls back to ssh2 when the GSSAPI-first system SSH attempt fails', async () => { spawnSystemSshCommandMock.mockImplementation(() => createFailingSystemCommandChannel(255, 'Permission denied (gssapi-with-mic,publickey)') diff --git a/src/main/ssh/ssh-connection.ts b/src/main/ssh/ssh-connection.ts index e9fe41c858c..1b19ee2c43e 100644 --- a/src/main/ssh/ssh-connection.ts +++ b/src/main/ssh/ssh-connection.ts @@ -33,13 +33,12 @@ import { isPassphraseError, sleep, buildConnectConfig, - resolveEffectiveProxy, - spawnProxyCommand, wrapRemoteCommandForPosixShell, createSshOperationAbortError, type SshExecOptions, type SshConnectionCallbacks } from './ssh-connection-utils' +import { resolveEffectiveProxy, spawnProxyCommand } from './ssh-proxy-command' import { createCancelledConnectAttemptError, isCancelledConnectAttemptError diff --git a/src/main/ssh/ssh-g-config-resolution.test.ts b/src/main/ssh/ssh-g-config-resolution.test.ts new file mode 100644 index 00000000000..4f21c896376 --- /dev/null +++ b/src/main/ssh/ssh-g-config-resolution.test.ts @@ -0,0 +1,63 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const { existsSyncMock, homedirMock, userInfoMock } = vi.hoisted(() => ({ + existsSyncMock: vi.fn<(path: string) => boolean>(() => true), + homedirMock: vi.fn<() => string>(() => '/home/env'), + userInfoMock: vi.fn<() => { homedir: string }>(() => ({ homedir: '/home/env' })) +})) + +vi.mock('node:fs', () => ({ existsSync: existsSyncMock })) +vi.mock('node:os', () => ({ homedir: homedirMock, userInfo: userInfoMock })) + +import { sshGArgsForHost } from './ssh-g-config-resolution' + +describe('sshGArgsForHost', () => { + beforeEach(() => { + existsSyncMock.mockReset().mockReturnValue(true) + homedirMock.mockReset().mockReturnValue('/home/env') + userInfoMock.mockReset().mockReturnValue({ homedir: '/home/env' }) + }) + + it('keeps OpenSSH default resolution when HOME matches the passwd home', () => { + // Why: the default search still reads /etc/ssh/ssh_config, which the + // SshResolvedConfig.gssapiAuthentication contract depends on. + expect(sshGArgsForHost('prod')).toEqual(['-G', '--', 'prod']) + }) + + it('pins the HOME config when it diverges from the passwd home', () => { + homedirMock.mockReturnValue('/tmp/e2e-home') + + expect(sshGArgsForHost('prod')).toEqual(['-F', '/tmp/e2e-home/.ssh/config', '-G', '--', 'prod']) + expect(existsSyncMock).toHaveBeenCalledWith('/tmp/e2e-home/.ssh/config') + }) + + it('falls back to passwd-home resolution when the HOME config is absent', () => { + // Why: ssh exits 255 on a missing -F file, so a divergent HOME without a + // config must not pin one. The picker lists nothing here, so the wider + // passwd-home resolution never mints a target. + homedirMock.mockReturnValue('/tmp/e2e-home') + existsSyncMock.mockReturnValue(false) + + expect(sshGArgsForHost('prod')).toEqual(['-G', '--', 'prod']) + }) + + it('treats an unavailable passwd entry as a HOME match', () => { + userInfoMock.mockImplementation(() => { + throw new Error('getpwuid failed') + }) + + expect(sshGArgsForHost('prod')).toEqual(['-G', '--', 'prod']) + }) + + it('does not let a leading-dash alias become a flag', () => { + homedirMock.mockReturnValue('/tmp/e2e-home') + + expect(sshGArgsForHost('-oProxyCommand=touch /tmp/pwned')).toEqual([ + '-F', + '/tmp/e2e-home/.ssh/config', + '-G', + '--', + '-oProxyCommand=touch /tmp/pwned' + ]) + }) +}) diff --git a/src/main/ssh/ssh-g-config-resolution.ts b/src/main/ssh/ssh-g-config-resolution.ts index 29c6d5eaae3..e329806ef3c 100644 --- a/src/main/ssh/ssh-g-config-resolution.ts +++ b/src/main/ssh/ssh-g-config-resolution.ts @@ -1,4 +1,7 @@ import { execFile } from 'node:child_process' +import { existsSync } from 'node:fs' +import { join } from 'node:path' +import { homedir, userInfo } from 'node:os' import { resolveSshConfigHomePath } from './ssh-config-path-expansion' export type SshResolvedConfig = { @@ -9,7 +12,10 @@ export type SshResolvedConfig = { identityAgent?: string identitiesOnly: boolean forwardAgent: boolean - /** Effective GSSAPIAuthentication, including distro-wide /etc/ssh defaults. */ + /** + * Effective GSSAPIAuthentication, including distro-wide /etc/ssh defaults — except on the + * HOME-divergent `-F` path (see sshGArgsForHost), where OpenSSH skips the system config. + */ gssapiAuthentication?: boolean proxyCommand?: string proxyUseFdpass: boolean @@ -21,6 +27,31 @@ export type SshResolvedConfig = { const SSH_G_TIMEOUT_MS = 5000 +function passwdHomeSshConfigPath(): string { + try { + return join(userInfo().homedir, '.ssh', 'config') + } catch { + return join(homedir(), '.ssh', 'config') + } +} + +export function sshGArgsForHost(host: string): string[] { + // Why: OpenSSH resolves the default user config via getpwuid, not $HOME. + // Node's loadUserSshConfig uses os.homedir() (HOME-aware). When those differ + // (E2E HOME isolation, sandboxes), pass -F so resolve sees the same file the + // picker listed. Leave the default path alone when HOME matches passwd home + // so /etc/ssh/ssh_config still participates. + // -F also suppresses /etc/ssh/ssh_config, so that path resolves user-only. + // existsSync is load-bearing: ssh exits 255 on a missing -F file. Without a HOME + // config we fall back to passwd-home resolution, whose aliases the picker cannot + // list — resolveUserSshConfigHost rejects those before trusting ssh -G. + const homeConfigPath = join(homedir(), '.ssh', 'config') + if (existsSync(homeConfigPath) && homeConfigPath !== passwdHomeSshConfigPath()) { + return ['-F', homeConfigPath, '-G', '--', host] + } + return ['-G', '--', host] +} + // Why: `ssh -G ` asks OpenSSH for the effective config, including // Include/Match/wildcard inheritance, without reimplementing OpenSSH matching. export function resolveWithSshG(host: string): Promise { @@ -48,13 +79,18 @@ export function resolveWithSshG(host: string): Promise // Why: '--' prevents host labels starting with '-' from becoming SSH flags. // execFile's timeout only signals ssh; keep the null fallback for stuck callbacks. try { - child = execFile('ssh', ['-G', '--', host], { timeout: SSH_G_TIMEOUT_MS }, (err, stdout) => { - if (err) { - settle(() => resolve(null)) - return + child = execFile( + 'ssh', + sshGArgsForHost(host), + { timeout: SSH_G_TIMEOUT_MS }, + (err, stdout) => { + if (err) { + settle(() => resolve(null)) + return + } + settle(() => resolve(parseSshGOutput(stdout))) } - settle(() => resolve(parseSshGOutput(stdout))) - }) + ) } catch { settle(() => resolve(null)) } diff --git a/src/main/ssh/ssh-multi-key-authentication.test.ts b/src/main/ssh/ssh-multi-key-authentication.test.ts index 693e754b661..32942facd27 100644 --- a/src/main/ssh/ssh-multi-key-authentication.test.ts +++ b/src/main/ssh/ssh-multi-key-authentication.test.ts @@ -127,6 +127,29 @@ describe('ordered SSH private-key authentication', () => { expect(unresolvedImport.authHandler).toBeUndefined() }) + it('offers every resolved key for a manually owned config-picker target', () => { + const config = buildConnectConfig( + makeTarget({ + source: 'manual', + configHost: 'prod', + host: 'prod.internal', + identityFile: undefined + }), + makeResolved(), + { includeAgent: false, includePrivateKey: true } + ) + + expect(nextAuth(config, true)).toMatchObject({ type: 'none' }) + expect(nextAuth(config, false)).toMatchObject({ + type: 'publickey', + key: Buffer.from('/keys/unauthorized-first') + }) + expect(nextAuth(config, false)).toMatchObject({ + type: 'publickey', + key: Buffer.from('/keys/authorized-second') + }) + }) + it('resets ordered authentication for credential retries without extra key reads', () => { const config = buildConnectConfig(makeTarget(), makeResolved(), { includeAgent: false, diff --git a/src/main/ssh/ssh-proxy-command.test.ts b/src/main/ssh/ssh-proxy-command.test.ts new file mode 100644 index 00000000000..aae440b4c6e --- /dev/null +++ b/src/main/ssh/ssh-proxy-command.test.ts @@ -0,0 +1,189 @@ +import { EventEmitter } from 'node:events' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const { spawnMock } = vi.hoisted(() => ({ + spawnMock: vi.fn() +})) + +vi.mock('child_process', () => ({ + spawn: spawnMock +})) + +import { spawnProxyCommand } from './ssh-proxy-command' + +type MockProxyProcess = EventEmitter & { + stdin: EventEmitter & { write: ReturnType } + stdout: EventEmitter & { pause: ReturnType; resume: ReturnType } + stderr: EventEmitter +} + +function createMockProxyProcess(): MockProxyProcess { + const proc = new EventEmitter() as MockProxyProcess + proc.stdin = Object.assign(new EventEmitter(), { + write: vi.fn((_chunk, cb?: (error?: Error | null) => void) => cb?.()) + }) + proc.stdout = Object.assign(new EventEmitter(), { pause: vi.fn(), resume: vi.fn() }) + proc.stderr = new EventEmitter() + return proc +} + +// ── spawnProxyCommand ─────────────────────────────────────────────── + +describe('spawnProxyCommand', () => { + beforeEach(() => { + spawnMock.mockReset() + }) + + it('removes proxy process listeners when the socket is destroyed', () => { + const proc = createMockProxyProcess() + spawnMock.mockReturnValue(proc) + + const { sock } = spawnProxyCommand( + { kind: 'jump-host', jumpHost: 'bastion.example.com' }, + 'target.example.com', + 22, + 'deploy' + ) + + expect(proc.stdout.listenerCount('data')).toBe(1) + expect(proc.stdout.listenerCount('end')).toBe(1) + expect(proc.stderr.listenerCount('data')).toBe(1) + expect(proc.stdin.listenerCount('error')).toBe(1) + expect(proc.listenerCount('error')).toBe(1) + + sock.destroy() + + expect(proc.stdout.listenerCount('data')).toBe(0) + expect(proc.stdout.listenerCount('end')).toBe(0) + expect(proc.stderr.listenerCount('data')).toBe(0) + expect(proc.stdin.listenerCount('error')).toBe(0) + expect(proc.listenerCount('error')).toBe(0) + }) + + it('drains proxy stderr so the pipe cannot fill and block the child', () => { + const proc = createMockProxyProcess() + spawnMock.mockReturnValue(proc) + const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) + + spawnProxyCommand( + { kind: 'jump-host', jumpHost: 'bastion.example.com' }, + 'target.example.com', + 22, + 'deploy' + ) + proc.stderr.emit('data', Buffer.from('bastion: permission denied\n')) + + expect(consoleError).toHaveBeenCalledWith('[ssh-proxy-command] bastion: permission denied') + consoleError.mockRestore() + }) + + it('expands a comma-separated ProxyJump chain into -J plus a final hop', () => { + spawnMock.mockReturnValue(createMockProxyProcess()) + + spawnProxyCommand( + { kind: 'jump-host', jumpHost: 'first.example.com, second.example.com,third.example.com' }, + 'target.example.com', + 2222, + 'deploy' + ) + + expect(spawnMock).toHaveBeenCalledWith( + 'ssh', + [ + '-W', + 'target.example.com:2222', + '-J', + 'first.example.com,second.example.com', + '--', + 'third.example.com' + ], + expect.anything() + ) + }) + + it('tunnels a single ProxyJump hop without a -J chain', () => { + spawnMock.mockReturnValue(createMockProxyProcess()) + + spawnProxyCommand( + { kind: 'jump-host', jumpHost: 'bastion.example.com' }, + 'target.example.com', + 22, + 'deploy' + ) + + expect(spawnMock).toHaveBeenCalledWith( + 'ssh', + ['-W', 'target.example.com:22', '--', 'bastion.example.com'], + expect.anything() + ) + }) + + it('pauses the proxy stdout when the transport stream applies backpressure', () => { + const proc = createMockProxyProcess() + spawnMock.mockReturnValue(proc) + + const { sock } = spawnProxyCommand( + { kind: 'jump-host', jumpHost: 'bastion.example.com' }, + 'target.example.com', + 22, + 'deploy' + ) + // Nothing reads the Duplex, so pushing past the high-water mark backs up. + for (let i = 0; i < 64; i += 1) { + proc.stdout.emit('data', Buffer.alloc(4096)) + } + + expect(proc.stdout.pause).toHaveBeenCalled() + + while (sock.read() !== null) { + // Drain below the high-water mark so the Duplex asks for more. + } + + expect(proc.stdout.resume).toHaveBeenCalled() + }) + + describe('on Windows', () => { + const realPlatform = process.platform + + const setPlatform = (platform: string): void => { + Object.defineProperty(process, 'platform', { value: platform, configurable: true }) + } + + afterEach(() => { + setPlatform(realPlatform) + }) + + it('passes the cmd.exe command line verbatim so inner quotes survive', () => { + setPlatform('win32') + spawnMock.mockReturnValue(createMockProxyProcess()) + + spawnProxyCommand( + { kind: 'proxy-command', command: 'cloudflared access ssh --hostname %h --port %p' }, + 'target.example.com', + 22, + 'deploy' + ) + + expect(spawnMock).toHaveBeenCalledWith( + process.env.ComSpec || 'cmd.exe', + ['/d', '/s', '/c', '"cloudflared access ssh --hostname "target.example.com" --port "22""'], + expect.objectContaining({ windowsVerbatimArguments: true }) + ) + }) + + it('refuses values that cmd.exe cannot quote safely', () => { + setPlatform('win32') + spawnMock.mockReturnValue(createMockProxyProcess()) + + expect(() => + spawnProxyCommand( + { kind: 'proxy-command', command: 'cloudflared access ssh --hostname %h' }, + 'host&echo injected', + 22, + 'deploy' + ) + ).toThrow(/cannot be safely expanded on Windows/) + expect(spawnMock).not.toHaveBeenCalled() + }) + }) +}) diff --git a/src/main/ssh/ssh-proxy-command.ts b/src/main/ssh/ssh-proxy-command.ts new file mode 100644 index 00000000000..c1a64ed6482 --- /dev/null +++ b/src/main/ssh/ssh-proxy-command.ts @@ -0,0 +1,178 @@ +import { spawn, type ChildProcess } from 'node:child_process' +import { Duplex } from 'node:stream' +import type { Socket as NetSocket } from 'node:net' +import type { SshTarget } from '../../shared/ssh-types' +import type { SshResolvedConfig } from './ssh-config-parser' +import { shellEscape } from './ssh-connection-utils' +import { isOpenSshConfigBackedTarget } from './system-ssh-args' + +// Why: ProxyJump and jumpHost are syntactic sugar for ProxyCommand. +// OpenSSH internally converts `ProxyJump bastion` to +// `ProxyCommand ssh -W %h:%p bastion`. We do the same so that ssh2 +// gets a single proxy spawn path regardless of how the tunnel was configured. +export type EffectiveProxy = + | { kind: 'proxy-command'; command: string } + | { kind: 'jump-host'; jumpHost: string } + +export function resolveEffectiveProxy( + target: SshTarget, + resolved: SshResolvedConfig | null +): EffectiveProxy | undefined { + if (isOpenSshConfigBackedTarget(target) && resolved) { + if (resolved.proxyCommand) { + return { kind: 'proxy-command', command: resolved.proxyCommand } + } + return resolved.proxyJump ? { kind: 'jump-host', jumpHost: resolved.proxyJump } : undefined + } + if (target.proxyCommand) { + return { kind: 'proxy-command', command: target.proxyCommand } + } + if (resolved?.proxyCommand) { + return { kind: 'proxy-command', command: resolved.proxyCommand } + } + const jump = target.jumpHost || resolved?.proxyJump + if (jump) { + return { kind: 'jump-host', jumpHost: jump } + } + return undefined +} + +// Why: cmd.exe has no quoting that survives arbitrary values — `%VAR%` expands +// inside quotes and `""` re-opens the unquoted state — so the only safe Windows +// expansion is to reject metacharacters instead of pretending to escape them. +// Hosts, ports and usernames never legitimately contain these. +const CMD_UNSAFE_PATTERN = /["%&|<>^\r\n]/ + +function cmdEscape(s: string): string { + if (CMD_UNSAFE_PATTERN.test(s)) { + throw new Error( + `ProxyCommand value cannot be safely expanded on Windows (unsupported characters): ${s}` + ) + } + return `"${s}"` +} + +type ShellSpawnConfig = { file: string; args: string[]; windowsVerbatimArguments: boolean } + +// Why: ssh2 doesn't natively support ProxyCommand. When the SSH config +// specifies one (e.g. `cloudflared access ssh --hostname %h`), we spawn +// the command and bridge its stdin/stdout into a Duplex stream that ssh2 +// uses as its transport socket via `config.sock`. +function getShellSpawnConfig(command: string): ShellSpawnConfig { + if (process.platform === 'win32') { + const comspec = process.env.ComSpec || 'cmd.exe' + // Why: mirror Node's own `shell: true` form. `/s` makes cmd.exe strip the + // outer quotes and take the rest verbatim; without verbatim arguments Node + // would backslash-escape inner quotes, which cmd.exe does not understand. + return { + file: comspec, + args: ['/d', '/s', '/c', `"${command}"`], + windowsVerbatimArguments: true + } + } + return { file: '/bin/sh', args: ['-c', command], windowsVerbatimArguments: false } +} + +// Why: ProxyJump takes a comma-separated chain, but `ssh -W host:port dest` +// only tunnels through a single final hop. Preceding hops become that hop's own +// -J chain, which is how OpenSSH expands a multi-hop ProxyJump. +function jumpHostSpawnArgs(jumpHost: string, host: string, port: number): string[] { + const hops = jumpHost + .split(',') + .map((hop) => hop.trim()) + .filter(Boolean) + const destination = hops.at(-1) ?? jumpHost + const chain = hops.slice(0, -1) + return [ + '-W', + `${host}:${port}`, + ...(chain.length > 0 ? ['-J', chain.join(',')] : []), + '--', + destination + ] +} + +export function spawnProxyCommand( + proxy: EffectiveProxy, + host: string, + port: number, + user: string +): { process: ChildProcess; sock: NetSocket } { + const proc = + proxy.kind === 'jump-host' + ? // Why: ProxyJump is structured input, not a shell snippet. Spawn ssh + // directly so jump-host values cannot escape through shell parsing. + spawn('ssh', jumpHostSpawnArgs(proxy.jumpHost, host, port), { + stdio: ['pipe', 'pipe', 'pipe'] + }) + : (() => { + const escape = process.platform === 'win32' ? cmdEscape : shellEscape + const expanded = proxy.command + .replace(/%h/g, escape(host)) + .replace(/%p/g, escape(String(port))) + .replace(/%r/g, escape(user)) + const shell = getShellSpawnConfig(expanded) + return spawn(shell.file, shell.args, { + stdio: ['pipe', 'pipe', 'pipe'], + windowsVerbatimArguments: shell.windowsVerbatimArguments + }) + })() + + // Why: a single PassThrough for both directions creates a feedback loop. + // Reads come from the proxy's stdout; writes go to its stdin. + let cleanedUp = false + const cleanup = (): void => { + if (cleanedUp) { + return + } + cleanedUp = true + proc.stdout!.off('data', onStdoutData) + proc.stdout!.off('end', onStdoutEnd) + proc.stderr!.off('data', onStderrData) + proc.stdin!.off('error', onInputError) + proc.off('error', onProcessError) + } + const onStdoutData = (data: Buffer): void => { + // Why: honour the Duplex's backpressure so a slow ssh2 consumer cannot + // buffer the proxy's output unboundedly. + if (!stream.push(data)) { + proc.stdout!.pause() + } + } + // Why: an undrained stderr pipe fills and blocks the proxy process, which + // looks like a silently hung connection. + const onStderrData = (data: Buffer): void => { + const text = data.toString('utf-8').trimEnd() + if (text) { + console.error(`[ssh-proxy-command] ${text}`) + } + } + const onStdoutEnd = (): void => { + stream.push(null) + } + const onInputError = (err: Error): void => { + stream.destroy(err) + } + const onProcessError = (err: Error): void => { + stream.destroy(err) + } + const stream = new Duplex({ + read() { + proc.stdout!.resume() + }, + write(chunk, _encoding, cb) { + proc.stdin!.write(chunk, cb) + }, + destroy(err, cb) { + cleanup() + cb(err) + } + }) + proc.stdout!.on('data', onStdoutData) + proc.stdout!.on('end', onStdoutEnd) + proc.stderr!.on('data', onStderrData) + proc.stdin!.on('error', onInputError) + proc.on('error', onProcessError) + + return { process: proc, sock: stream as unknown as NetSocket } +} diff --git a/src/main/ssh/ssh-relay-session.ts b/src/main/ssh/ssh-relay-session.ts index d413f45f044..c8440f6c239 100644 --- a/src/main/ssh/ssh-relay-session.ts +++ b/src/main/ssh/ssh-relay-session.ts @@ -15,6 +15,7 @@ import type { SshPtyRecoveryActivationLease } from '../providers/ssh-pty-notific import { isSshPtyIdentityMismatchError, isSshPtyNotFoundError } from '../providers/ssh-pty-errors' import { toAppSshPtyId, toRelaySshPtyId } from '../providers/ssh-pty-id' import { SshFilesystemProvider } from '../providers/ssh-filesystem-provider' +import { isMethodNotFoundError } from './ssh-filesystem-stream-reader' import { SshGitProvider } from '../providers/ssh-git-provider' import { agentHookServer } from '../agent-hooks/server' import { isAgentStatusHooksEnabled } from '../agent-hooks/managed-agent-hook-controls' @@ -86,6 +87,11 @@ import { parseRemoteOrcaCliPostOutput } from './ssh-remote-orchestration-post-output' import { toSshExecutionHostId, type ExecutionHostId } from '../../shared/execution-host' +import { + SSH_AI_VAULT_LIST_SESSIONS_METHOD, + SSH_AI_VAULT_LIST_SESSIONS_TIMEOUT_MS, + type SshAiVaultRelayListParams +} from '../../shared/ssh-ai-vault-relay' import { isTerminalLeafId, makePaneKey } from '../../shared/stable-pane-id' import { isValidTerminalTabId } from '../../shared/terminal-tab-id' import { @@ -272,6 +278,7 @@ export class SshRelaySession { private currentConnection: SshConnection | null = null private hostPlatform: RemoteHostPlatform | null = null private remoteCliBridgeEnv: RemoteCliBridgeEnv | null = null + private aiVaultListMethodSupported: boolean | null = null private pendingPtyReattaches = new Map() private readonly ptyRecoveryRetention = new SshPtyRecoveryRetentionBudget() private activePtyProviderGeneration: number | null = null @@ -377,6 +384,33 @@ export class SshRelaySession { } } + async requestAiVaultSessionList( + params: SshAiVaultRelayListParams, + options: { signal?: AbortSignal; timeoutMs?: number } = {} + ): Promise { + if (this.aiVaultListMethodSupported === false) { + return null + } + const mux = this.mux + if (!mux || mux.isDisposed() || this._state !== 'ready') { + throw new Error('SSH relay is not ready') + } + try { + const result = await mux.request(SSH_AI_VAULT_LIST_SESSIONS_METHOD, params, { + signal: options.signal, + timeoutMs: options.timeoutMs ?? SSH_AI_VAULT_LIST_SESSIONS_TIMEOUT_MS + }) + this.aiVaultListMethodSupported = true + return result + } catch (error) { + if (isMethodNotFoundError(error)) { + this.aiVaultListMethodSupported = false + return null + } + throw error + } + } + getPortScanner(): PortScanner | null { return this.portScanner } @@ -395,6 +429,7 @@ export class SshRelaySession { throw new Error(`Cannot establish relay session in state: ${this._state}`) } this._state = 'deploying' + this.aiVaultListMethodSupported = null this.currentConnection = conn try { @@ -528,6 +563,7 @@ export class SshRelaySession { this.abortController = abortController this._state = 'reconnecting' + this.aiVaultListMethodSupported = null this.currentConnection = conn // Why: stop scanning before teardownProviders so the poll timer can't fire against a disposed multiplexer. diff --git a/src/main/ssh/ssh-remote-platform-detection.test.ts b/src/main/ssh/ssh-remote-platform-detection.test.ts index 71fc4e7c0cd..aa3fb3a0916 100644 --- a/src/main/ssh/ssh-remote-platform-detection.test.ts +++ b/src/main/ssh/ssh-remote-platform-detection.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { SshConnection } from './ssh-connection' const execCommandMock = vi.hoisted(() => vi.fn()) @@ -16,9 +16,19 @@ function decodePowerShellCommand(command: string): string { return match ? Buffer.from(match[1], 'base64').toString('utf16le') : '' } +/** OpenSSH refuses session channels past MaxSessions with reason 2 + "open failed". */ +function maxSessionsError(): Error { + return Object.assign(new Error('(SSH) Channel open failure: open failed'), { reason: 2 }) +} + describe('detectRemoteHostPlatform', () => { beforeEach(() => { execCommandMock.mockReset() + vi.spyOn(console, 'warn').mockImplementation(() => {}) + }) + + afterEach(() => { + vi.restoreAllMocks() }) it('detects POSIX hosts from uname output', async () => { @@ -109,3 +119,120 @@ describe('detectRemoteHostPlatform', () => { expect(usedWhitespaceFieldSplit).toBe(false) }) }) + +describe('detectRemoteHostPlatform failure reporting', () => { + beforeEach(() => { + execCommandMock.mockReset() + vi.spyOn(console, 'warn').mockImplementation(() => {}) + }) + + afterEach(() => { + vi.restoreAllMocks() + }) + + it('does not misreport a refused exec channel as an unsupported platform', async () => { + execCommandMock.mockRejectedValue(maxSessionsError()) + + // The host is linux-x64 and fully supported; the probe never ran. + await expect(detectRemoteHostPlatform(conn)).rejects.toThrow(/open failed/iu) + await expect(detectRemoteHostPlatform(conn)).rejects.toMatchObject({ + cause: expect.objectContaining({ reason: 2 }) + }) + // Both probes run: the second gets a fresh session-channel retry budget. + expect(execCommandMock).toHaveBeenCalledTimes(4) + }) + + it('still detects Windows when the uname probe hits the session limit', async () => { + execCommandMock + .mockRejectedValueOnce(maxSessionsError()) + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ Windows AMD64\r\n') + + await expect(detectRemoteHostPlatform(conn)).resolves.toMatchObject({ + relayPlatform: 'win32-x64' + }) + }) + + it('skips the second probe when the first channel never confirmed close', async () => { + const error = Object.assign(new Error('boom'), { sshChannelCloseConfirmed: false }) + execCommandMock.mockRejectedValueOnce(error) + + await expect(detectRemoteHostPlatform(conn)).rejects.toBe(error) + expect(execCommandMock).toHaveBeenCalledTimes(1) + }) + + it('skips the second probe when the first was cancelled', async () => { + const error = Object.assign(new Error('SSH operation was cancelled'), { name: 'AbortError' }) + execCommandMock.mockRejectedValueOnce(error) + + await expect(detectRemoteHostPlatform(conn)).rejects.toBe(error) + expect(execCommandMock).toHaveBeenCalledTimes(1) + }) + + it('prefers a refused channel over the other probe non-zero exit', async () => { + execCommandMock + .mockRejectedValueOnce(new Error('Command "sh -c ..." failed (exit 127): sh: not found')) + .mockRejectedValueOnce(maxSessionsError()) + + await expect(detectRemoteHostPlatform(conn)).rejects.toThrow(/open failed/u) + await expect(detectRemoteHostPlatform(conn)).rejects.not.toThrow(/exit 127/u) + }) + + it('prefers unrecognized uname output over a failed PowerShell probe', async () => { + execCommandMock + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ Linux') + .mockRejectedValueOnce(new Error('powershell.exe: not found')) + + await expect(detectRemoteHostPlatform(conn)).rejects.toThrow(/__ORCA_REMOTE_PLATFORM__ Linux/u) + }) + + it('reports the raw probe output when a POSIX host yields no marker line', async () => { + // Restricted shell / ForceCommand: the probe command is swallowed, banner only. + execCommandMock.mockResolvedValue('Welcome to pc-server05\n') + + await expect(detectRemoteHostPlatform(conn)).rejects.toThrow(/pc-server05/u) + }) + + it('truncates a long banner in the thrown message but logs a longer tail', async () => { + execCommandMock.mockResolvedValue(`${'banner line\n'.repeat(500)}goodbye\n`) + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + const error = await detectRemoteHostPlatform(conn).catch((err: Error) => err) + + expect(error).toBeInstanceOf(Error) + expect((error as Error).message).not.toContain('\n') + expect((error as Error).message.length).toBeLessThanOrEqual(300) + expect(String(warnSpy.mock.calls[0]?.[0]).length).toBeGreaterThan(600) + }) + + it('returns null when a parsed uname is genuinely unsupported', async () => { + execCommandMock + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ FreeBSD x86_64\n') + .mockRejectedValueOnce(new Error('powershell.exe: not found')) + + await expect(detectRemoteHostPlatform(conn)).resolves.toBeNull() + }) + + it('does not call an unmappable uname unsupported when PowerShell was refused', async () => { + // Cygwin sh on a win32-x64 host: only PowerShell can settle it, and it never ran. + execCommandMock + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ CYGWIN_NT-10.0 x86_64\n') + .mockRejectedValueOnce(maxSessionsError()) + + const error = await detectRemoteHostPlatform(conn).catch((err: unknown) => err) + + expect(error).toBeInstanceOf(Error) + expect((error as Error).message).toMatch(/open failed/iu) + expect((error as Error).message).not.toMatch(/unsupported/iu) + expect((error as Error).cause).toMatchObject({ reason: 2 }) + }) + + it('falls through to PowerShell for a Cygwin uname it cannot map', async () => { + execCommandMock + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ CYGWIN_NT-10.0 x86_64\n') + .mockResolvedValueOnce('__ORCA_REMOTE_PLATFORM__ Windows AMD64\r\n') + + await expect(detectRemoteHostPlatform(conn)).resolves.toMatchObject({ + relayPlatform: 'win32-x64' + }) + }) +}) diff --git a/src/main/ssh/ssh-remote-platform-detection.ts b/src/main/ssh/ssh-remote-platform-detection.ts index 44c31e617e4..5f830fb7449 100644 --- a/src/main/ssh/ssh-remote-platform-detection.ts +++ b/src/main/ssh/ssh-remote-platform-detection.ts @@ -5,27 +5,128 @@ import { } from '../../shared/process-output-field-scanner' import { parseUnameToRelayPlatform, type RelayPlatform } from './relay-protocol' import { execCommand } from './ssh-relay-deploy-helpers' +import { isUnconfirmedSshCommandTermination } from './ssh-relay-exec-command' +import { isSshSessionLimitError } from './ssh-session-limit-error' import { getRemoteHostPlatform, type RemoteHostPlatform } from './ssh-remote-platform' import { powerShellCommand } from './ssh-remote-powershell' const PLATFORM_PROBE_MARKER = '__ORCA_REMOTE_PLATFORM__' +const MAX_UNAME_FIELD_CHARS = 64 +const MAX_THROWN_OUTPUT_CHARS = 200 +const MAX_LOGGED_OUTPUT_CHARS = 1000 +const EXEC_TIMEOUT_MESSAGE = /timed out after \d+s$/u + +type PlatformProbeOutcome = + | { kind: 'detected'; platform: RelayPlatform } + | { kind: 'unsupported'; uname: string } + | { kind: 'unparsed'; output: string } + | { kind: 'failed'; error: unknown } export async function detectRemoteHostPlatform( conn: SshConnection, options?: { signal?: AbortSignal } ): Promise { - const unamePlatform = await detectUnamePlatform(conn, options?.signal) - if (unamePlatform) { - return getRemoteHostPlatform(unamePlatform) + const uname = await detectUnamePlatform(conn, options?.signal) + if (uname.kind === 'detected') { + return getRemoteHostPlatform(uname.platform) } - const windowsPlatform = await detectWindowsPlatform(conn, options?.signal) - return windowsPlatform ? getRemoteHostPlatform(windowsPlatform) : null + if (uname.kind === 'failed' && shouldAbandonAfterUnameProbe(uname.error)) { + throw uname.error + } + const windows = await detectWindowsPlatform(conn, options?.signal) + if (windows.kind === 'detected') { + return getRemoteHostPlatform(windows.platform) + } + // Why: only the PowerShell probe can settle a uname the parser cannot map + // (Cygwin, say), so a refused or timed-out channel leaves it unsettled. + const windowsProbeNeverRan = windows.kind === 'failed' && isTransportShapedError(windows.error) + if ((uname.kind === 'unsupported' && !windowsProbeNeverRan) || windows.kind === 'unsupported') { + const reported = uname.kind === 'unsupported' ? uname.uname : probeUname(windows) + console.warn(`[ssh-relay] Remote reported an unsupported platform: ${reported}`) + return null + } + console.warn( + `[ssh-relay] Remote platform detection failed (uname probe: ${uname.kind}, PowerShell probe: ${windows.kind}). ` + + `Remote output: "${summarizeProbeOutput(probeEvidence(uname) || probeEvidence(windows), MAX_LOGGED_OUTPUT_CHARS)}"` + ) + throw undetectedPlatformError(uname, windows) +} + +// Why: an unconfirmed close still holds the sshd session slot, so a second +// probe only burns another exec timeout before being refused too. +function shouldAbandonAfterUnameProbe(error: unknown): boolean { + return ( + (error instanceof Error && error.name === 'AbortError') || + isUnconfirmedSshCommandTermination(error) + ) +} + +/** Precedence: transport failure from either probe, then uname, then PowerShell. */ +function undetectedPlatformError( + uname: PlatformProbeOutcome, + windows: PlatformProbeOutcome +): Error { + for (const outcome of [uname, windows]) { + if (outcome.kind === 'failed' && isTransportShapedError(outcome.error)) { + return wrapProbeError(outcome.error) + } + } + if (uname.kind === 'failed') { + return wrapProbeError(uname.error) + } + if (uname.kind === 'unparsed') { + return unrecognizedOutputError(uname.output) + } + if (windows.kind === 'failed') { + return wrapProbeError(windows.error) + } + return unrecognizedOutputError(probeOutput(windows)) +} + +// Why: a refused or timed-out channel explains the failure better than the +// other probe's mundane non-zero exit (e.g. "sh: not found" on Windows). +function isTransportShapedError(error: unknown): boolean { + return ( + isSshSessionLimitError(error) || + isUnconfirmedSshCommandTermination(error) || + (error instanceof Error && EXEC_TIMEOUT_MESSAGE.test(error.message)) + ) +} + +function wrapProbeError(error: unknown): Error { + const message = error instanceof Error ? error.message : String(error) + return new Error(`Could not detect the remote platform: ${message}`, { cause: error }) +} + +function unrecognizedOutputError(output: string): Error { + return new Error( + `Remote platform probe returned no recognizable output. Remote output: "${summarizeProbeOutput(output, MAX_THROWN_OUTPUT_CHARS)}"` + ) +} + +function probeOutput(outcome: PlatformProbeOutcome): string { + return outcome.kind === 'unparsed' ? outcome.output : '' +} + +function probeUname(outcome: PlatformProbeOutcome): string { + return outcome.kind === 'unsupported' ? outcome.uname : '' +} + +function probeEvidence(outcome: PlatformProbeOutcome): string { + return probeOutput(outcome) || probeUname(outcome) +} + +// Why: the marker is printed last, so the tail holds the evidence; collapsing +// CR/LF keeps a Windows banner from becoming a multi-line renderer message. +function summarizeProbeOutput(output: string, maxChars: number): string { + const collapsed = output.replace(/\s+/gu, ' ').trim() + return collapsed.length > maxChars ? `…${collapsed.slice(-maxChars)}` : collapsed } async function detectUnamePlatform( conn: SshConnection, signal?: AbortSignal -): Promise { +): Promise { try { // Why: Remote startup output may omit its trailing newline and must not absorb the marker. const command = `printf '\\n%s ' '${PLATFORM_PROBE_MARKER}'; uname -sm` @@ -33,16 +134,16 @@ async function detectUnamePlatform( ? await execCommand(conn, command, { signal }) : await execCommand(conn, command) return parseRemotePlatformOutput(output) - } catch { + } catch (error) { signal?.throwIfAborted() - return null + return { kind: 'failed', error } } } async function detectWindowsPlatform( conn: SshConnection, signal?: AbortSignal -): Promise { +): Promise { try { const script = [ '$arch = $env:PROCESSOR_ARCHITECTURE', @@ -56,13 +157,14 @@ async function detectWindowsPlatform( ...(signal ? { signal } : {}) }) return parseRemotePlatformOutput(output) - } catch { + } catch (error) { signal?.throwIfAborted() - return null + return { kind: 'failed', error } } } -function parseRemotePlatformOutput(output: string): RelayPlatform | null { +function parseRemotePlatformOutput(output: string): PlatformProbeOutcome { + let unsupportedUname = '' // Why: SSH startup noise can resemble valid probe output and select the wrong relay. for (const line of iterateProcessOutputLines(output)) { const parts = getProcessOutputFields(line, 3) @@ -71,8 +173,16 @@ function parseRemotePlatformOutput(output: string): RelayPlatform | null { } const platform = parseUnameToRelayPlatform(parts[1], parts[2]) if (platform) { - return platform + return { kind: 'detected', platform } } + unsupportedUname = `${clampUnameField(parts[1])} ${clampUnameField(parts[2])}` } - return null + return unsupportedUname + ? { kind: 'unsupported', uname: unsupportedUname } + : { kind: 'unparsed', output } +} + +// Why: a single field can be kilobytes — the scanner reads up to 4096 chars. +function clampUnameField(field: string): string { + return field.length > MAX_UNAME_FIELD_CHARS ? `${field.slice(0, MAX_UNAME_FIELD_CHARS)}…` : field } diff --git a/src/main/text-generation/commit-message-text-generation.test.ts b/src/main/text-generation/commit-message-text-generation.test.ts index 13feda4006c..5c21ffa231e 100644 --- a/src/main/text-generation/commit-message-text-generation.test.ts +++ b/src/main/text-generation/commit-message-text-generation.test.ts @@ -1,7 +1,7 @@ /* eslint-disable max-lines -- Why: local/remote generation, cancellation, and env propagation share subprocess mocks; splitting would obscure the cross-path invariants these tests protect. */ -import { exec, spawn } from 'node:child_process' +import { spawn } from 'node:child_process' import type * as ChildProcess from 'node:child_process' import { EventEmitter } from 'node:events' import { beforeEach, describe, expect, it, vi } from 'vitest' @@ -20,21 +20,22 @@ import { trimGeneratedCommitMessage } from './commit-message-text-generation' +const { terminateWindowsProcessTreeMock } = vi.hoisted(() => ({ + terminateWindowsProcessTreeMock: vi.fn(async () => {}) +})) + +vi.mock('../windows-process-tree-kill', () => ({ + terminateWindowsProcessTree: terminateWindowsProcessTreeMock +})) + vi.mock('child_process', async (importOriginal) => { const actual = await importOriginal() return { ...actual, - exec: vi.fn((_command, callback) => { - if (typeof callback === 'function') { - callback(null, '', '') - } - return new actual.ChildProcess() - }), spawn: vi.fn(actual.spawn) } }) -const execMock = vi.mocked(exec) const spawnMock = vi.mocked(spawn) type MockDiscoveryChild = EventEmitter & { @@ -71,7 +72,7 @@ function withPlatform(platform: NodeJS.Platform, fn: () => T): T { function expectChildTerminated(child: { pid: number; kill: ReturnType }): void { if (process.platform === 'win32') { - expect(execMock).toHaveBeenCalledWith(`taskkill /pid ${child.pid} /T /F`, expect.any(Function)) + expect(terminateWindowsProcessTreeMock).toHaveBeenCalledWith(child.pid) expect(child.kill).not.toHaveBeenCalled() return } @@ -79,7 +80,8 @@ function expectChildTerminated(child: { pid: number; kill: ReturnType { - execMock.mockClear() + terminateWindowsProcessTreeMock.mockClear() + terminateWindowsProcessTreeMock.mockResolvedValue(undefined) spawnMock.mockClear() }) @@ -504,6 +506,40 @@ describe('discoverCommitMessageModelsLocal', () => { } }) + it('keeps the Codex home locked after a discovery timeout until the child closes', async () => { + vi.useFakeTimers() + const firstChild = createMockDiscoveryChild() + const secondChild = createMockDiscoveryChild() + spawnMock.mockReturnValueOnce(firstChild as never).mockReturnValueOnce(secondChild as never) + const env = { CODEX_HOME: '/managed/codex-discovery-home' } + + try { + const first = discoverCommitMessageModelsLocal('codex', env) + await vi.advanceTimersByTimeAsync(0) + const second = discoverCommitMessageModelsLocal('codex', env) + await vi.advanceTimersByTimeAsync(60_000) + + await expect(first).resolves.toMatchObject({ + success: false, + error: 'Codex model discovery timed out after 60s.' + }) + expectChildTerminated(firstChild) + expect(spawnMock).toHaveBeenCalledTimes(1) + + firstChild.emit('close', null) + await vi.advanceTimersByTimeAsync(0) + expect(spawnMock).toHaveBeenCalledTimes(2) + secondChild.stdout.emit( + 'data', + Buffer.from(JSON.stringify({ models: [{ slug: 'gpt-5.5', display_name: 'GPT-5.5' }] })) + ) + secondChild.emit('close', 0) + await expect(second).resolves.toMatchObject({ success: true, defaultModelId: 'gpt-5.5' }) + } finally { + vi.useRealTimers() + } + }) + it('settles and detaches model discovery when output exceeds the limit', async () => { const child = createMockDiscoveryChild() spawnMock.mockReturnValue(child as never) @@ -1618,6 +1654,129 @@ describe('generateCommitMessageFromContext', () => { } }) + it('publishes Codex cancellation immediately but holds its home lock until close', async () => { + const firstChild = createMockDiscoveryChild() + const secondChild = createMockDiscoveryChild() + spawnMock.mockReturnValueOnce(firstChild as never).mockReturnValueOnce(secondChild as never) + const env = { CODEX_HOME: '/managed/codex-generation-home' } + const context = { branch: 'main', stagedSummary: 'M\tREADME.md', stagedPatch: '+hello' } + const params = { agentId: 'codex' as const, model: 'gpt-5.5' } + + const first = generateCommitMessageFromContext(context, params, { + kind: 'local', + cwd: '/repo', + env + }) + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(1)) + cancelGenerateCommitMessageLocal('/repo') + + await expect(first).resolves.toEqual({ + success: false, + error: 'Generation canceled.', + canceled: true + }) + expectChildTerminated(firstChild) + + const second = generateCommitMessageFromContext(context, params, { + kind: 'local', + cwd: '/repo-2', + env + }) + await Promise.resolve() + expect(spawnMock).toHaveBeenCalledTimes(1) + + firstChild.emit('close', null) + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(2)) + secondChild.stdout.emit('data', Buffer.from('Update README\n')) + secondChild.emit('close', 0) + await expect(second).resolves.toMatchObject({ success: true, message: 'Update README' }) + }) + + it('holds the Codex home lock until Windows tree termination and wrapper close', async () => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + let finishTreeKill!: () => void + terminateWindowsProcessTreeMock.mockReturnValueOnce( + new Promise((resolve) => { + finishTreeKill = resolve + }) + ) + const firstChild = createMockDiscoveryChild() + const secondChild = createMockDiscoveryChild() + spawnMock.mockReturnValueOnce(firstChild as never).mockReturnValueOnce(secondChild as never) + const env = { CODEX_HOME: 'C:\\managed\\codex-generation-home' } + const context = { branch: 'main', stagedSummary: 'M\tREADME.md', stagedPatch: '+hello' } + const params = { agentId: 'codex' as const, model: 'gpt-5.5' } + + try { + const first = generateCommitMessageFromContext(context, params, { + kind: 'local', + cwd: 'C:\\repo', + env + }) + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(1)) + cancelGenerateCommitMessageLocal('C:\\repo') + await expect(first).resolves.toMatchObject({ canceled: true }) + + const second = generateCommitMessageFromContext(context, params, { + kind: 'local', + cwd: 'C:\\repo-2', + env + }) + firstChild.emit('close', null) + await Promise.resolve() + expect(spawnMock).toHaveBeenCalledTimes(1) + + finishTreeKill() + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(2)) + secondChild.stdout.emit('data', Buffer.from('Update README\n')) + secondChild.emit('close', 0) + await expect(second).resolves.toMatchObject({ success: true, message: 'Update README' }) + } finally { + Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform }) + } + }) + + it('cancels Codex generation promptly while it is queued behind the home lock', async () => { + const discoveryChild = createMockDiscoveryChild() + const laterChild = createMockDiscoveryChild() + spawnMock.mockReturnValueOnce(discoveryChild as never).mockReturnValueOnce(laterChild as never) + const env = { CODEX_HOME: '/managed/codex-queued-home' } + const blocker = discoverCommitMessageModelsLocal('codex', env) + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(1)) + + const queued = generateCommitMessageFromContext( + { branch: 'main', stagedSummary: 'M\tREADME.md', stagedPatch: '+hello' }, + { agentId: 'codex', model: 'gpt-5.5' }, + { kind: 'local', cwd: '/queued-repo', env } + ) + cancelGenerateCommitMessageLocal('/queued-repo') + + await expect(queued).resolves.toEqual({ + success: false, + error: 'Generation canceled.', + canceled: true + }) + expect(spawnMock).toHaveBeenCalledTimes(1) + + discoveryChild.stdout.emit( + 'data', + Buffer.from(JSON.stringify({ models: [{ slug: 'gpt-5.5', display_name: 'GPT-5.5' }] })) + ) + discoveryChild.emit('close', 0) + await expect(blocker).resolves.toMatchObject({ success: true }) + + const later = generateCommitMessageFromContext( + { branch: 'main', stagedSummary: 'M\tREADME.md', stagedPatch: '+later' }, + { agentId: 'codex', model: 'gpt-5.5' }, + { kind: 'local', cwd: '/later-repo', env } + ) + await vi.waitFor(() => expect(spawnMock).toHaveBeenCalledTimes(2)) + laterChild.stdout.emit('data', Buffer.from('Update later\n')) + laterChild.emit('close', 0) + await expect(later).resolves.toMatchObject({ success: true, message: 'Update later' }) + }) + it('routes Windows batch-script agent commands through cmd.exe', async () => { const originalComSpec = process.env.ComSpec process.env.ComSpec = 'C:\\Windows\\System32\\cmd.exe' diff --git a/src/main/text-generation/commit-message-text-generation.ts b/src/main/text-generation/commit-message-text-generation.ts index fde91c1f746..8410231dc40 100644 --- a/src/main/text-generation/commit-message-text-generation.ts +++ b/src/main/text-generation/commit-message-text-generation.ts @@ -1,7 +1,7 @@ /* eslint-disable max-lines -- Why: local and SSH generation share cancellation, spawn failure handling, and output normalization; keeping them together prevents those paths from drifting. */ -import { exec, spawn, type ChildProcess } from 'node:child_process' +import { spawn, type ChildProcess } from 'node:child_process' import type { GlobalSettings, Repo, TuiAgent } from '../../shared/types' import { buildCommitMessagePrompt, @@ -47,6 +47,10 @@ import type { SourceControlAiOperation } from '../../shared/source-control-ai-ty import { formatLinkedIssueTemplateValue } from '../../shared/source-control-ai-action-variables' import { renderSourceControlActionCommandTemplate } from '../../shared/source-control-ai-actions' import { resolveCliCommand } from '../codex-cli/command' +import { + resolveCodexHomeProcessLockKeyForSpawnEnv, + withCodexHomeProcessLock +} from '../codex-cli/codex-home-process-lock' import { getSpawnArgsForWindows, UnsafeWindowsBatchArgumentsError, @@ -54,6 +58,7 @@ import { } from '../win32-utils' import { withMacTailscaleDnsHint } from '../network/macos-tailscale-dns-diagnostic' import { wslAwareSpawn } from '../git/runner' +import { terminateWindowsProcessTree } from '../windows-process-tree-kill' const GENERATION_TIMEOUT_MS = 60_000 const MAX_AGENT_OUTPUT_BYTES = 4 * 1024 * 1024 @@ -122,6 +127,11 @@ type InternalTextGenerationResult = failureOutput?: AgentGenerationFailureOutput } +type LocalProcessExecution = { + result: Promise + processClosed: Promise +} + export type CommitMessageModelDiscoveryLocalOptions = { cwd?: string wslDistro?: string @@ -312,121 +322,159 @@ export async function discoverCommitMessageModelsLocal( return toModelDiscoveryCapability(spec) } - return new Promise((resolve) => { - let child: ChildProcess - const spawnEnv = env ?? process.env - try { - const planned = planModelDiscovery(spec, agentCommandOverride) - if (!planned.ok) { - resolve({ success: false, error: planned.error }) - return - } - if (process.platform === 'win32' && options.wslDistro) { - child = wslAwareSpawn(planned.plan.binary, planned.plan.args, { - cwd: options.cwd, - env: buildWslLauncherEnv(env), - stdio: ['ignore', 'pipe', 'pipe'], - windowsHide: true, - wslDistro: options.wslDistro, - useWslLoginShell: true + const startDiscovery = (): LocalProcessExecution => { + let markProcessClosed!: () => void + const processClosed = new Promise((resolve) => { + markProcessClosed = resolve + }) + const result = new Promise((resolve) => { + let child: ChildProcess + const spawnEnv = env ?? process.env + try { + const planned = planModelDiscovery(spec, agentCommandOverride) + if (!planned.ok) { + markProcessClosed() + resolve({ success: false, error: planned.error }) + return + } + if (process.platform === 'win32' && options.wslDistro) { + child = wslAwareSpawn(planned.plan.binary, planned.plan.args, { + cwd: options.cwd, + env: buildWslLauncherEnv(env), + stdio: ['ignore', 'pipe', 'pipe'], + windowsHide: true, + wslDistro: options.wslDistro, + useWslLoginShell: true + }) + } else { + const resolvedBinary = + process.platform === 'win32' + ? resolveCliCommand(planned.plan.binary, { + pathEnv: spawnEnv.PATH ?? spawnEnv.Path ?? null + }) + : planned.plan.binary + const { spawnCmd, spawnArgs } = getSpawnArgsForWindows(resolvedBinary, planned.plan.args) + child = spawn(spawnCmd, spawnArgs, { + env: spawnEnv, + stdio: ['ignore', 'pipe', 'pipe'], + windowsHide: true + }) + } + } catch (error) { + markProcessClosed() + console.error('[commit-message] Failed to spawn model discovery:', error) + resolve({ + success: false, + error: `${spec.label} model discovery could not be started. Check the agent CLI configuration and try again.` }) - } else { - const resolvedBinary = - process.platform === 'win32' - ? resolveCliCommand(planned.plan.binary, { - pathEnv: spawnEnv.PATH ?? spawnEnv.Path ?? null - }) - : planned.plan.binary - const { spawnCmd, spawnArgs } = getSpawnArgsForWindows(resolvedBinary, planned.plan.args) - child = spawn(spawnCmd, spawnArgs, { - env: spawnEnv, - stdio: ['ignore', 'pipe', 'pipe'], - windowsHide: true - }) - } - } catch (error) { - console.error('[commit-message] Failed to spawn model discovery:', error) - resolve({ - success: false, - error: `${spec.label} model discovery could not be started. Check the agent CLI configuration and try again.` - }) - return - } - - let stdout = '' - let stderr = '' - let outputLimitExceeded = false - let settled = false - let timer: ReturnType | null = null - let detachChildListeners = (): void => {} - const finish = (result: DiscoverCommitMessageModelsResult): void => { - if (settled) { return } - settled = true - if (timer) { - clearTimeout(timer) - timer = null - } - detachChildListeners() - resolve(result) - } - timer = setTimeout(() => { - killProcessTree(child) - finish({ - success: false, - error: `${spec.label} model discovery timed out after ${GENERATION_TIMEOUT_MS / 1000}s.` - }) - }, GENERATION_TIMEOUT_MS) - const onData = (chunk: Buffer, append: (text: string) => void): void => { - if (stdout.length + stderr.length + chunk.byteLength > MAX_AGENT_OUTPUT_BYTES) { - outputLimitExceeded = true - killProcessTree(child) - finish({ success: false, error: `${spec.label} returned too much model data.` }) - return + let stdout = '' + let stderr = '' + let outputLimitExceeded = false + let settled = false + let timer: ReturnType | null = null + let terminationComplete: Promise | null = null + let detachChildListeners = (): void => {} + const startTermination = (): void => { + terminationComplete ??= killProcessTree(child) } - append(chunk.toString('utf-8')) - } - - const onStdoutData = (chunk: Buffer): void => onData(chunk, (text) => (stdout += text)) - const onStderrData = (chunk: Buffer): void => onData(chunk, (text) => (stderr += text)) - const onError = (error: Error): void => { - if ((error as NodeJS.ErrnoException).code === 'ENOENT') { + const markClosedAfterTermination = (): void => { + void (terminationComplete ?? Promise.resolve()).then(markProcessClosed) + } + const finish = (result: DiscoverCommitMessageModelsResult): void => { + if (settled) { + return + } + settled = true + if (timer) { + clearTimeout(timer) + timer = null + } + detachChildListeners() + if (agentId !== 'codex') { + markProcessClosed() + } + resolve(result) + } + timer = setTimeout(() => { + startTermination() finish({ success: false, - error: `${spec.modelDiscovery?.binary ?? spec.binary} not found on PATH. Install ${spec.label} to discover models.` + error: `${spec.label} model discovery timed out after ${GENERATION_TIMEOUT_MS / 1000}s.` }) - return - } - finish({ - success: false, - error: `${spec.label} model discovery failed to start. Check the agent CLI configuration and try again.` - }) - } - const onClose = (code: number | null): void => { - if (outputLimitExceeded) { - finish({ success: false, error: `${spec.label} returned too much model data.` }) - return - } - if (code !== 0) { - finish(finalizeModelDiscoveryOutput(spec, stdout, stderr, code)) - return - } - finish(finalizeModelDiscoveryOutput(spec, stdout, stderr, code)) - } + }, GENERATION_TIMEOUT_MS) - child.stdout?.on('data', onStdoutData) - child.stderr?.on('data', onStderrData) - child.on('error', onError) - child.on('close', onClose) - detachChildListeners = () => { - child.stdout?.off?.('data', onStdoutData) - child.stderr?.off?.('data', onStderrData) - child.off?.('error', onError) - child.off?.('close', onClose) - } - }) + const onData = (chunk: Buffer, append: (text: string) => void): void => { + if (stdout.length + stderr.length + chunk.byteLength > MAX_AGENT_OUTPUT_BYTES) { + outputLimitExceeded = true + startTermination() + finish({ success: false, error: `${spec.label} returned too much model data.` }) + return + } + append(chunk.toString('utf-8')) + } + + const onStdoutData = (chunk: Buffer): void => onData(chunk, (text) => (stdout += text)) + const onStderrData = (chunk: Buffer): void => onData(chunk, (text) => (stderr += text)) + const onError = (error: Error): void => { + if (!child.pid) { + markProcessClosed() + } + if ((error as NodeJS.ErrnoException).code === 'ENOENT') { + finish({ + success: false, + error: `${spec.modelDiscovery?.binary ?? spec.binary} not found on PATH. Install ${spec.label} to discover models.` + }) + return + } + finish({ + success: false, + error: `${spec.label} model discovery failed to start. Check the agent CLI configuration and try again.` + }) + } + const onClose = (code: number | null): void => { + markClosedAfterTermination() + if (outputLimitExceeded) { + finish({ success: false, error: `${spec.label} returned too much model data.` }) + return + } + if (code !== 0) { + finish(finalizeModelDiscoveryOutput(spec, stdout, stderr, code)) + return + } + finish(finalizeModelDiscoveryOutput(spec, stdout, stderr, code)) + } + + child.stdout?.on('data', onStdoutData) + child.stderr?.on('data', onStderrData) + if (agentId === 'codex') { + // Result publication stays prompt while the home lock follows the + // process lifetime after asynchronous timeout/output-limit kills. + child.once('close', markClosedAfterTermination) + } + child.on('error', onError) + child.on('close', onClose) + detachChildListeners = () => { + child.stdout?.off?.('data', onStdoutData) + child.stderr?.off?.('data', onStderrData) + child.off?.('error', onError) + child.off?.('close', onClose) + } + }) + return { result, processClosed } + } + + if (agentId === 'codex') { + // Why: discovery spawns a real codex process in the selected home; keep it + // off an auth.json a quota probe may be refreshing at the same time. + return runCodexProcessWithHomeLock( + resolveCodexHomeProcessLockKeyForSpawnEnv(env, options.wslDistro), + startDiscovery + ) + } + return startDiscovery().result } export async function discoverCommitMessageModelsRemote( @@ -493,16 +541,13 @@ export async function discoverCommitMessageModelsRemote( // `child.kill()` would only terminate the wrapper. `taskkill /T /F` walks the // process tree from the wrapper PID and force-kills every descendant, which is // what users expect when they hit "stop generating". -function killProcessTree(child: ChildProcess): void { +function killProcessTree(child: ChildProcess): Promise { const pid = child.pid if (!pid) { - return + return Promise.resolve() } if (process.platform === 'win32') { - exec(`taskkill /pid ${pid} /T /F`, () => { - // Best-effort; the spawn's `close` listener fires once the tree exits. - }) - return + return terminateWindowsProcessTree(pid) } try { child.kill('SIGKILL') @@ -510,6 +555,7 @@ function killProcessTree(child: ChildProcess): void { // The child may have already exited between the in-flight check and the // kill - that race is benign and can be ignored. } + return Promise.resolve() } // Keying by operation plus `local:${cwd}` keeps local cancellation independent @@ -551,16 +597,21 @@ function buildWslLauncherEnv(explicitEnv: NodeJS.ProcessEnv | undefined): NodeJS return env } -async function runLocalPlan( +function runLocalPlan( plan: CommitMessagePlan, cwd: string, env: NodeJS.ProcessEnv | undefined, emptyResultName = 'message', operation: TextGenerationOperation = 'commit-message', - wslDistro?: string -): Promise { + wslDistro?: string, + holdHomeLockUntilClose = false +): LocalProcessExecution { const { binary, args, stdinPayload, label } = plan - return new Promise((resolve) => { + let markProcessClosed!: () => void + const processClosed = new Promise((resolve) => { + markProcessClosed = resolve + }) + const result = new Promise((resolve) => { let child: ChildProcess try { const spawnEnv = env ?? process.env @@ -587,6 +638,7 @@ async function runLocalPlan( }) } } catch (error) { + markProcessClosed() if (error instanceof UnsafeWindowsBatchArgumentsError) { resolve({ success: false, @@ -612,7 +664,14 @@ async function runLocalPlan( const laneKey = localLaneKey(operation, cwd) let cancelToken: (() => void) | null = null let timer: ReturnType | null = null + let terminationComplete: Promise | null = null let detachChildListeners = (): void => {} + const startTermination = (): void => { + terminationComplete ??= killProcessTree(child) + } + const markClosedAfterTermination = (): void => { + void (terminationComplete ?? Promise.resolve()).then(markProcessClosed) + } const finalize = (result: InternalTextGenerationResult): void => { if (settled) { return @@ -626,12 +685,15 @@ async function runLocalPlan( if (cancelToken && cancelTokensByLane.get(laneKey) === cancelToken) { cancelTokensByLane.delete(laneKey) } + if (!holdHomeLockUntilClose) { + markProcessClosed() + } resolve(result) } cancelToken = () => { canceledByUser = true - killProcessTree(child) + startTermination() // Why: cancellation is a user-visible UI command; do not wait for a // wedged agent CLI to emit `close` before the request leaves loading. finalize({ success: false, error: 'Generation canceled.', canceled: true }) @@ -639,7 +701,7 @@ async function runLocalPlan( cancelTokensByLane.set(laneKey, cancelToken) timer = setTimeout(() => { - killProcessTree(child) + startTermination() finalize({ success: false, error: `Generation timed out after ${GENERATION_TIMEOUT_MS / 1000}s.` @@ -650,7 +712,7 @@ async function runLocalPlan( stdoutBytes += chunk.byteLength if (stdoutBytes > MAX_AGENT_OUTPUT_BYTES) { outputLimitExceeded = true - killProcessTree(child) + startTermination() return } stdout += chunk.toString('utf-8') @@ -659,12 +721,15 @@ async function runLocalPlan( stderrBytes += chunk.byteLength if (stderrBytes > MAX_AGENT_OUTPUT_BYTES) { outputLimitExceeded = true - killProcessTree(child) + startTermination() return } stderr += chunk.toString('utf-8') } const onError = (error: Error): void => { + if (!child.pid) { + markProcessClosed() + } const code = (error as NodeJS.ErrnoException).code if (code === 'ENOENT') { finalize({ @@ -680,6 +745,7 @@ async function runLocalPlan( }) } const onClose = (code: number | null): void => { + markClosedAfterTermination() if (canceledByUser) { finalize({ success: false, error: 'Generation canceled.', canceled: true }) return @@ -703,6 +769,9 @@ async function runLocalPlan( } child.stdout?.on('data', onStdoutData) child.stderr?.on('data', onStderrData) + if (holdHomeLockUntilClose) { + child.once('close', markClosedAfterTermination) + } child.on('error', onError) child.on('close', onClose) detachChildListeners = () => { @@ -712,7 +781,119 @@ async function runLocalPlan( child.off?.('close', onClose) } - child.stdin?.end(stdinPayload ?? undefined) + try { + child.stdin?.end(stdinPayload ?? undefined) + } catch (error) { + startTermination() + onError(error instanceof Error ? error : new Error(String(error))) + } + }) + return { result, processClosed } +} + +type LocalGenerationTarget = Extract + +function runLocalPlanForAgent( + agentId: string, + plan: CommitMessagePlan, + target: LocalGenerationTarget, + emptyResultName: string, + operation: TextGenerationOperation +): Promise { + const start = ( + holdHomeLockUntilClose = false + ): LocalProcessExecution => + runLocalPlan( + plan, + target.cwd, + target.env, + emptyResultName, + operation, + target.wslDistro, + holdHomeLockUntilClose + ) + if (agentId !== 'codex') { + // Why: no extra promise hops here — cancellation timing for non-codex + // agents must stay byte-identical to a direct runLocalPlan call. + return start().result + } + return runCodexLocalPlanUnderHomeLock(() => start(true), target, operation) +} + +// Why: codex rewrites rotating OAuth tokens in its home's auth.json; the +// per-home lock keeps this run from racing Orca's own quota probes there. +function runCodexLocalPlanUnderHomeLock( + start: () => LocalProcessExecution, + target: LocalGenerationTarget, + operation: TextGenerationOperation +): Promise { + const laneKey = localLaneKey(operation, target.cwd) + let canceledWhileQueued = false + let publishResult!: (result: InternalTextGenerationResult) => void + let rejectResult!: (error: unknown) => void + let resultPublished = false + const result = new Promise((resolve, reject) => { + publishResult = (value) => { + if (!resultPublished) { + resultPublished = true + resolve(value) + } + } + rejectResult = reject + }) + const queuedCancelToken = (): void => { + canceledWhileQueued = true + publishResult({ success: false, error: 'Generation canceled.', canceled: true }) + } + // Why: Stop must work while this run waits behind a probe holding the lock. + cancelTokensByLane.set(laneKey, queuedCancelToken) + void withCodexHomeProcessLock( + resolveCodexHomeProcessLockKeyForSpawnEnv(target.env, target.wslDistro), + async () => { + if (canceledWhileQueued) { + publishResult({ success: false, error: 'Generation canceled.', canceled: true }) + return + } + const execution = start() + try { + publishResult(await execution.result) + } catch (error) { + if (!resultPublished) { + rejectResult(error) + } + } finally { + await execution.processClosed + } + } + ) + .catch((error: unknown) => { + if (!resultPublished) { + rejectResult(error) + } + }) + .finally(() => { + if (cancelTokensByLane.get(laneKey) === queuedCancelToken) { + cancelTokensByLane.delete(laneKey) + } + }) + return result +} + +function runCodexProcessWithHomeLock( + lockKey: string, + start: () => LocalProcessExecution +): Promise { + return new Promise((resolve, reject) => { + void withCodexHomeProcessLock(lockKey, async () => { + const execution = start() + try { + resolve(await execution.result) + } catch (error) { + reject(error) + } finally { + await execution.processClosed + } + }).catch(reject) }) } @@ -890,13 +1071,12 @@ export async function generateCommitMessageFromContext( const internalResult = target.kind === 'remote' ? await runRemotePlan(planned.plan, target) - : await runLocalPlan( + : await runLocalPlanForAgent( + params.agentId, planned.plan, - target.cwd, - target.env, + target, 'message', - 'commit-message', - target.wslDistro + 'commit-message' ) return formatCommitMessageGenerationResult(internalResult) } @@ -967,13 +1147,12 @@ export async function generatePullRequestFieldsFromContext( const internalResult = target.kind === 'remote' ? await runRemotePlan(planned.plan, target, 'details', 'pull-request-fields') - : await runLocalPlan( + : await runLocalPlanForAgent( + params.agentId, planned.plan, - target.cwd, - target.env, + target, 'details', - 'pull-request-fields', - target.wslDistro + 'pull-request-fields' ) return formatPullRequestFieldsGenerationResult(internalResult, context) } @@ -1014,13 +1193,12 @@ export async function generateBranchNameFromContext( const internalResult = target.kind === 'remote' ? await runRemotePlan(planned.plan, target, 'branch name', 'branch-name') - : await runLocalPlan( + : await runLocalPlanForAgent( + params.agentId, planned.plan, - target.cwd, - target.env, + target, 'branch name', - 'branch-name', - target.wslDistro + 'branch-name' ) if (!internalResult.success) { return internalResult diff --git a/src/main/updater-events.test.ts b/src/main/updater-events.test.ts new file mode 100644 index 00000000000..7a24483ca70 --- /dev/null +++ b/src/main/updater-events.test.ts @@ -0,0 +1,196 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import type { registerAutoUpdaterHandlers } from './updater-events' + +const { appMock, nativeUpdaterMock, getLinuxRootPackageTypeMock } = vi.hoisted(() => ({ + appMock: { + isPackaged: true, + getVersion: vi.fn(() => '1.0.51'), + on: vi.fn() + }, + nativeUpdaterMock: { on: vi.fn() }, + getLinuxRootPackageTypeMock: vi.fn<() => 'deb' | 'rpm' | null>(() => 'deb') +})) + +vi.mock('electron', () => ({ + app: appMock, + autoUpdater: nativeUpdaterMock, + shell: { showItemInFolder: vi.fn() } +})) + +// Why: only the packaged-marker resolver is faked so the real artifact tracking runs. +vi.mock('./linux-update-package-type', () => ({ + getLinuxRootPackageType: getLinuxRootPackageTypeMock +})) + +vi.mock('./updater-changelog', () => ({ fetchChangelog: vi.fn().mockResolvedValue(null) })) +vi.mock('./updater-lifecycle-diagnostics', () => ({ recordUpdaterLifecycle: vi.fn() })) + +const DEB_PATH = '/home/tester/.cache/orca-updater/pending/orca-ide_1.0.61_amd64.deb' +// A real 64-byte SHA-512; capture rejects a digest that cannot decode to one. +const DEB_SHA512 = + 'LHlL7dKoqg98gS2nfQv878dK+UoktbAkm4M20/hoJ2Qr0Kqsa3MSL4VmWy/Lll/MYjQFkpvOxduQ/vswentozA==' + +type HandlerContext = Parameters[0] + +function createUpdaterStub(): { + on: (event: string, handler: (...args: unknown[]) => void) => unknown + emit: (event: string, ...args: unknown[]) => void +} { + const handlers = new Map void)[]>() + const stub = { + on: (event: string, handler: (...args: unknown[]) => void) => { + handlers.set(event, [...(handlers.get(event) ?? []), handler]) + return stub + }, + emit: (event: string, ...args: unknown[]) => { + for (const handler of handlers.get(event) ?? []) { + handler(...args) + } + } + } + return stub +} + +function createContext(overrides?: Partial): HandlerContext { + return { + autoUpdater: createUpdaterStub() as never, + clearBackgroundCheckLaunchPending: vi.fn(), + clearAvailableUpdateContext: vi.fn(), + consumeMissingManifestPrereleaseFallbackResult: vi.fn(() => null), + getPublishingWindowLastGoodCheck: vi.fn(() => null), + getMissingManifestPrereleaseFallbackUserInitiated: vi.fn(() => null), + getCurrentStatus: vi.fn(() => ({ state: 'checking' }) as never), + getActiveUpdateCheckEventAttemptId: vi.fn(() => 1), + getKnownReleaseUrl: vi.fn(() => undefined), + getPendingInstallVersion: vi.fn(() => '1.0.61'), + getUserInitiatedCheck: vi.fn(() => false), + handleQuitAndInstallFailure: vi.fn(() => false), + isQuitAndInstallHandoffActive: vi.fn(() => false), + hasInstallableDownloadedVersion: vi.fn(() => true), + isLocalBuildCheck: vi.fn(() => false), + isPinnedBuildCheck: vi.fn(() => false), + shouldHandleUpdaterErrorEvent: vi.fn(() => true), + clearUpdateAvailableEventPending: vi.fn(), + isActiveUpdateCheckAttempt: vi.fn(() => true), + markUpdateCheckEventAttempt: vi.fn(() => true), + markUpdateAvailableEventPending: vi.fn(), + markMissingManifestPrereleaseFallbackChecking: vi.fn(), + performQuitAndInstall: vi.fn(), + shouldDeferMacQuitForInstall: vi.fn(() => true), + recordCompletedUpdateCheck: vi.fn(), + restoreReleaseUpdateSource: vi.fn(), + sendCheckFailureStatus: vi.fn().mockResolvedValue(undefined), + sendErrorStatus: vi.fn(), + sendStatus: vi.fn(), + scheduleAutomaticUpdateCheck: vi.fn(), + shouldSuppressMissingManifestPrereleaseFallbackEvent: vi.fn(() => false), + suppressMissingManifestPrereleaseFallbackPromiseFailure: vi.fn(), + setAvailableReleaseUrl: vi.fn(), + setAvailableVersion: vi.fn(), + setUserInitiatedCheck: vi.fn(), + ...overrides + } +} + +function downloadedEvent(overrides?: Record): Record { + return { + version: '1.0.61', + downloadedFile: DEB_PATH, + files: [{ url: 'orca-ide_1.0.61_amd64.deb', sha512: DEB_SHA512 }], + ...overrides + } +} + +describe('registerAutoUpdaterHandlers linux package artifact tracking', () => { + beforeEach(() => { + vi.resetModules() + appMock.on.mockReset() + nativeUpdaterMock.on.mockReset() + appMock.getVersion.mockReset().mockReturnValue('1.0.51') + getLinuxRootPackageTypeMock.mockReset().mockReturnValue('deb') + }) + + const register = async ( + overrides?: Partial + ): Promise<{ + context: HandlerContext + emit: (event: string, ...args: unknown[]) => void + getArtifact: () => unknown + }> => { + const context = createContext(overrides) + const { registerAutoUpdaterHandlers } = await import('./updater-events') + registerAutoUpdaterHandlers(context) + const { getTrackedLinuxPackageArtifact } = await import('./linux-package-update-recovery') + return { + context, + emit: (context.autoUpdater as unknown as ReturnType).emit, + getArtifact: getTrackedLinuxPackageArtifact + } + } + + it('hands the whole downloaded event to artifact capture', async () => { + const { emit, getArtifact } = await register() + + emit('update-downloaded', downloadedEvent()) + + // Why: path and digest exist only in the event's own fields, so a trimmed event fails here. + expect(getArtifact()).toEqual({ + packageType: 'deb', + version: '1.0.61', + path: DEB_PATH, + sha512: DEB_SHA512 + }) + }) + + it('passes the actual updater error into the install-failure handler', async () => { + const handleQuitAndInstallFailure = vi.fn<(error?: unknown) => boolean>(() => true) + const { emit, context } = await register({ handleQuitAndInstallFailure }) + const failure = new Error('Command failed, exited with code 127') + + emit('error', failure) + + expect(handleQuitAndInstallFailure).toHaveBeenCalledTimes(1) + expect(handleQuitAndInstallFailure.mock.calls[0]?.[0]).toBe(failure) + // Recovery owns the event; no generic check/download error follows it. + expect(context.sendErrorStatus).not.toHaveBeenCalled() + }) + + it('drops the artifact once the update resolves as not available', async () => { + const { emit, getArtifact } = await register() + emit('update-downloaded', downloadedEvent()) + + emit('update-not-available') + + expect(getArtifact()).toBeNull() + }) + + it('drops the artifact when another version takes over the cycle', async () => { + const { emit, getArtifact } = await register() + emit('update-downloaded', downloadedEvent()) + + emit('update-available', { version: '1.0.62' }) + + expect(getArtifact()).toBeNull() + }) + + it('drops the artifact when progress reports a different pending version', async () => { + const { emit, getArtifact } = await register({ + getPendingInstallVersion: vi.fn(() => '1.0.62') + }) + emit('update-downloaded', downloadedEvent()) + + emit('download-progress', { percent: 12 }) + + expect(getArtifact()).toBeNull() + }) + + it('keeps the artifact through a same-version recheck', async () => { + const { emit, getArtifact } = await register() + emit('update-downloaded', downloadedEvent()) + + emit('update-available', { version: '1.0.61' }) + emit('download-progress', { percent: 100 }) + + expect(getArtifact()).toEqual(expect.objectContaining({ version: '1.0.61', path: DEB_PATH })) + }) +}) diff --git a/src/main/updater-events.ts b/src/main/updater-events.ts index 1e3f7de3395..eb1ca193510 100644 --- a/src/main/updater-events.ts +++ b/src/main/updater-events.ts @@ -12,6 +12,11 @@ import { compareVersions } from './updater-fallback' import { fetchChangelog } from './updater-changelog' import type { ElectronAutoUpdater } from './electron-updater-loader' import { recordUpdaterLifecycle } from './updater-lifecycle-diagnostics' +import { + captureLinuxPackageArtifact, + clearTrackedLinuxPackageArtifact, + clearTrackedLinuxPackageArtifactForOtherVersion +} from './linux-package-update-recovery' const AUTO_UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000 const AUTO_UPDATE_RETRY_INTERVAL_MS = 60 * 60 * 1000 @@ -28,7 +33,7 @@ type UpdaterHandlerContext = { getKnownReleaseUrl: () => string | undefined getPendingInstallVersion: () => string getUserInitiatedCheck: () => boolean - handleQuitAndInstallFailure: () => boolean + handleQuitAndInstallFailure: (error?: unknown) => boolean isQuitAndInstallHandoffActive: () => boolean hasInstallableDownloadedVersion: () => boolean isLocalBuildCheck: () => boolean @@ -184,6 +189,10 @@ export function registerAutoUpdaterHandlers({ return } + // Why: only a genuinely newer offer supersedes the retained package; a publishing-window blip that + // momentarily resolves an older tag must not destroy a still-valid recovery path. + clearTrackedLinuxPackageArtifactForOtherVersion(info.version) + // Why: fetch the changelog in main to avoid renderer-side CORS on onorca.dev. markUpdateAvailableEventPending(attemptId) void (async () => { @@ -232,6 +241,7 @@ export function registerAutoUpdaterHandlers({ } clearBackgroundCheckLaunchPending() resetMacInstallState() + clearTrackedLinuxPackageArtifact() const missingManifestFallback = consumeMissingManifestPrereleaseFallbackResult() const publishingWindowLastGoodCheck = getPublishingWindowLastGoodCheck() const wasUserInitiated = missingManifestFallback?.userInitiated ?? getUserInitiatedCheck() @@ -260,10 +270,12 @@ export function registerAutoUpdaterHandlers({ autoUpdater.on('download-progress', (progress) => { clearBackgroundCheckLaunchPending() + const version = getPendingInstallVersion() + clearTrackedLinuxPackageArtifactForOtherVersion(version) sendStatus({ state: 'downloading', percent: Math.round(progress.percent), - version: getPendingInstallVersion() + version }) }) @@ -276,9 +288,12 @@ export function registerAutoUpdaterHandlers({ compareVersions(info.version, app.getVersion()) <= 0 ) { clearAvailableUpdateContext() + clearTrackedLinuxPackageArtifact() sendStatus({ state: 'not-available' }) return } + // Why: retain the verified artifact now — the 'error' event after a failed install no longer carries it. + captureLinuxPackageArtifact(info) const macInstallerReady = process.platform === 'darwin' ? isMacInstallerReady() : true recordUpdaterLifecycle('update_downloaded', { version: info.version, macInstallerReady }) // On macOS, defer 'downloaded' until Squirrel.Mac finishes processing; other platforms are ready immediately. @@ -294,7 +309,7 @@ export function registerAutoUpdaterHandlers({ autoUpdater.on('error', (err) => { const message = err?.message ?? 'Unknown error' // Why: quitAndInstall reports "no staged update" via this error event (async on macOS); recover quit flags before suppression guards run. - if (handleQuitAndInstallFailure()) { + if (handleQuitAndInstallFailure(err)) { return } // Why: handoff still owns the process; don't treat as a check/download error. diff --git a/src/main/updater-fallback.ts b/src/main/updater-fallback.ts index d91cdf75ef2..a1c77b315d6 100644 --- a/src/main/updater-fallback.ts +++ b/src/main/updater-fallback.ts @@ -50,7 +50,12 @@ export function statusesEqual(left: UpdateStatus, right: UpdateStatus): boolean right.state === 'error' && left.message === right.message && left.userInitiated === right.userInitiated && - left.activeNudgeId === right.activeNudgeId + left.activeNudgeId === right.activeNudgeId && + // Why: clearing recovery must reach the renderer even when the message is unchanged, or dead actions stay enabled. + left.recovery?.kind === right.recovery?.kind && + left.recovery?.packageType === right.recovery?.packageType && + left.recovery?.reason === right.recovery?.reason && + left.recovery?.version === right.recovery?.version ) } } diff --git a/src/main/updater-linux-package-recovery-actions.test.ts b/src/main/updater-linux-package-recovery-actions.test.ts new file mode 100644 index 00000000000..91b2423c817 --- /dev/null +++ b/src/main/updater-linux-package-recovery-actions.test.ts @@ -0,0 +1,287 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { UpdateStatus } from '../shared/types' +import type * as UpdaterModule from './updater' + +const { + appMock, + autoUpdaterMock, + clearTrackedLinuxPackageArtifactMock, + getTrackedLinuxPackageArtifactMock, + recordUpdaterLifecycleMock, + resolveLinuxPackageInstallInstructionsMock, + revealLinuxPackageMock, + resetHandlers +} = vi.hoisted(() => { + const updaterHandlers = new Map void)[]>() + const autoUpdaterMock = { + autoDownload: false, + autoInstallOnAppQuit: false, + autoRunAppAfterInstall: true, + allowPrerelease: false, + allowDowngrade: false, + disableDifferentialDownload: false, + logger: undefined as { error: (message: unknown) => void } | undefined, + checkForUpdates: vi.fn().mockResolvedValue(null), + downloadUpdate: vi.fn(), + quitAndInstall: vi.fn(), + setFeedURL: vi.fn(), + on: vi.fn((event: string, handler: (...args: unknown[]) => void) => { + updaterHandlers.set(event, [...(updaterHandlers.get(event) ?? []), handler]) + return autoUpdaterMock + }), + emit: (event: string, ...args: unknown[]) => { + for (const handler of updaterHandlers.get(event) ?? []) { + handler(...args) + } + } + } + return { + appMock: { isPackaged: true, getVersion: vi.fn(() => '1.0.51'), on: vi.fn(), quit: vi.fn() }, + autoUpdaterMock, + clearTrackedLinuxPackageArtifactMock: vi.fn(), + getTrackedLinuxPackageArtifactMock: vi.fn(), + recordUpdaterLifecycleMock: vi.fn(), + resolveLinuxPackageInstallInstructionsMock: vi.fn(), + revealLinuxPackageMock: vi.fn(), + resetHandlers: () => updaterHandlers.clear() + } +}) + +vi.mock('electron', () => ({ + app: appMock, + BrowserWindow: { getAllWindows: vi.fn(() => []) }, + autoUpdater: { on: vi.fn() }, + powerMonitor: { on: vi.fn() }, + net: { fetch: vi.fn() } +})) + +vi.mock('electron-updater', () => ({ autoUpdater: autoUpdaterMock })) +vi.mock('./electron-updater-loader', () => ({ loadElectronAutoUpdater: () => autoUpdaterMock })) +vi.mock('@electron-toolkit/utils', () => ({ is: { dev: false } })) +vi.mock('./ipc/pty', () => ({ killAllPty: vi.fn() })) +vi.mock('./updater-changelog', () => ({ fetchChangelog: vi.fn().mockResolvedValue(null) })) +vi.mock('./updater-nudge', () => ({ + fetchNudge: vi.fn().mockResolvedValue(null), + shouldApplyNudge: vi.fn().mockReturnValue(false) +})) +vi.mock('./updater-prerelease-feed', () => ({ + fetchNewerReleaseTagsWithReadiness: vi.fn().mockResolvedValue({ tags: [], state: 'no-newer' }), + getReleaseDownloadUrl: vi.fn(() => 'https://example.invalid/download') +})) +vi.mock('./update-install-exit-watchdog', () => ({ + armUpdateInstallExitWatchdog: vi.fn(), + disarmUpdateInstallExitWatchdog: vi.fn() +})) +vi.mock('./updater-lifecycle-diagnostics', () => ({ + recordUpdaterLifecycle: recordUpdaterLifecycleMock +})) +vi.mock('./linux-update-package-type', () => ({ getLinuxRootPackageType: () => 'deb' })) +vi.mock('./linux-package-update-recovery', () => ({ + captureLinuxPackageArtifact: vi.fn(), + clearTrackedLinuxPackageArtifact: clearTrackedLinuxPackageArtifactMock, + clearTrackedLinuxPackageArtifactForOtherVersion: vi.fn(), + getTrackedLinuxPackageArtifact: getTrackedLinuxPackageArtifactMock, + resolveLinuxPackageInstallInstructions: resolveLinuxPackageInstallInstructionsMock, + revealLinuxPackage: revealLinuxPackageMock +})) + +const ARTIFACT = { + packageType: 'deb' as const, + version: '1.0.61', + path: '/home/tester/.cache/orca-updater/pending/orca-ide_1.0.61_amd64.deb', + sha512: 'LHlL7dKoqg98gS2nfQv878dK+UoktbAkm4M20/hoJ2Qr0Kqsa3MSL4VmWy/Lll/MYjQFkpvOxduQ/vswentozA==' +} + +describe('linux package recovery actions', () => { + afterEach(() => { + vi.useRealTimers() + }) + + beforeEach(() => { + vi.resetModules() + vi.useFakeTimers() + resetHandlers() + autoUpdaterMock.checkForUpdates.mockReset().mockResolvedValue(null) + autoUpdaterMock.downloadUpdate.mockReset() + autoUpdaterMock.quitAndInstall.mockReset() + autoUpdaterMock.setFeedURL.mockReset() + autoUpdaterMock.on.mockClear() + appMock.on.mockClear() + clearTrackedLinuxPackageArtifactMock.mockReset() + getTrackedLinuxPackageArtifactMock.mockReset().mockReturnValue(ARTIFACT) + recordUpdaterLifecycleMock.mockReset() + resolveLinuxPackageInstallInstructionsMock + .mockReset() + .mockResolvedValue({ ok: true, command: "sudo apt install -- ''", packageFileName: 'p' }) + revealLinuxPackageMock.mockReset().mockResolvedValue({ ok: true }) + }) + + const startUpdater = async (): Promise<{ + send: ReturnType + updater: typeof UpdaterModule + }> => { + const send = vi.fn() + const updater = await import('./updater') + updater.setupAutoUpdater({ webContents: { send } } as never, { + getLastUpdateCheckAt: () => Date.now() + }) + return { send, updater } + } + + /** Drives a pre-commit install failure so the status carries the recovery discriminant. */ + const failInstall = async (updater: typeof UpdaterModule): Promise => { + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.emit('error', new Error('Command failed, exited with code 127')) + }) + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + } + + type ErrorStatus = Extract + + const errorStatuses = (send: ReturnType): ErrorStatus[] => + send.mock.calls + .filter(([channel]) => channel === 'updater:status') + .map(([, status]) => status as UpdateStatus) + .filter((status): status is ErrorStatus => status.state === 'error') + + it('rejects both actions while no package-install recovery is active', async () => { + const { updater } = await startUpdater() + + await expect(updater.getLinuxPackageInstallInstructions()).rejects.toThrow( + 'No package install recovery is available.' + ) + await expect(updater.showLinuxPackage()).rejects.toThrow( + 'No package install recovery is available.' + ) + expect(resolveLinuxPackageInstallInstructionsMock).not.toHaveBeenCalled() + expect(revealLinuxPackageMock).not.toHaveBeenCalled() + }) + + it('revalidates the retained package on every invocation', async () => { + const { updater } = await startUpdater() + await failInstall(updater) + + await expect(updater.getLinuxPackageInstallInstructions()).resolves.toEqual({ + ok: true, + command: "sudo apt install -- ''", + packageFileName: 'p' + }) + await updater.getLinuxPackageInstallInstructions() + await updater.showLinuxPackage() + await updater.showLinuxPackage() + + const recovery = { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'package-install-failed', + version: '1.0.61' + } + expect(resolveLinuxPackageInstallInstructionsMock.mock.calls).toEqual([[recovery], [recovery]]) + expect(revealLinuxPackageMock.mock.calls).toEqual([[recovery], [recovery]]) + }) + + it('replaces the structured status when revalidation fails so stale actions die', async () => { + const { send, updater } = await startUpdater() + await failInstall(updater) + resolveLinuxPackageInstallInstructionsMock.mockResolvedValue({ + ok: false, + reason: 'hash-mismatch' + }) + + await expect(updater.getLinuxPackageInstallInstructions()).rejects.toThrow( + 'no longer matches the verified release' + ) + + expect(clearTrackedLinuxPackageArtifactMock).toHaveBeenCalledTimes(1) + const latest = errorStatuses(send).at(-1) + expect(latest?.state === 'error' && latest.recovery).toBeUndefined() + expect(recordUpdaterLifecycleMock).toHaveBeenCalledWith( + 'linux_package_recovery_unavailable', + { reason: 'hash-mismatch', packageType: 'deb', version: '1.0.61' }, + expect.objectContaining({ level: 'warn' }) + ) + // The replacement status has no recovery, so a second attempt cannot reach the artifact again. + await expect(updater.showLinuxPackage()).rejects.toThrow( + 'No package install recovery is available.' + ) + expect(revealLinuxPackageMock).not.toHaveBeenCalled() + }) + + it('clears recovery for both actions once the package is gone', async () => { + const { updater } = await startUpdater() + await failInstall(updater) + revealLinuxPackageMock.mockResolvedValue({ ok: false, reason: 'missing' }) + + await expect(updater.showLinuxPackage()).rejects.toThrow('no longer in the update cache') + + await expect(updater.getLinuxPackageInstallInstructions()).rejects.toThrow( + 'No package install recovery is available.' + ) + }) + + it.each(['no-sudo', 'no-package-manager'] as const)( + 'resolves %s as a result and keeps the card usable instead of rejecting', + async (reason) => { + const { send, updater } = await startUpdater() + await failInstall(updater) + resolveLinuxPackageInstallInstructionsMock.mockResolvedValue({ ok: false, reason }) + const statusesBefore = errorStatuses(send).length + + // Why: the renderer demotes copy on a rejection, so a missing package manager must not reject. + await expect(updater.getLinuxPackageInstallInstructions()).resolves.toEqual({ + ok: false, + reason, + message: expect.stringContaining('Show the package') + }) + + expect(clearTrackedLinuxPackageArtifactMock).not.toHaveBeenCalled() + expect(errorStatuses(send)).toHaveLength(statusesBefore) + expect(recordUpdaterLifecycleMock).toHaveBeenCalledWith( + 'linux_package_recovery_unavailable', + { reason, packageType: 'deb', version: '1.0.61' }, + expect.objectContaining({ level: 'warn' }) + ) + // Show Package must remain reachable as the promoted action. + await expect(updater.showLinuxPackage()).resolves.toBeUndefined() + } + ) + + it('keeps recovery available after a transient read failure', async () => { + const { send, updater } = await startUpdater() + await failInstall(updater) + revealLinuxPackageMock.mockResolvedValue({ ok: false, reason: 'read-failed' }) + const statusesBefore = errorStatuses(send).length + + await expect(updater.showLinuxPackage()).rejects.toThrow( + 'could not read the downloaded package' + ) + + // Why: a read error is not evidence the artifact is bad, so retrying must stay possible. + expect(clearTrackedLinuxPackageArtifactMock).not.toHaveBeenCalled() + expect(errorStatuses(send)).toHaveLength(statusesBefore) + revealLinuxPackageMock.mockResolvedValue({ ok: true }) + await expect(updater.showLinuxPackage()).resolves.toBeUndefined() + }) + + it('ignores a stale mismatch verdict once a newer recovery replaced the card', async () => { + const { send, updater } = await startUpdater() + await failInstall(updater) + let settleValidation!: (result: { ok: false; reason: 'hash-mismatch' }) => void + resolveLinuxPackageInstallInstructionsMock.mockReturnValue( + new Promise((resolve) => { + settleValidation = resolve + }) + ) + + const pending = updater.getLinuxPackageInstallInstructions() + // A 160 MB hash outlives the cycle it started in; a newer download takes over meanwhile. + getTrackedLinuxPackageArtifactMock.mockReturnValue({ ...ARTIFACT, version: '1.0.62' }) + await failInstall(updater) + settleValidation({ ok: false, reason: 'hash-mismatch' }) + + await expect(pending).rejects.toThrow('no longer matches the verified release') + expect(clearTrackedLinuxPackageArtifactMock).not.toHaveBeenCalled() + expect(errorStatuses(send).at(-1)?.recovery?.version).toBe('1.0.62') + }) +}) diff --git a/src/main/updater.fallback.test.ts b/src/main/updater.fallback.test.ts index 24d6729d9eb..f946aafeb6f 100644 --- a/src/main/updater.fallback.test.ts +++ b/src/main/updater.fallback.test.ts @@ -1,10 +1,12 @@ import { describe, expect, it } from 'vitest' +import type { UpdateStatus } from '../shared/types' import { compareVersions, isBenignCheckFailure, isMissingUpdateManifestFailure, isReleaseAssetsPublishingFailure, - isPrereleaseVersion + isPrereleaseVersion, + statusesEqual } from './updater-fallback' describe('compareVersions', () => { @@ -50,6 +52,42 @@ describe('isBenignCheckFailure', () => { }) }) +describe('statusesEqual', () => { + const recovery = { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'authentication-agent-unavailable', + version: '1.0.61' + } as const + const withRecovery: UpdateStatus = { state: 'error', message: 'install failed', recovery } + const withoutRecovery: UpdateStatus = { state: 'error', message: 'install failed' } + + it('does not dedupe a recovery-carrying error against the same message without recovery', () => { + // Why: deduping here would leave the card's copy/show actions enabled with no usable package. + expect(statusesEqual(withRecovery, withoutRecovery)).toBe(false) + expect(statusesEqual(withoutRecovery, withRecovery)).toBe(false) + }) + + it('separates recovery statuses that differ only in package type, reason, or version', () => { + expect( + statusesEqual(withRecovery, { + ...withRecovery, + recovery: { ...recovery, packageType: 'rpm' } + }) + ).toBe(false) + expect( + statusesEqual(withRecovery, { + ...withRecovery, + recovery: { ...recovery, reason: 'package-install-failed' } + }) + ).toBe(false) + expect( + statusesEqual(withRecovery, { ...withRecovery, recovery: { ...recovery, version: '1.0.62' } }) + ).toBe(false) + expect(statusesEqual(withRecovery, { ...withRecovery })).toBe(true) + }) +}) + describe('isReleaseAssetsPublishingFailure', () => { it('only matches the explicit release-asset publishing sentinel', () => { expect(isReleaseAssetsPublishingFailure('Latest release assets are still publishing')).toBe( diff --git a/src/main/updater.test.ts b/src/main/updater.test.ts index b882f9c30b3..35a8c4c45bc 100644 --- a/src/main/updater.test.ts +++ b/src/main/updater.test.ts @@ -1,5 +1,6 @@ /* eslint-disable max-lines */ import { beforeEach, describe, expect, it, vi } from 'vitest' +import type * as UpdaterModule from './updater' const { appMock, @@ -53,6 +54,7 @@ const { autoUpdaterMock.allowDowngrade = false autoUpdaterMock.disableDifferentialDownload = false autoUpdaterMock.autoRunAppAfterInstall = true + autoUpdaterMock.logger = undefined delete (autoUpdaterMock as Record).verifyUpdateCodeSignature } @@ -63,6 +65,8 @@ const { allowPrerelease: false, allowDowngrade: false, disableDifferentialDownload: false, + // Why: setup installs the diagnostic logger adapter here; tests drive child stderr through it. + logger: undefined as { error: (message: unknown) => void } | undefined, on, checkForUpdates: vi.fn(), downloadUpdate: vi.fn(), @@ -99,9 +103,24 @@ vi.mock('electron', () => ({ BrowserWindow: browserWindowMock, autoUpdater: nativeUpdaterMock, powerMonitor: { on: powerMonitorOnMock }, + shell: { showItemInFolder: vi.fn() }, net: { fetch: vi.fn() } })) +const { getLinuxRootPackageTypeMock, recordUpdaterLifecycleMock } = vi.hoisted(() => ({ + getLinuxRootPackageTypeMock: vi.fn<() => 'deb' | 'rpm' | null>(() => null), + recordUpdaterLifecycleMock: vi.fn() +})) + +// Why: only the marker resolver is faked so the real artifact capture/redaction path stays under test. +vi.mock('./linux-update-package-type', () => ({ + getLinuxRootPackageType: getLinuxRootPackageTypeMock +})) + +vi.mock('./updater-lifecycle-diagnostics', () => ({ + recordUpdaterLifecycle: recordUpdaterLifecycleMock +})) + vi.mock('electron-updater', () => ({ autoUpdater: autoUpdaterMock })) @@ -196,6 +215,8 @@ describe('updater', () => { armExitWatchdogMock.mockReset() disarmExitWatchdogMock.mockReset() powerMonitorOnMock.mockReset() + getLinuxRootPackageTypeMock.mockReset().mockReturnValue(null) + recordUpdaterLifecycleMock.mockReset() fetchNudgeMock.mockReset().mockResolvedValue(null) shouldApplyNudgeMock.mockReset().mockReturnValue(false) fetchChangelogMock.mockReset().mockResolvedValue(null) @@ -225,6 +246,34 @@ describe('updater', () => { expect(powerMonitorOnMock).not.toHaveBeenCalled() }) + it.each([ + ['hourly', 'v1.4.160-hourly.202607281400', 'Hourly builds are produced only for macOS.'], + ['adhoc', 'v1.4.160-adhoc.20260728140533', 'Adhoc builds are produced only for macOS.'] + ] as const)( + 'uses the display label in the mac-only %s pinned-build error', + async (channel, tag, message) => { + const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('linux') + try { + const send = vi.fn() + const { setupAutoUpdater, checkForUpdatesFromMenu } = await import('./updater') + setupAutoUpdater({ webContents: { send } } as never, { + getLastUpdateCheckAt: () => Date.now() + }) + + checkForUpdatesFromMenu({ channel, targetTag: tag }) + + expect(send).toHaveBeenCalledWith('updater:status', { + state: 'error', + message, + userInitiated: true + }) + expect(autoUpdaterMock.checkForUpdates).not.toHaveBeenCalled() + } finally { + platformSpy.mockRestore() + } + } + ) + it.runIf(process.platform === 'darwin')( 'allows a validated local build to downgrade through the normal updater lifecycle', async () => { @@ -1731,7 +1780,8 @@ describe('updater', () => { 'updater:status', expect.objectContaining({ state: 'error', - message: 'Could not restart to install the update. Quit and reopen Orca, then try again.' + // Why: a pre-commit install failure is not fixed by restarting, so the copy must not suggest it. + message: 'Could not start the update installer. Orca remains open.' }) ) }) @@ -3742,4 +3792,330 @@ describe('updater', () => { url: 'https://github.com/stablyai/orca/releases/download/v1.3.18-rc.1' }) }) + + describe('linux root package install recovery', () => { + // Real 64-byte SHA-512 values; capture rejects a digest that cannot decode to one. + const DEB_SHA512 = + 'LHlL7dKoqg98gS2nfQv878dK+UoktbAkm4M20/hoJ2Qr0Kqsa3MSL4VmWy/Lll/MYjQFkpvOxduQ/vswentozA==' + const RPM_SHA512 = + 'W2U3AUPfVpc0Ia1qX/VJ5+8aW+yOFhysT6ryodo7A6DTZKqL6RYLK53U6ShGx+9f4lb35qtd4tOp5jzJZZdAfQ==' + // Why: macOS keeps the restart advice because quitting does re-stage a Squirrel update. + const PRE_COMMIT_FAILURE_MESSAGE = + process.platform === 'darwin' + ? 'Could not restart to install the update. Quit and reopen Orca, then try again.' + : 'Could not start the update installer. Orca remains open.' + const DEB_PATH = '/home/tester/.cache/orca-updater/pending/orca-ide_1.0.61_amd64.deb' + const RPM_PATH = '/home/tester/.cache/orca-updater/pending/orca-ide-1.0.61.x86_64.rpm' + const AGENT_STDERR = + 'pkexec: Error executing command as another user: No authentication agent found.' + const EXIT_127 = `Command failed: /usr/bin/pkexec /usr/bin/dpkg -i ${DEB_PATH}, exited with code 127` + + const downloadedEvent = (overrides?: Record): Record => ({ + version: '1.0.61', + downloadedFile: DEB_PATH, + files: [{ url: 'orca-ide_1.0.61_amd64.deb', sha512: DEB_SHA512 }], + ...overrides + }) + + const startUpdater = async ( + packageType: 'deb' | 'rpm' | null + ): Promise<{ send: ReturnType; updater: typeof UpdaterModule }> => { + getLinuxRootPackageTypeMock.mockReturnValue(packageType) + vi.useFakeTimers() + fetchNewerReleaseTagsMock.mockResolvedValue({ tags: ['v1.0.61'], state: 'ready' }) + autoUpdaterMock.checkForUpdates.mockImplementation(() => { + autoUpdaterMock.emit('checking-for-update') + queueMicrotask(() => autoUpdaterMock.emit('update-available', { version: '1.0.61' })) + return Promise.resolve(undefined) + }) + const send = vi.fn() + const updater = await import('./updater') + updater.setupAutoUpdater({ webContents: { send } } as never, { + getLastUpdateCheckAt: () => Date.now() + }) + return { send, updater } + } + + const reachDownloaded = async ( + updater: typeof UpdaterModule, + event: Record + ): Promise => { + updater.checkForUpdatesFromMenu() + await vi.advanceTimersByTimeAsync(0) + autoUpdaterMock.emit('update-downloaded', event) + if (process.platform === 'darwin') { + const nativeReady = nativeUpdaterMock.on.mock.calls.find( + ([eventName]) => eventName === 'update-downloaded' + )?.[1] as (() => void) | undefined + nativeReady?.() + } + await vi.advanceTimersByTimeAsync(0) + } + + it('disables install-on-quit for deb and rpm root packages', async () => { + for (const packageType of ['deb', 'rpm'] as const) { + vi.resetModules() + autoUpdaterMock.autoInstallOnAppQuit = true + getLinuxRootPackageTypeMock.mockReturnValue(packageType) + const { setupAutoUpdater } = await import('./updater') + + setupAutoUpdater({ webContents: { send: vi.fn() } } as never, { + getLastUpdateCheckAt: () => Date.now(), + installMode: 'interactive' + }) + + expect(autoUpdaterMock.autoInstallOnAppQuit).toBe(false) + } + }) + + it('keeps interactive install-on-quit when no root-package marker is present', async () => { + autoUpdaterMock.autoInstallOnAppQuit = false + const { setupAutoUpdater } = await import('./updater') + + setupAutoUpdater({ webContents: { send: vi.fn() } } as never, { + getLastUpdateCheckAt: () => Date.now(), + installMode: 'interactive' + }) + + expect(autoUpdaterMock.autoInstallOnAppQuit).toBe(true) + }) + + it('leaves headless serve installs supervisor-controlled', async () => { + for (const installMode of [ + 'supervised-headless-serve', + 'unsupported-headless-serve' + ] as const) { + vi.resetModules() + autoUpdaterMock.autoInstallOnAppQuit = true + const { setupAutoUpdater } = await import('./updater') + + setupAutoUpdater({ webContents: { send: vi.fn() } } as never, { + getLastUpdateCheckAt: () => Date.now(), + installMode + }) + + expect(autoUpdaterMock.autoInstallOnAppQuit).toBe(false) + } + }) + + it('sends structured recovery when quitAndInstall throws synchronously', async () => { + const { send, updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.logger?.error(`${AGENT_STDERR} target ${DEB_PATH}`) + throw new Error(EXIT_127) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + // Why: the sync throw ends capture before the catch, so the stashed text must survive. + expect(send).toHaveBeenCalledWith('updater:status', { + state: 'error', + message: `${AGENT_STDERR} target `, + recovery: { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'authentication-agent-unavailable', + version: '1.0.61' + } + }) + }) + + it('recovers an event-driven pre-commit failure without tearing down the session', async () => { + const openWindow = { removeAllListeners: vi.fn() } + browserWindowMock.getAllWindows.mockReturnValue([openWindow] as never) + const { send, updater } = await startUpdater('rpm') + await reachDownloaded( + updater, + downloadedEvent({ + downloadedFile: RPM_PATH, + files: [{ url: 'orca-ide-1.0.61.x86_64.rpm', sha512: RPM_SHA512 }] + }) + ) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.emit('error', new Error('Command failed, exited with code 1')) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + expect(send).toHaveBeenCalledWith('updater:status', { + state: 'error', + message: 'Command failed, exited with code 1', + recovery: { + kind: 'linux-package-install', + packageType: 'rpm', + reason: 'package-install-failed', + version: '1.0.61' + } + }) + expect(killAllPtyMock).not.toHaveBeenCalled() + expect(openWindow.removeAllListeners).not.toHaveBeenCalled() + expect(updater.isQuittingForUpdate()).toBe(false) + expect(disarmExitWatchdogMock).toHaveBeenCalled() + }) + + it('keeps the generic install-failure copy when no artifact was retained', async () => { + const { send, updater } = await startUpdater('deb') + // Release metadata without a digest must not enable cached-package recovery. + await reachDownloaded( + updater, + downloadedEvent({ files: [{ url: 'orca-ide_1.0.61_amd64.deb' }] }) + ) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.emit('error', new Error(EXIT_127)) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + expect(send).toHaveBeenCalledWith('updater:status', { + state: 'error', + message: PRE_COMMIT_FAILURE_MESSAGE + }) + expect(recordUpdaterLifecycleMock).not.toHaveBeenCalledWith( + 'linux_package_install_failed', + expect.anything(), + expect.anything() + ) + }) + + it('advises a restart only for a failure before the native invoke', async () => { + const { send, updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + // The source calls this out as the pre-native "cleanup/tracing exception" case. + recordUpdaterLifecycleMock.mockImplementation((event: unknown) => { + if (event === 'quit_and_install_invoking_native') { + throw new Error('tracing sink unavailable') + } + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + expect(autoUpdaterMock.quitAndInstall).not.toHaveBeenCalled() + expect(send).toHaveBeenCalledWith('updater:status', { + state: 'error', + message: 'Could not restart to install the update. Quit and reopen Orca, then try again.' + }) + expect(updater.isQuittingForUpdate()).toBe(false) + }) + + it('keeps a committed install intact when post-commit cleanup throws', async () => { + const { send, updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + // Why: spawnSync already installed the package; a teardown throw must not be reported as failure. + killAllPtyMock.mockImplementation(() => { + throw new Error('pty teardown failed') + }) + send.mockClear() + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + expect(recordUpdaterLifecycleMock).toHaveBeenCalledWith( + 'post_commit_cleanup_failed', + { errorType: 'Error' }, + expect.objectContaining({ level: 'warn' }) + ) + expect(send).not.toHaveBeenCalled() + expect(updater.isQuittingForUpdate()).toBe(true) + expect(armExitWatchdogMock).toHaveBeenCalledTimes(1) + expect(disarmExitWatchdogMock).not.toHaveBeenCalled() + }) + + it('still suppresses late post-commit errors while an artifact is retained', async () => { + const { send, updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + expect(killAllPtyMock).toHaveBeenCalledTimes(1) + + send.mockClear() + autoUpdaterMock.emit('error', new Error(EXIT_127)) + + expect(send).not.toHaveBeenCalled() + expect(updater.isQuittingForUpdate()).toBe(true) + }) + + it('retries the automatic install without redownloading the package', async () => { + const { send, updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.emit('error', new Error(EXIT_127)) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + // Why: a retry usually fails identically; a deduped status would strand the preload restart relay. + expect( + send.mock.calls.filter( + ([channel, status]) => + channel === 'updater:status' && + (status as { recovery?: { kind?: string } })?.recovery?.kind === 'linux-package-install' + ) + ).toHaveLength(2) + expect(autoUpdaterMock.quitAndInstall).toHaveBeenCalledTimes(2) + expect(autoUpdaterMock.downloadUpdate).not.toHaveBeenCalled() + expect(recordUpdaterLifecycleMock).toHaveBeenCalledWith('linux_package_recovery_requested', { + action: 'retry-automatic', + packageType: 'deb', + version: '1.0.61' + }) + }) + + it('records classification-only lifecycle data for a package install failure', async () => { + const { updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.logger?.error(`${AGENT_STDERR} target ${DEB_PATH}`) + autoUpdaterMock.emit('error', new Error(EXIT_127)) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + const failure = recordUpdaterLifecycleMock.mock.calls.find( + ([event]) => event === 'linux_package_install_failed' + ) + expect(failure?.[1]).toEqual({ + packageType: 'deb', + reason: 'authentication-agent-unavailable', + exitCode: 127, + version: '1.0.61', + errorType: 'Error' + }) + const durable = JSON.stringify(recordUpdaterLifecycleMock.mock.calls) + expect(durable).not.toContain(DEB_PATH) + expect(durable).not.toContain('authentication agent') + }) + + it('omits exitCode from lifecycle data when the child status is unparseable', async () => { + const { updater } = await startUpdater('deb') + await reachDownloaded(updater, downloadedEvent()) + autoUpdaterMock.quitAndInstall.mockImplementation(() => { + autoUpdaterMock.emit('error', new Error('dpkg was interrupted')) + }) + + updater.quitAndInstall() + await vi.advanceTimersByTimeAsync(100) + + const failure = recordUpdaterLifecycleMock.mock.calls.find( + ([event]) => event === 'linux_package_install_failed' + ) + // Why: an absent key, not an explicit null, keeps the breadcrumb schema honest. + expect(failure?.[1]).toEqual({ + packageType: 'deb', + reason: 'package-install-failed', + version: '1.0.61', + errorType: 'Error' + }) + expect(Object.keys(failure?.[1] as object)).not.toContain('exitCode') + }) + }) }) diff --git a/src/main/updater.ts b/src/main/updater.ts index d5b5065afc9..6bb26d84dd5 100644 --- a/src/main/updater.ts +++ b/src/main/updater.ts @@ -1,7 +1,13 @@ /* eslint-disable max-lines */ import { app, BrowserWindow, powerMonitor } from 'electron' import { is } from '@electron-toolkit/utils' -import type { UpdateCheckOptions, UpdateSource, UpdateStatus } from '../shared/types' +import type { + LinuxPackageInstallInstructions, + LinuxPackageInstallRecovery, + UpdateCheckOptions, + UpdateSource, + UpdateStatus +} from '../shared/types' import type { RemoteServerUpdateInstallResult, RemoteServerUpdaterSnapshot, @@ -25,6 +31,23 @@ import { } from './update-install-exit-watchdog' import { registerAutoUpdaterHandlers } from './updater-events' import { recordUpdaterLifecycle } from './updater-lifecycle-diagnostics' +import { getLinuxRootPackageType } from './linux-update-package-type' +import { + beginLinuxPackageInstallDiagnosticCapture, + createUpdaterDiagnosticLogger, + endLinuxPackageInstallDiagnosticCapture, + getLinuxPackageInstallDiagnostic, + parseLinuxPackageInstallExitCode, + redactLinuxPackageInstallText, + type LinuxPackageInstallDiagnostic +} from './linux-package-install-diagnostic' +import { + clearTrackedLinuxPackageArtifact, + getTrackedLinuxPackageArtifact, + resolveLinuxPackageInstallInstructions, + revealLinuxPackage, + type LinuxPackageRecoveryUnavailableReason +} from './linux-package-update-recovery' import { compareVersions, isBenignCheckFailure, @@ -48,6 +71,7 @@ import { listReleaseBuilds, resolveTargetBuild } from './updater-release-builds' import { hasDedicatedReleaseRepo, isChannelSupportedOnPlatform, + RELEASE_CHANNEL_LABELS, type ReleaseBuild, type ReleaseChannel } from '../shared/release-channel' @@ -106,6 +130,8 @@ let lastInstallDeferralVersion = { download: null as string | null, install: nul let updateInstallCommitted = false // Why: recovery must only run after the native quitAndInstall call; pre-native errors must not clear quittingForUpdate or look like install recovery. let quitAndInstallNativeInvoked = false +// Why: a synchronous throw out of quitAndInstall ends diagnostic capture before the catch runs, so stash the redacted text for it. +let lastInstallAttemptDiagnostic: LinuxPackageInstallDiagnostic | null = null let persistLastUpdateCheckAt: ((timestamp: number) => void) | null = null let _getLastUpdateCheckAt: (() => number | null) | null = null let backgroundCheckLaunchPending = false @@ -242,7 +268,8 @@ function decorateStatusWithActiveNudge(status: UpdateStatus): UpdateStatus { return { ...status, activeNudgeId: activeUpdateNudgeId } } -function sendStatus(status: UpdateStatus): void { +/** `force` re-delivers a status the renderer must not miss even when it repeats the current one. */ +function sendStatus(status: UpdateStatus, options?: { force?: boolean }): void { const pendingUserInitiatedCheckVariant = pendingUserInitiatedCheckAfterInFlight const shouldLaunchPendingUserInitiatedCheck = pendingUserInitiatedCheckVariant !== null && @@ -308,10 +335,15 @@ function sendStatus(status: UpdateStatus): void { downloadInFlight = false } if (shouldLaunchPendingUserInitiatedCheck) { + // Why: a forced status must still land before the queued check restarts the cycle. + if (options?.force) { + currentStatus = decoratedStatus + mainWindowRef?.webContents.send('updater:status', decoratedStatus) + } launchPendingUserInitiatedCheckAfterInFlight(pendingUserInitiatedCheckVariant) return } - if (statusesEqual(currentStatus, decoratedStatus)) { + if (!options?.force && statusesEqual(currentStatus, decoratedStatus)) { return } currentStatus = decoratedStatus @@ -729,7 +761,15 @@ async function performQuitAndInstall(): Promise { quitAndInstallNativeInvoked = true // Why: invoke before killAllPty/removing close listeners so a sync 'error' (the "no filepath" path) can recover while windows and PTYs are intact. const supervisorOwnsRelaunch = updateInstallMode === 'supervised-headless-serve' - getAutoUpdater().quitAndInstall(supervisorOwnsRelaunch, !supervisorOwnsRelaunch) + // Why: BaseUpdater logs child stderr but drops it from the 'error' event, so retain it for the span of this call. + beginLinuxPackageInstallDiagnosticCapture(getTrackedLinuxPackageArtifact()?.path ?? null) + try { + getAutoUpdater().quitAndInstall(supervisorOwnsRelaunch, !supervisorOwnsRelaunch) + } finally { + const diagnostic = endLinuxPackageInstallDiagnosticCapture() + // Why: a synchronous 'error' already consumed and reset this attempt; re-stashing would leak it into the next one. + lastInstallAttemptDiagnostic = quitAndInstallInProgress ? diagnostic : null + } span.addEvent('native_quit_and_install_invoked') // Why: quitAndInstall can synchronously clear quitAndInstallInProgress via recovery (Win/Linux dispatchError); skip destructive prep if it already ran. @@ -737,6 +777,14 @@ async function performQuitAndInstall(): Promise { return } + // Why: DebUpdater/RpmUpdater install through spawnSync, so a normal return already means the + // package is installed. Commit here or a throw in the cleanup below is reported as an install + // failure — offering a recovery card, and stale stderr, for an update that actually succeeded. + if (getLinuxRootPackageType() !== null) { + updateInstallCommitted = true + armUpdateInstallExitWatchdog() + } + killAllPty() span.addEvent('local_pty_kill_all') @@ -748,13 +796,33 @@ async function performQuitAndInstall(): Promise { }) // Why: committed installs keep quittingForUpdate so dock activate can't reopen the old process; macOS without Squirrel stays uncommitted so late native errors can still recover. - if (process.platform !== 'darwin' || isMacInstallerReady()) { + if (!updateInstallCommitted && (process.platform !== 'darwin' || isMacInstallerReady())) { updateInstallCommitted = true // Why: past commit the installer waits for this process to exit; a wedged async shutdown would strand the user with no app and no update (#4438). armUpdateInstallExitWatchdog() } }) } catch (error) { + // Why: on Linux the package is already installed once quitAndInstall returns, and the installer is + // waiting for this process to exit. Tearing down here would disarm the exit watchdog (#4438), clear + // quittingForUpdate mid-quit, and tell the user an install failed that actually succeeded. + if (updateInstallCommitted) { + recordUpdaterLifecycle( + 'post_commit_cleanup_failed', + { errorType: error instanceof Error ? error.name : typeof error }, + { + level: 'warn', + message: 'Update install cleanup failed after commit; install already applied' + } + ) + return + } + // Why: a pre-native cleanup/tracing exception is not a package install failure and must not be labelled as one. + const quitAndInstallNativeInvokedBeforeReset = quitAndInstallNativeInvoked + const recoveryStatus = + quitAndInstallNativeInvokedBeforeReset && !updateInstallCommitted + ? buildLinuxPackageInstallFailureStatus(error) + : null failServeUpdateHandoff('Could not invoke the native updater.') resetQuitForUpdateState() recordUpdaterLifecycle( @@ -765,8 +833,14 @@ async function performQuitAndInstall(): Promise { message: 'Could not start update install' } ) - sendErrorStatus( - 'Could not restart to install the update. Quit and reopen Orca, then try again.' + sendInstallFailureStatus( + recoveryStatus ?? { + state: 'error', + // Why: past the native invoke this is the same pre-commit failure the event path reports, so it gets the same copy; only a pre-native exception can be helped by a restart. + message: quitAndInstallNativeInvokedBeforeReset + ? getPreCommitInstallFailureMessage() + : 'Could not restart to install the update. Quit and reopen Orca, then try again.' + } ) } } @@ -776,22 +850,95 @@ function resetQuitForUpdateState(): void { quittingForUpdate = false updateInstallCommitted = false quitAndInstallNativeInvoked = false + lastInstallAttemptDiagnostic = null disarmUpdateInstallExitWatchdog() resetMacInstallState() } +/** + * On macOS a pre-commit failure means Squirrel rejected the staged update, and quitting does re-stage + * it — so keep that advice there. Everywhere else a restart is not known to help. + */ +function getPreCommitInstallFailureMessage(): string { + return process.platform === 'darwin' + ? 'Could not restart to install the update. Quit and reopen Orca, then try again.' + : 'Could not start the update installer. Orca remains open.' +} + +/** + * Sends an install-failure status even when it repeats the current one. "Try Automatic Install + * Again" usually fails identically, and a deduped status would never reach the preload abort relay, + * leaving the renderer stuck in its restart checkpoint. + */ +function sendInstallFailureStatus(status: UpdateStatus): void { + sendStatus(status, { force: true }) +} + +/** + * The recovery status for a failed `.deb`/`.rpm` install, or null when no retained package can + * recover it. Must run before `resetQuitForUpdateState()` clears the attempt diagnostic. + */ +function buildLinuxPackageInstallFailureStatus(error: unknown): UpdateStatus | null { + const artifact = getTrackedLinuxPackageArtifact() + if (!artifact) { + return null + } + const pendingVersion = getPendingInstallVersion() + if (pendingVersion && pendingVersion !== artifact.version) { + return null + } + const diagnostic = getLinuxPackageInstallDiagnostic() ?? lastInstallAttemptDiagnostic + // Why: the reason was classified from the original output, before redaction could rewrite a match. + const reason = diagnostic?.reason ?? 'package-install-failed' + // Durable data carries classification only — never the package path, home path, command, or stderr. + const exitCode = parseLinuxPackageInstallExitCode(error) + recordUpdaterLifecycle( + 'linux_package_install_failed', + { + packageType: artifact.packageType, + reason, + // Omitted rather than null when the child status could not be parsed. + ...(exitCode === null ? {} : { exitCode }), + version: artifact.version, + errorType: error instanceof Error ? error.name : typeof error + }, + { level: 'warn', message: 'Linux package install failed; cached package retained' } + ) + // Why: this text is shown in the card, so it gets the same redaction as retained stderr. + const message = + diagnostic?.message ?? + (error instanceof Error ? redactLinuxPackageInstallText(error.message, artifact.path) : null) ?? + 'The system package installer did not start.' + return { + state: 'error', + message, + recovery: { + kind: 'linux-package-install', + packageType: artifact.packageType, + reason, + version: artifact.version + } + } +} + // Why: quitAndInstall failures arrive via 'error'; recover only after native invoke and before commit, else clearing quittingForUpdate lets dock activate reopen the old process mid-installer. -function handleQuitAndInstallFailure(): boolean { +function handleQuitAndInstallFailure(error?: unknown): boolean { if (!quitAndInstallInProgress || !quitAndInstallNativeInvoked || updateInstallCommitted) { return false } + const recoveryStatus = buildLinuxPackageInstallFailureStatus(error) failServeUpdateHandoff('The native updater rejected the install request.') resetQuitForUpdateState() recordUpdaterLifecycle('quit_and_install_failed_via_event', undefined, { level: 'warn', message: 'Update install could not start; recovered app state' }) - sendErrorStatus('Could not restart to install the update. Quit and reopen Orca, then try again.') + sendInstallFailureStatus( + recoveryStatus ?? { + state: 'error', + message: getPreCommitInstallFailureMessage() + } + ) return true } @@ -1534,7 +1681,7 @@ async function checkForPinnedBuild(channel: ReleaseChannel, tag: string): Promis if (!isChannelSupportedOnPlatform(channel, process.platform)) { sendStatus({ state: 'error', - message: `${channel} builds are produced only for macOS.`, + message: `${RELEASE_CHANNEL_LABELS[channel]} builds are produced only for macOS.`, userInitiated: true }) return @@ -1592,6 +1739,111 @@ export function isQuittingForUpdate(): boolean { return quittingForUpdate } +function getActiveLinuxPackageRecovery(): LinuxPackageInstallRecovery | null { + if (currentStatus.state !== 'error') { + return null + } + return currentStatus.recovery?.kind === 'linux-package-install' ? currentStatus.recovery : null +} + +const LINUX_PACKAGE_RECOVERY_MESSAGES: Record = { + missing: + 'The downloaded package is no longer in the update cache. Download the update again, or get it from the official release page.', + // Why: this reason also covers a path that left the cache (traversal or symlinked parent), so the copy must not promise the file merely changed type. + 'not-regular': + 'The downloaded package is no longer a valid file in the update cache. Download the update again, or get it from the official release page.', + 'hash-mismatch': + 'The downloaded package no longer matches the verified release, so Orca will not hand it to a package manager. Download the update again, or get it from the official release page.', + 'read-failed': + 'Orca could not read the downloaded package. Download the update again, or get it from the official release page.', + 'no-sudo': + 'No sudo command was found in the system directories, so Orca cannot build a safe install command. Show the package and install it with your package manager.', + 'no-package-manager': + 'No supported package manager was found in the system directories, so Orca cannot build a safe install command. Show the package and install it with your package manager.', + // Defensive: capture only ever tracks absolute cache paths, so this reports a bug rather than a machine state. + 'invalid-package-path': + 'The downloaded package is not at a usable path, so Orca cannot build a safe install command. Show the package and install it with your package manager.' +} + +// Why: clearing the artifact alone would leave the renderer's actions enabled; the status must lose its recovery too. +const RECOVERY_CLEARING_REASONS: LinuxPackageRecoveryUnavailableReason[] = [ + 'missing', + 'not-regular', + 'hash-mismatch' +] + +function recordLinuxPackageRecoveryUnavailable( + recovery: LinuxPackageInstallRecovery, + reason: LinuxPackageRecoveryUnavailableReason +): void { + recordUpdaterLifecycle( + 'linux_package_recovery_unavailable', + { reason, packageType: recovery.packageType, version: recovery.version }, + { level: 'warn', message: 'Linux package recovery action unavailable' } + ) +} + +function failLinuxPackageRecovery( + recovery: LinuxPackageInstallRecovery, + reason: LinuxPackageRecoveryUnavailableReason +): never { + recordLinuxPackageRecoveryUnavailable(recovery, reason) + const message = LINUX_PACKAGE_RECOVERY_MESSAGES[reason] + // Why: hashing 160 MB takes long enough for a new cycle to land. Acting on a stale verdict would + // destroy the newer artifact and clobber whatever card replaced this one. + const active = getActiveLinuxPackageRecovery() + const stillCurrent = + active?.version === recovery.version && active?.packageType === recovery.packageType + if (stillCurrent && RECOVERY_CLEARING_REASONS.includes(reason)) { + clearTrackedLinuxPackageArtifact() + sendStatus({ state: 'error', message }) + } + throw new Error(message) +} + +export async function getLinuxPackageInstallInstructions(): Promise { + const recovery = getActiveLinuxPackageRecovery() + if (!recovery) { + throw new Error('No package install recovery is available.') + } + recordUpdaterLifecycle('linux_package_recovery_requested', { + action: 'copy-command', + packageType: recovery.packageType, + version: recovery.version + }) + const result = await resolveLinuxPackageInstallInstructions(recovery) + if (!result.ok) { + // Why: the renderer must distinguish "this machine has no package manager" (keep the card, promote + // Show Package) from "the artifact is gone" (recovery is cleared and the card unmounts). + if (result.reason === 'no-sudo' || result.reason === 'no-package-manager') { + recordLinuxPackageRecoveryUnavailable(recovery, result.reason) + return { + ok: false, + reason: result.reason, + message: LINUX_PACKAGE_RECOVERY_MESSAGES[result.reason] + } + } + failLinuxPackageRecovery(recovery, result.reason) + } + return { ok: true, command: result.command, packageFileName: result.packageFileName } +} + +export async function showLinuxPackage(): Promise { + const recovery = getActiveLinuxPackageRecovery() + if (!recovery) { + throw new Error('No package install recovery is available.') + } + recordUpdaterLifecycle('linux_package_recovery_requested', { + action: 'show-package', + packageType: recovery.packageType, + version: recovery.version + }) + const result = await revealLinuxPackage(recovery) + if (!result.ok) { + failLinuxPackageRecovery(recovery, result.reason) + } +} + export function quitAndInstall(): void { if ( localBuildSelectionInProgress || @@ -1602,6 +1854,15 @@ export function quitAndInstall(): void { return } + const retriedRecovery = getActiveLinuxPackageRecovery() + if (retriedRecovery) { + recordUpdaterLifecycle('linux_package_recovery_requested', { + action: 'retry-automatic', + packageType: retriedRecovery.packageType, + version: retriedRecovery.version + }) + } + if (deferHeadlessServeInstall('install', getPendingInstallVersion())) { return } @@ -1760,17 +2021,15 @@ export function setupAutoUpdater( autoUpdater.disableDifferentialDownload = false } // Why: supervised serve installs require an explicit handoff; ordinary service quits must never install implicitly. - autoUpdater.autoInstallOnAppQuit = updateInstallMode === 'interactive' + // Root Linux packages also opt out: an implicit quit-time escalation would fail after the UI is gone, leaving no recovery surface. + autoUpdater.autoInstallOnAppQuit = + updateInstallMode === 'interactive' && getLinuxRootPackageType() === null // Why: MacUpdater ignores quitAndInstall arguments; the surviving CLI supervisor must be the only serve relaunch owner. autoUpdater.autoRunAppAfterInstall = updateInstallMode === 'interactive' // Why: our only on-machine window into electron-updater; otherwise an unexpected update-not-available or failed fetch is invisible. - autoUpdater.logger = { - info: (m: unknown) => console.info('[autoUpdater]', m), - warn: (m: unknown) => console.warn('[autoUpdater]', m), - error: (m: unknown) => console.error('[autoUpdater]', m), - debug: (m: unknown) => console.debug('[autoUpdater]', m) - } as never + // The adapter also retains the redacted child stderr that BaseUpdater logs but drops from the 'error' event. + autoUpdater.logger = createUpdaterDiagnosticLogger() as never // Security: never re-add a verifyUpdateCodeSignature override — a no-op disables electron-updater's built-in Authenticode check and accepts any installer. diff --git a/src/main/window/attach-main-window-services.ts b/src/main/window/attach-main-window-services.ts index b580b97e456..0e1632ecfbe 100644 --- a/src/main/window/attach-main-window-services.ts +++ b/src/main/window/attach-main-window-services.ts @@ -35,14 +35,17 @@ import type { OrcaRuntimeService, RuntimeWorktreeLifecycleEvent } from '../runti import { checkForUpdatesFromMenu, downloadUpdate, + getLinuxPackageInstallInstructions, getUpdateStatus, quitAndInstall, setupAutoUpdater, + showLinuxPackage, dismissAvailableUpdate, dismissNudge, listAvailableReleaseBuilds, type UpdateInstallMode } from '../updater' +import { isTrustedUIRenderer } from '../ipc/ui' import { scheduleHistoryGc } from '../terminal-history-gc' import { hydrateLocalPtyRegistryAtBoot } from '../memory/hydrate-local-pty-registry' import type { ClaudeRuntimeAuthPreparation } from '../claude-accounts/runtime-auth-service' @@ -530,6 +533,8 @@ export function registerUpdaterHandlers(_store: Store): void { ipcMain.removeHandler('updater:quitAndInstall') ipcMain.removeHandler('updater:dismissNudge') ipcMain.removeHandler('updater:dismissAvailableUpdate') + ipcMain.removeHandler('updater:getLinuxPackageInstallInstructions') + ipcMain.removeHandler('updater:showLinuxPackage') ipcMain.removeHandler('updater:listBuilds') ipcMain.handle('updater:getStatus', () => getUpdateStatus()) @@ -542,6 +547,16 @@ export function registerUpdaterHandlers(_store: Store): void { ipcMain.handle('updater:quitAndInstall', () => quitAndInstall()) ipcMain.handle('updater:dismissNudge', () => dismissNudge()) ipcMain.handle('updater:dismissAvailableUpdate', () => dismissAvailableUpdate()) + // Why: the response carries a local package path and the reveal touches the native desktop, so + // neither may be reached from a guest, dashboard popout, stale window, or utility renderer. + ipcMain.handle('updater:getLinuxPackageInstallInstructions', (event) => { + assertTrustedUpdaterRecoverySender(event) + return getLinuxPackageInstallInstructions() + }) + ipcMain.handle('updater:showLinuxPackage', (event) => { + assertTrustedUpdaterRecoverySender(event) + return showLinuxPackage() + }) ipcMain.handle( 'updater:listBuilds', async (_event, channel: ReleaseChannel): Promise => { @@ -558,3 +573,9 @@ export function registerUpdaterHandlers(_store: Store): void { } ) } + +function assertTrustedUpdaterRecoverySender(event: IpcMainInvokeEvent): void { + if (!isTrustedUIRenderer(event.sender)) { + throw new Error('Unauthorized updater package recovery sender') + } +} diff --git a/src/main/window/updater-package-recovery-ipc.test.ts b/src/main/window/updater-package-recovery-ipc.test.ts new file mode 100644 index 00000000000..554ca4e23b5 --- /dev/null +++ b/src/main/window/updater-package-recovery-ipc.test.ts @@ -0,0 +1,193 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' +import type { IpcMainInvokeEvent, WebContents } from 'electron' +import type { Store } from '../persistence' +import type * as IpcUiModule from '../ipc/ui' + +const { + handleMock, + removeHandlerMock, + isTrustedUIRendererMock, + getLinuxPackageInstallInstructionsMock, + showLinuxPackageMock +} = vi.hoisted(() => ({ + handleMock: vi.fn(), + removeHandlerMock: vi.fn(), + isTrustedUIRendererMock: vi.fn<(sender: unknown) => boolean>(() => true), + getLinuxPackageInstallInstructionsMock: vi.fn(), + showLinuxPackageMock: vi.fn() +})) + +vi.mock('electron', () => ({ + app: { getVersion: vi.fn(() => '1.0.51') }, + clipboard: {}, + systemPreferences: { askForMediaAccess: vi.fn(), getMediaAccessStatus: vi.fn() }, + ipcMain: { + on: vi.fn(), + removeAllListeners: vi.fn(), + removeListener: vi.fn(), + removeHandler: removeHandlerMock, + handle: handleMock + }, + powerMonitor: { on: vi.fn(), off: vi.fn() } +})) + +vi.mock('../ipc/repos', () => ({ registerRepoHandlers: vi.fn() })) +vi.mock('../ipc/worktrees', () => ({ registerWorktreeHandlers: vi.fn() })) +vi.mock('../ipc/worktree-change-invalidators', () => ({ runWorktreeChangeInvalidators: vi.fn() })) +vi.mock('../ipc/pty', () => ({ getLocalPtyProvider: vi.fn(), registerPtyHandlers: vi.fn() })) +vi.mock('../memory/hydrate-local-pty-registry', () => ({ + hydrateLocalPtyRegistryAtBoot: vi.fn() +})) +vi.mock('../browser/browser-manager', () => ({ browserManager: { unregisterAll: vi.fn() } })) +vi.mock('../macos-tcc-prompt-notice', () => ({ + acknowledgePendingTccPromptNotice: vi.fn(), + consumePendingTccPromptNotice: vi.fn(), + dismissTccPromptNotice: vi.fn(), + releasePendingTccPromptNotice: vi.fn() +})) + +vi.mock('../updater', () => ({ + checkForUpdates: vi.fn(), + checkForUpdatesFromMenu: vi.fn(), + downloadUpdate: vi.fn(), + getUpdateStatus: vi.fn(), + quitAndInstall: vi.fn(), + dismissNudge: vi.fn(), + dismissAvailableUpdate: vi.fn(), + setupAutoUpdater: vi.fn(), + getLinuxPackageInstallInstructions: getLinuxPackageInstallInstructionsMock, + showLinuxPackage: showLinuxPackageMock +})) + +// Why: the seam stays mocked so one test can prove the wiring, but it defaults to delegating to the +// real predicate so the sender cases below exercise its actual branches. +vi.mock('../ipc/ui', async (importOriginal) => ({ + ...(await importOriginal()), + isTrustedUIRenderer: (sender: unknown) => isTrustedUIRendererMock(sender) +})) + +import { registerUpdaterHandlers } from './attach-main-window-services' + +const RECOVERY_CHANNELS = [ + 'updater:getLinuxPackageInstallInstructions', + 'updater:showLinuxPackage' +] as const + +const TRUSTED_ID = 7 +const UNAUTHORIZED = 'Unauthorized updater package recovery sender' + +type InvokeHandler = (event: IpcMainInvokeEvent, ...args: unknown[]) => unknown + +let actualUi: typeof IpcUiModule + +function getHandler(channel: string): InvokeHandler { + const handler = handleMock.mock.calls.find(([name]) => name === channel)?.[1] as + | InvokeHandler + | undefined + if (!handler) { + throw new Error(`no handler registered for ${channel}`) + } + return handler +} + +function webContents(overrides: Partial): Partial { + return { + id: TRUSTED_ID, + isDestroyed: () => false, + getType: () => 'window', + getURL: () => 'file:///index.html', + ...overrides + } +} + +function senderEvent(sender: Partial): IpcMainInvokeEvent { + return { sender } as IpcMainInvokeEvent +} + +function expectBothChannelsRejected(sender: Partial): void { + const event = senderEvent(sender) + for (const channel of RECOVERY_CHANNELS) { + expect(() => getHandler(channel)(event)).toThrow(UNAUTHORIZED) + } + expect(getLinuxPackageInstallInstructionsMock).not.toHaveBeenCalled() + expect(showLinuxPackageMock).not.toHaveBeenCalled() +} + +describe('updater linux package recovery IPC handlers', () => { + beforeAll(async () => { + // An unmocked copy, so the trusted-id state it reads is the one these tests set. + actualUi = await vi.importActual('../ipc/ui') + }) + + beforeEach(() => { + handleMock.mockReset() + removeHandlerMock.mockReset() + isTrustedUIRendererMock + .mockReset() + .mockImplementation((sender) => actualUi.isTrustedUIRenderer(sender as WebContents)) + actualUi.setTrustedUIRendererWebContentsId(TRUSTED_ID) + getLinuxPackageInstallInstructionsMock + .mockReset() + .mockResolvedValue({ ok: true, command: "sudo apt install -- ''", packageFileName: 'p' }) + showLinuxPackageMock.mockReset().mockResolvedValue(undefined) + registerUpdaterHandlers({} as Store) + }) + + afterEach(() => { + vi.unstubAllEnvs() + }) + + it('removes and re-registers both recovery channels', () => { + for (const channel of RECOVERY_CHANNELS) { + expect(removeHandlerMock).toHaveBeenCalledWith(channel) + expect(handleMock.mock.calls.filter(([name]) => name === channel)).toHaveLength(1) + } + }) + + it('routes both channels through the trusted-renderer guard', () => { + isTrustedUIRendererMock.mockReturnValue(false) + + expectBothChannelsRejected(webContents({})) + + expect(isTrustedUIRendererMock).toHaveBeenCalledTimes(2) + }) + + it('serves the current main UI renderer', async () => { + const event = senderEvent(webContents({})) + + await expect(getHandler(RECOVERY_CHANNELS[0])(event)).resolves.toEqual({ + ok: true, + command: "sudo apt install -- ''", + packageFileName: 'p' + }) + await expect(getHandler(RECOVERY_CHANNELS[1])(event)).resolves.toBeUndefined() + }) + + // Each row is a distinct branch of the real isTrustedUIRenderer, not a relabelled mock return. + it.each([ + ['a guest webview', webContents({ getType: () => 'webview' })], + ['a utility renderer', webContents({ getType: () => 'offscreen' })], + ['a destroyed sender', webContents({ isDestroyed: () => true })], + ['a dashboard popout or stale window', webContents({ id: TRUSTED_ID + 1 })] + ])('rejects both recovery channels for %s', (_label, sender) => { + expectBothChannelsRejected(sender) + }) + + it('rejects a foreign-origin renderer when only the dev URL fallback applies', () => { + actualUi.setTrustedUIRendererWebContentsId(null) + vi.stubEnv('ELECTRON_RENDERER_URL', 'http://localhost:5173') + + expectBothChannelsRejected(webContents({ getURL: () => 'http://evil.invalid/index.html' })) + }) + + it('rechecks sender trust on every invocation', () => { + const event = senderEvent(webContents({})) + void getHandler(RECOVERY_CHANNELS[0])(event) + + // The main window was replaced between calls; the previously served sender is now stale. + actualUi.setTrustedUIRendererWebContentsId(TRUSTED_ID + 1) + + expect(() => getHandler(RECOVERY_CHANNELS[0])(event)).toThrow(UNAUTHORIZED) + expect(getLinuxPackageInstallInstructionsMock).toHaveBeenCalledTimes(1) + }) +}) diff --git a/src/preload/api-types.ts b/src/preload/api-types.ts index cd1ba3b4708..0cb1bc071fa 100644 --- a/src/preload/api-types.ts +++ b/src/preload/api-types.ts @@ -54,6 +54,9 @@ import type { VerifyAndAddRuntimeEnvironmentResult } from '../shared/remote-pair import type { SshMutationExpectation, SshConnectionState, + SshConfigHostListArgs, + SshConfigHostListResult, + SshConfigHostResolution, SshConfigImportResult, SshTargetAddResult, SshTarget, @@ -271,7 +274,8 @@ import type { WorktreeSetupLaunch, WorktreeStartupLaunch, WorkspaceSessionPatch, - WorkspaceSessionState + WorkspaceSessionState, + LinuxPackageInstallInstructions } from '../shared/types' import type { PtyModelRestoreNeededEvent } from '../shared/pty-model-restore-marker' import type { PtyListedSession } from '../shared/pty-listed-session' @@ -551,6 +555,14 @@ export type BrowserApi = { sessionProfileId?: string | null webContentsId: number }) => Promise + isGuestRegistered: (args: { browserPageId: string; webContentsId: number }) => Promise + repairGuestRegistration: (args: { + browserPageId: string + workspaceId: string + worktreeId: string + sessionProfileId?: string | null + webContentsId: number + }) => Promise unregisterGuest: (args: { browserPageId: string }) => Promise openDevTools: (args: { browserPageId: string }) => Promise setViewportOverride: (args: { @@ -881,6 +893,7 @@ export type OpenCodeUsageApi = { export type AiVaultApi = { listSessions: (args?: AiVaultListArgs) => Promise + cancelListSessions: (args: { requestToken: string }) => Promise prepareSessionResume: ( args: AiVaultPrepareSessionResumeArgs ) => Promise @@ -977,6 +990,9 @@ export type AppApi = { sessions: { state: WorkspaceSessionState; hostId?: ExecutionHostId }[] ui: Partial }) => void + /** Resolves once the last staged checkpoint is durably written; rejects if that + * write failed, so a reload/restart can abort instead of losing the snapshot. */ + awaitBeforeUnloadCheckpoint: () => Promise /** Resolves when the daemon PTY provider and hook receiver have either * started or failed open for the first BrowserWindow. */ awaitFirstWindowStartupServices: () => Promise @@ -1409,6 +1425,10 @@ export type PreloadApi = { worktreeId: string hostId?: ExecutionHostId force?: boolean + // Why (#11960): distinct from `force`, which the plain Delete confirmation + // already sets to skip the dirty-file prompt. Only an explicit Force Delete + // may waive the proof that every PTY stopped. + allowUnverifiedPtyStop?: boolean skipArchive?: boolean }) => Promise // Forget a workspace from Orca only (no remote Git/FS work) — for workspaces pinned to a removed/disconnected SSH host. @@ -2681,7 +2701,12 @@ export type PreloadApi = { quitAndInstall: () => Promise dismissNudge: () => Promise dismissAvailableUpdate: () => Promise + /** Desktop-only. Rejects unless the current status carries `linux-package-install` recovery. */ + getLinuxPackageInstallInstructions: () => Promise + /** Desktop-only. Reveals the revalidated cached package in the native file manager. */ + showLinuxPackage: () => Promise listBuilds: (channel: ReleaseChannel) => Promise + onStatus: (callback: (status: UpdateStatus) => void) => () => void onClearDismissal: (callback: () => void) => () => void } @@ -3406,6 +3431,8 @@ export type PreloadApi = { }) => Promise removeTarget: (args: { id: string }) => Promise importConfig: (args?: { reAdopt?: boolean }) => Promise + listConfigHosts: (args?: SshConfigHostListArgs) => Promise + resolveConfigHost: (args: { alias: string }) => Promise // `initiator: 'auto'` = Orca reconnecting on its own; only 'user' (the default) re-earns the // auto-reconnect budget that stops a down host from being retried forever. connect: (args: { @@ -3627,7 +3654,7 @@ export type PreloadApi = { > openWindowsNetworkSettings: () => Promise getRuntimePairingUrl: (args?: { address?: string; rotate?: boolean }) => Promise< - | { available: false } + | { available: false; reason?: 'network_exposure_failed'; guidance?: string } | { available: true pairingUrl: string diff --git a/src/preload/index.ts b/src/preload/index.ts index 217d0c2b760..ec99b4af6db 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -27,6 +27,9 @@ import type { VerifyAndAddRuntimeEnvironmentResult } from '../shared/remote-pair import type { SshMutationExpectation, SshConnectionState, + SshConfigHostListArgs, + SshConfigHostListResult, + SshConfigHostResolution, SshConfigImportResult, SshTargetAddResult, SshTarget, @@ -95,7 +98,8 @@ import type { WorktreeBaseStatusEvent, WorktreeDefaultTabsLaunch, WorktreeHeadIdentity, - WorktreeRemoteBranchConflictEvent + WorktreeRemoteBranchConflictEvent, + WorktreeSetupLaunch } from '../shared/types' import type { PtyModelRestoreNeededEvent } from '../shared/pty-model-restore-marker' import type { PtyListedSession } from '../shared/pty-listed-session' @@ -286,6 +290,17 @@ import { registerRendererRestartIpcRelays } from './renderer-restart-wiring' +// Why: the sync checkpoint only stages; this joins its durable write so a +// navigating path can abort instead of losing the staged session. +async function awaitBeforeUnloadCheckpoint(): Promise { + const result = (await ipcRenderer.invoke('app:await-before-unload-checkpoint')) as { + ok?: unknown + } + if (result?.ok !== true) { + throw new Error('Failed to persist renderer state before unload.') + } +} + type NativeFileDropCallback = (data: NativeFileDropPayload) => void const nativeFileDropCallbacks: NativeFileDropCallback[] = [] @@ -475,7 +490,8 @@ const api = { restart: async (): Promise => { await prepareRendererForAppRestart(window, { startedEventName: ORCA_APP_RESTART_STARTED_EVENT, - abortedEventName: ORCA_APP_RESTART_ABORTED_EVENT + abortedEventName: ORCA_APP_RESTART_ABORTED_EVENT, + awaitCheckpoint: awaitBeforeUnloadCheckpoint }) try { return await ipcRenderer.invoke('app:restart') @@ -2435,6 +2451,17 @@ const api = { webContentsId: number }): Promise => ipcRenderer.invoke('browser:registerGuest', args), + isGuestRegistered: (args: { browserPageId: string; webContentsId: number }): Promise => + ipcRenderer.invoke('browser:isGuestRegistered', args), + + repairGuestRegistration: (args: { + browserPageId: string + workspaceId: string + worktreeId: string + sessionProfileId?: string | null + webContentsId: number + }): Promise => ipcRenderer.invoke('browser:repairGuestRegistration', args), + unregisterGuest: (args: { browserPageId: string }): Promise => ipcRenderer.invoke('browser:unregisterGuest', args), @@ -2868,8 +2895,7 @@ const api = { repoId: string worktreePath: string command: string - }): Promise<{ runnerScriptPath: string; envVars: Record }> => - ipcRenderer.invoke('hooks:createIssueCommandRunner', args), + }): Promise => ipcRenderer.invoke('hooks:createIssueCommandRunner', args), readIssueCommand: (args: { repoId: string @@ -2955,11 +2981,18 @@ const api = { download: () => ipcRenderer.invoke('updater:download'), dismissNudge: () => ipcRenderer.invoke('updater:dismissNudge'), dismissAvailableUpdate: () => ipcRenderer.invoke('updater:dismissAvailableUpdate'), + getLinuxPackageInstallInstructions: () => + ipcRenderer.invoke('updater:getLinuxPackageInstallInstructions'), + showLinuxPackage: () => ipcRenderer.invoke('updater:showLinuxPackage'), listBuilds: (channel) => ipcRenderer.invoke('updater:listBuilds', channel), quitAndInstall: (): Promise => - prepareAndInvokeUpdaterInstall(window, updaterQuitAbortRelay, () => - ipcRenderer.invoke('updater:quitAndInstall') + prepareAndInvokeUpdaterInstall( + window, + updaterQuitAbortRelay, + () => ipcRenderer.invoke('updater:quitAndInstall'), + awaitBeforeUnloadCheckpoint ), + onStatus: (callback) => { const listener = (_event: Electron.IpcRendererEvent, status: UpdateStatus) => callback(status) ipcRenderer.on('updater:status', listener) @@ -3685,7 +3718,7 @@ const api = { callback: (data: { repoId: string worktreeId: string - setup?: { runnerScriptPath: string; envVars: Record } + setup?: WorktreeSetupLaunch startup?: { command: string; env?: Record } defaultTabs?: WorktreeDefaultTabsLaunch }) => void @@ -3695,7 +3728,7 @@ const api = { data: { repoId: string worktreeId: string - setup?: { runnerScriptPath: string; envVars: Record } + setup?: WorktreeSetupLaunch startup?: { command: string; env?: Record } defaultTabs?: WorktreeDefaultTabsLaunch } @@ -4149,6 +4182,8 @@ const api = { aiVault: { listSessions: (args?: AiVaultListArgs): Promise => ipcRenderer.invoke('aiVault:listSessions', args), + cancelListSessions: (args: { requestToken: string }): Promise => + ipcRenderer.invoke('aiVault:cancelListSessions', args), prepareSessionResume: (args: AiVaultPrepareSessionResumeArgs): Promise => ipcRenderer.invoke('aiVault:prepareSessionResume', args), listSubagentSessions: (args: AiVaultSubagentListArgs): Promise => @@ -4395,6 +4430,12 @@ const api = { importConfig: (args?: { reAdopt?: boolean }): Promise => ipcRenderer.invoke('ssh:importConfig', args), + listConfigHosts: (args?: SshConfigHostListArgs): Promise => + ipcRenderer.invoke('ssh:listConfigHosts', args), + + resolveConfigHost: (args: { alias: string }): Promise => + ipcRenderer.invoke('ssh:resolveConfigHost', args), + // Why: `initiator: 'auto'` marks connects Orca issues on its own (pane remounts, automations). // Only a user-initiated connect re-earns the auto-reconnect budget; defaulting to 'user' keeps // every unmarked caller on the pre-existing behavior. @@ -4620,7 +4661,7 @@ const api = { address?: string rotate?: boolean }): Promise< - | { available: false } + | { available: false; reason?: 'network_exposure_failed'; guidance?: string } | { available: true pairingUrl: string diff --git a/src/preload/renderer-restart-wiring.test.ts b/src/preload/renderer-restart-wiring.test.ts index 56cd5d3dd9e..0198c72a44f 100644 --- a/src/preload/renderer-restart-wiring.test.ts +++ b/src/preload/renderer-restart-wiring.test.ts @@ -44,10 +44,27 @@ describe('renderer restart wiring', () => { throw new Error('IPC failed') }) - await expect(prepareAndInvokeUpdaterInstall(eventTarget, relay, invoke)).rejects.toThrow( - 'IPC failed' - ) + await expect( + prepareAndInvokeUpdaterInstall(eventTarget, relay, invoke, async () => { + calls.push('checkpoint-flushed') + }) + ).rejects.toThrow('IPC failed') - expect(calls).toEqual(['prepared', 'marked', 'invoked', 'aborted']) + expect(calls).toEqual(['prepared', 'checkpoint-flushed', 'marked', 'invoked', 'aborted']) + }) + + it('never installs the update when the shutdown checkpoint fails to persist', async () => { + const eventTarget = new EventTarget() + const invoke = vi.fn(() => Promise.resolve()) + const relay = { markPrepared: vi.fn(), abort: vi.fn() } + + await expect( + prepareAndInvokeUpdaterInstall(eventTarget, relay, invoke, () => + Promise.reject(new Error('Failed to persist renderer state before unload.')) + ) + ).rejects.toThrow('Failed to persist renderer state before unload.') + + expect(invoke).not.toHaveBeenCalled() + expect(relay.markPrepared).not.toHaveBeenCalled() }) }) diff --git a/src/preload/renderer-restart-wiring.ts b/src/preload/renderer-restart-wiring.ts index fbd3e26a71d..254d386403a 100644 --- a/src/preload/renderer-restart-wiring.ts +++ b/src/preload/renderer-restart-wiring.ts @@ -26,11 +26,13 @@ export function registerRendererRestartIpcRelays( export async function prepareAndInvokeUpdaterInstall( eventTarget: EventTarget, relay: Pick, - invoke: () => Promise + invoke: () => Promise, + awaitCheckpoint: () => Promise ): Promise { await prepareRendererForAppRestart(eventTarget, { startedEventName: ORCA_UPDATER_QUIT_AND_INSTALL_STARTED_EVENT, - abortedEventName: ORCA_UPDATER_QUIT_AND_INSTALL_ABORTED_EVENT + abortedEventName: ORCA_UPDATER_QUIT_AND_INSTALL_ABORTED_EVENT, + awaitCheckpoint }) relay.markPrepared() try { diff --git a/src/preload/updater-package-recovery.test.ts b/src/preload/updater-package-recovery.test.ts new file mode 100644 index 00000000000..b28d4632f60 --- /dev/null +++ b/src/preload/updater-package-recovery.test.ts @@ -0,0 +1,93 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { PreloadApi } from './api-types' + +const { exposeInMainWorld, invoke, on, removeListener, send, sendSync } = vi.hoisted(() => ({ + exposeInMainWorld: vi.fn(), + invoke: vi.fn(), + on: vi.fn(), + removeListener: vi.fn(), + send: vi.fn(), + sendSync: vi.fn() +})) + +vi.mock('electron', () => ({ + contextBridge: { exposeInMainWorld }, + ipcRenderer: { invoke, on, removeListener, send, sendSync }, + webFrame: { + getZoomFactor: vi.fn(() => 1), + setZoomFactor: vi.fn(), + setVisualZoomLevelLimits: vi.fn() + }, + webUtils: { getPathForFile: vi.fn(() => '') } +})) + +vi.mock('@electron-toolkit/preload', () => ({ electronAPI: {} })) + +describe('native preload linux package recovery methods', () => { + const originalContextIsolated = Object.getOwnPropertyDescriptor(process, 'contextIsolated') + + beforeEach(() => { + vi.resetModules() + exposeInMainWorld.mockReset() + invoke.mockReset() + on.mockReset() + removeListener.mockReset() + send.mockReset() + sendSync.mockReset() + Object.defineProperty(process, 'contextIsolated', { configurable: true, value: true }) + vi.stubGlobal('window', { + addEventListener: vi.fn(), + dispatchEvent: vi.fn(), + removeEventListener: vi.fn() + }) + vi.stubGlobal('document', { addEventListener: vi.fn() }) + }) + + afterEach(() => { + vi.unstubAllGlobals() + if (originalContextIsolated) { + Object.defineProperty(process, 'contextIsolated', originalContextIsolated) + } else { + Reflect.deleteProperty(process, 'contextIsolated') + } + }) + + const loadApi = async (): Promise => { + await import('./index') + return exposeInMainWorld.mock.calls.find(([name]) => name === 'api')?.[1] as PreloadApi + } + + it('invokes only the instructions channel and returns the main-built command', async () => { + const api = await loadApi() + invoke.mockResolvedValueOnce({ + command: "sudo apt install -- '/cache/orca.deb'", + packageFileName: 'orca.deb' + }) + invoke.mockClear() + + await expect(api.updater.getLinuxPackageInstallInstructions()).resolves.toEqual({ + command: "sudo apt install -- '/cache/orca.deb'", + packageFileName: 'orca.deb' + }) + + // Why: the renderer must never reach a generic shell/path channel for this cache artifact. + expect(invoke.mock.calls).toEqual([['updater:getLinuxPackageInstallInstructions']]) + }) + + it('invokes only the show-package channel', async () => { + const api = await loadApi() + invoke.mockResolvedValueOnce(undefined) + invoke.mockClear() + + await expect(api.updater.showLinuxPackage()).resolves.toBeUndefined() + + expect(invoke.mock.calls).toEqual([['updater:showLinuxPackage']]) + }) + + it('surfaces a main-process validation rejection to the caller', async () => { + const api = await loadApi() + invoke.mockRejectedValueOnce(new Error('hash mismatch')) + + await expect(api.updater.getLinuxPackageInstallInstructions()).rejects.toThrow('hash mismatch') + }) +}) diff --git a/src/relay/ai-vault-handler.test.ts b/src/relay/ai-vault-handler.test.ts new file mode 100644 index 00000000000..6a04b5a0bd5 --- /dev/null +++ b/src/relay/ai-vault-handler.test.ts @@ -0,0 +1,260 @@ +import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { afterEach, describe, expect, it, vi } from 'vitest' +import type { AiVaultListResult } from '../shared/ai-vault-types' +import { SSH_AI_VAULT_LIST_SESSIONS_METHOD } from '../shared/ssh-ai-vault-relay' +import { getRemoteHostPlatform } from '../main/ssh/ssh-remote-platform' +import type { RelayDispatcher, RequestContext } from './dispatcher' +import { AiVaultHandler } from './ai-vault-handler' + +type RequestHandler = (params: Record, context: RequestContext) => Promise + +const temporaryHomes: string[] = [] + +afterEach(async () => { + await Promise.all( + temporaryHomes.splice(0).map((path) => rm(path, { recursive: true, force: true })) + ) +}) + +describe('AiVaultHandler', () => { + it('discovers and parses sessions entirely on the relay host', async () => { + const remoteHome = await makeTemporaryHome() + const transcriptPath = join( + remoteHome, + '.codex', + 'sessions', + '2026', + '07', + '26', + 'rollout-test.jsonl' + ) + await mkdir(dirname(transcriptPath), { recursive: true }) + await writeFile( + transcriptPath, + [ + JSON.stringify({ + timestamp: '2026-07-26T01:00:00.000Z', + type: 'session_meta', + payload: { id: 'ssh-session', cwd: join(remoteHome, 'repo') } + }), + JSON.stringify({ + timestamp: '2026-07-26T01:00:01.000Z', + type: 'response_item', + payload: { + type: 'message', + role: 'user', + content: [{ type: 'text', text: 'Scan on the SSH target' }] + } + }) + ].join('\n') + ) + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome, + hostPlatform: getRemoteHostPlatform('linux-x64') + }) + + const result = (await dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { + limit: 20 + })) as AiVaultListResult + + expect(result.issues).toEqual([]) + expect(result.sessions).toHaveLength(1) + expect(result.sessions[0]).toMatchObject({ + executionHostId: 'local', + executionHostPlatform: 'linux', + sessionId: 'ssh-session', + title: 'Scan on the SSH target', + filePath: transcriptPath + }) + }) + + it('bounds relay scan parameters before touching the target filesystem', async () => { + const scanRemoteSessions = vi.fn().mockResolvedValue(emptyResult()) + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + scanRemoteSessions + }) + const scopePaths = Array.from({ length: 80 }, (_, index) => `/repo/${index}`) + + await dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { + limit: 50_000, + scopePaths + }) + + expect(scanRemoteSessions).toHaveBeenCalledWith( + expect.objectContaining({ + executionHostId: 'local', + limit: 1000, + scopePaths: scopePaths.slice(0, 64) + }) + ) + const result = (await dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { + scopePaths + })) as AiVaultListResult + expect(result.issues).toContainEqual( + expect.objectContaining({ + kind: 'scope', + message: expect.stringContaining('first 64 project paths') + }) + ) + }) + + it('forwards Unlimited without the relay numeric cap', async () => { + const scanRemoteSessions = vi.fn().mockResolvedValue(emptyResult()) + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + scanRemoteSessions + }) + + await dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { + limit: 50_000, + unlimited: true + }) + + expect(scanRemoteSessions).toHaveBeenCalledWith( + expect.objectContaining({ limit: undefined, unlimited: true }) + ) + }) + + it('coalesces identical in-flight scans without coupling caller cancellation', async () => { + let resolveScan: ((result: AiVaultListResult) => void) | undefined + let sharedSignal: AbortSignal | undefined + const scanRemoteSessions = vi.fn( + (args: { signal?: AbortSignal }) => + new Promise((resolve) => { + sharedSignal = args.signal + resolveScan = resolve + }) + ) + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + scanRemoteSessions: scanRemoteSessions as never + }) + const firstController = new AbortController() + const first = dispatcher.call( + SSH_AI_VAULT_LIST_SESSIONS_METHOD, + { limit: 20 }, + firstController.signal + ) + const second = dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { limit: 20 }) + await vi.waitFor(() => expect(scanRemoteSessions).toHaveBeenCalledTimes(1)) + + firstController.abort() + await expect(first).rejects.toMatchObject({ name: 'AbortError' }) + expect(sharedSignal?.aborted).toBe(false) + + resolveScan?.(emptyResult()) + await expect(second).resolves.toEqual(emptyResult()) + }) + + it('re-joins a preempted relay caller onto the forced refresh', async () => { + const signals: AbortSignal[] = [] + let resolveForced: ((result: AiVaultListResult) => void) | undefined + const scanRemoteSessions = vi.fn((args: { signal: AbortSignal }) => { + signals.push(args.signal) + return new Promise((resolve) => { + if (signals.length === 1) { + args.signal.addEventListener('abort', () => resolve(emptyResult()), { once: true }) + } else { + resolveForced = resolve + } + }) + }) + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64'), + scanRemoteSessions: scanRemoteSessions as never + }) + const first = dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { limit: 20 }) + await vi.waitFor(() => expect(signals).toHaveLength(1)) + + const forced = dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, { + limit: 20, + force: true + }) + await vi.waitFor(() => expect(signals).toHaveLength(2)) + + expect(signals[0]?.aborted).toBe(true) + resolveForced?.(emptyResult()) + // The desktop caller that did not ask for a refresh still gets sessions. + await expect(Promise.all([first, forced])).resolves.toEqual([emptyResult(), emptyResult()]) + }) + + it('soft-disables the method instead of aborting relay startup on an unsupported platform', () => { + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { value: 'freebsd', configurable: true }) + const stderr = vi.spyOn(process.stderr, 'write').mockReturnValue(true) + try { + const dispatcher = createMockDispatcher() + + expect(() => new AiVaultHandler(dispatcher.value)).not.toThrow() + + expect(() => dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, {})).toThrow(/No handler/) + } finally { + stderr.mockRestore() + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + }) + + it('stops a relay-local scan when the owning request is cancelled', async () => { + const dispatcher = createMockDispatcher() + new AiVaultHandler(dispatcher.value, { + remoteHome: '/home/ada', + hostPlatform: getRemoteHostPlatform('linux-x64') + }) + const controller = new AbortController() + controller.abort() + + await expect( + dispatcher.call(SSH_AI_VAULT_LIST_SESSIONS_METHOD, {}, controller.signal) + ).rejects.toMatchObject({ name: 'AbortError' }) + }) +}) + +async function makeTemporaryHome(): Promise { + const path = await mkdtemp(join(tmpdir(), 'orca-relay-ai-vault-')) + temporaryHomes.push(path) + return path +} + +function emptyResult(): AiVaultListResult { + return { sessions: [], issues: [], scannedAt: '2026-07-26T00:00:00.000Z' } +} + +function createMockDispatcher(): { + value: RelayDispatcher + call: (method: string, params: Record, signal?: AbortSignal) => Promise +} { + const handlers = new Map() + const value = { + onRequest(method: string, handler: RequestHandler) { + handlers.set(method, handler) + } + } as RelayDispatcher + return { + value, + call(method, params, signal) { + const handler = handlers.get(method) + if (!handler) { + throw new Error(`No handler for ${method}`) + } + return handler(params, { + clientId: 1, + isStale: () => signal?.aborted ?? false, + signal + }) + } + } +} diff --git a/src/relay/ai-vault-handler.ts b/src/relay/ai-vault-handler.ts new file mode 100644 index 00000000000..80feae8ea8c --- /dev/null +++ b/src/relay/ai-vault-handler.ts @@ -0,0 +1,159 @@ +import { lstat, readdir } from 'node:fs/promises' +import { homedir } from 'node:os' +import { AI_VAULT_SCOPE_PATHS_MAX_COUNT, type AiVaultListResult } from '../shared/ai-vault-types' +import { LOCAL_EXECUTION_HOST_ID } from '../shared/execution-host' +import { + SSH_AI_VAULT_LIST_LIMIT_MAX, + SSH_AI_VAULT_LIST_SESSIONS_METHOD, + SSH_AI_VAULT_SCOPE_PATH_MAX_LENGTH, + type SshAiVaultRelayListParams +} from '../shared/ssh-ai-vault-relay' +import { scanRemoteAiVaultSessions } from '../main/ai-vault/remote-session-scanner' +import type { RemoteSessionFilesystemProvider } from '../main/ai-vault/remote-session-scanner-types' +import { getRemoteHostPlatform, type RemoteHostPlatform } from '../main/ssh/ssh-remote-platform' +import { parseUnameToRelayPlatform } from '../main/ssh/relay-protocol' +import { readRelayFileContent } from './fs-handler-file-read' +import { relayLogLine } from './relay-diagnostic-log' +import type { RelayDispatcher } from './dispatcher' +import { AiVaultScanCoordinator } from '../main/ai-vault/ai-vault-scan-coordinator' + +type ScanRemoteSessions = typeof scanRemoteAiVaultSessions + +type AiVaultHandlerOptions = { + remoteHome?: string + hostPlatform?: RemoteHostPlatform + scanRemoteSessions?: ScanRemoteSessions +} + +export class AiVaultHandler { + private readonly remoteHome: string + private readonly scanRemoteSessions: ScanRemoteSessions + private readonly provider: RemoteSessionFilesystemProvider + private readonly scanCoordinator = new AiVaultScanCoordinator() + + constructor(dispatcher: RelayDispatcher, options: AiVaultHandlerOptions = {}) { + this.remoteHome = options.remoteHome ?? homedir() + this.scanRemoteSessions = options.scanRemoteSessions ?? scanRemoteAiVaultSessions + this.provider = createRelayAiVaultFilesystemProvider() + const hostPlatform = options.hostPlatform ?? currentRelayHostPlatform() + // Why: an OS/arch this build has no path flavor for must not abort relay + // startup — leaving the method unregistered soft-disables the feature and + // the host falls back to its own SSH filesystem scan. + if (!hostPlatform) { + relayLogLine( + `[relay] Agent Session History disabled: unsupported platform ${process.platform}-${process.arch}` + ) + return + } + dispatcher.onRequest(SSH_AI_VAULT_LIST_SESSIONS_METHOD, (params, context) => + this.listSessions(hostPlatform, params, context.signal) + ) + } + + private async listSessions( + hostPlatform: RemoteHostPlatform, + rawParams: Record, + signal?: AbortSignal + ): Promise { + const params = normalizeSshAiVaultRelayListParams(rawParams) + const result = await this.scanCoordinator.run({ + key: JSON.stringify({ + limit: params.limit, + unlimited: params.unlimited, + scopePaths: params.scopePaths, + scopePathsTruncated: params.scopePathsTruncated + }), + force: params.force, + signal, + start: (scanSignal) => + this.scanRemoteSessions({ + provider: this.provider, + executionHostId: LOCAL_EXECUTION_HOST_ID, + remoteHome: this.remoteHome, + hostPlatform, + limit: params.limit, + unlimited: params.unlimited, + scopePaths: params.scopePaths, + signal: scanSignal + }) + }) + if (!params.scopePathsTruncated) { + return result + } + return { + ...result, + issues: [ + ...result.issues, + { + executionHostId: LOCAL_EXECUTION_HOST_ID, + agent: 'codex', + kind: 'scope', + path: this.remoteHome, + message: `Only the first ${AI_VAULT_SCOPE_PATHS_MAX_COUNT} project paths were scanned.` + } + ] + } + } +} + +export function normalizeSshAiVaultRelayListParams( + params: Record +): SshAiVaultRelayListParams { + const rawLimit = params.limit + const unlimited = params.unlimited === true + const limit = + !unlimited && typeof rawLimit === 'number' && Number.isFinite(rawLimit) && rawLimit > 0 + ? Math.min(Math.floor(rawLimit), SSH_AI_VAULT_LIST_LIMIT_MAX) + : undefined + const scopePaths = Array.isArray(params.scopePaths) + ? params.scopePaths + .slice(0, AI_VAULT_SCOPE_PATHS_MAX_COUNT) + .filter( + (path): path is string => + typeof path === 'string' && + path.trim().length > 0 && + path.length <= SSH_AI_VAULT_SCOPE_PATH_MAX_LENGTH + ) + : undefined + const scopePathsTruncated = + params.scopePathsTruncated === true || + (Array.isArray(params.scopePaths) && params.scopePaths.length > AI_VAULT_SCOPE_PATHS_MAX_COUNT) + return { + ...(unlimited ? { unlimited: true } : {}), + ...(limit === undefined ? {} : { limit }), + ...(params.force === true ? { force: true } : {}), + ...(scopePaths === undefined ? {} : { scopePaths }), + ...(scopePathsTruncated ? { scopePathsTruncated: true } : {}) + } +} + +function currentRelayHostPlatform(): RemoteHostPlatform | null { + const relayPlatform = parseUnameToRelayPlatform(process.platform, process.arch) + return relayPlatform ? getRemoteHostPlatform(relayPlatform) : null +} + +function createRelayAiVaultFilesystemProvider(): RemoteSessionFilesystemProvider { + return { + async readDir(dirPath) { + const entries = await readdir(dirPath, { withFileTypes: true }) + return entries.map((entry) => ({ + name: entry.name, + isDirectory: entry.isDirectory(), + isSymlink: entry.isSymbolicLink() + })) + }, + readFile: readRelayFileContent, + async stat(filePath) { + const stats = await lstat(filePath) + return { + size: stats.size, + type: stats.isDirectory() ? 'directory' : stats.isSymbolicLink() ? 'symlink' : 'file', + mtime: stats.mtimeMs, + mtimeMs: stats.mtimeMs, + dev: stats.dev, + ino: stats.ino, + nlink: stats.nlink + } + } + } +} diff --git a/src/relay/git-handler.ts b/src/relay/git-handler.ts index c574e7aaa62..6674500c6f9 100644 --- a/src/relay/git-handler.ts +++ b/src/relay/git-handler.ts @@ -383,7 +383,7 @@ export class GitHandler { // Why: pointer/range probes are part of the same SSH request and must not outlive its cancellation. const requestGit: GitExec = (args, cwd, options) => this.git(args, cwd, { ...options, signal: context.signal }) - // Why: moved clean gitlinks need committed changes surfaced. + // Why: moved clean gitlinks need committed changes surfaced. const { fromOid, toOid } = await resolveSubmoduleCommitRange( requestGit, worktreePath, @@ -775,7 +775,7 @@ export class GitHandler { private async branchCompare(params: Record) { const worktreePath = params.worktreePath as string const baseRef = params.baseRef as string - // Why: reject flag-like base refs to prevent rev-parse option injection. + // Why: reject flag-like base refs to prevent rev-parse option injection. if (baseRef.startsWith('-')) { throw new Error('Base ref must not start with "-"') } diff --git a/src/relay/pty-handler.test.ts b/src/relay/pty-handler.test.ts index 1c1ff41328d..35d11461c53 100644 --- a/src/relay/pty-handler.test.ts +++ b/src/relay/pty-handler.test.ts @@ -34,6 +34,10 @@ vi.mock('node-pty', () => ({ spawn: mockPtySpawn })) +vi.mock('../main/pty/posix-pty-process-groups', () => ({ + forceKillPosixPtyProcessGroups: vi.fn((_pid: number, fallback: () => void) => fallback()) +})) + import { IMMEDIATE_PTY_EXIT_TIMEOUT_MS, MAX_RELAY_PTY_SESSIONS, @@ -102,6 +106,7 @@ function createMockDispatcher() { describe('PtyHandler', () => { let dispatcher: ReturnType let handler: PtyHandler + let originalPlatform: PropertyDescriptor | undefined async function spawnPty( params: Record = {} @@ -122,6 +127,8 @@ describe('PtyHandler', () => { } beforeEach(() => { + originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { configurable: true, value: 'linux' }) vi.useFakeTimers() mockPtySpawn.mockReset() mockPtyInstance.onData.mockReset() @@ -132,6 +139,7 @@ describe('PtyHandler', () => { mockPtyInstance.clear.mockReset() mockPtyInstance.pause.mockReset() mockPtyInstance.resume.mockReset() + vi.spyOn(ptyShellUtils, 'processHasChildren').mockResolvedValue(false) mockPtySpawn.mockReturnValue({ ...mockPtyInstance }) @@ -144,6 +152,10 @@ describe('PtyHandler', () => { await vi.runAllTimersAsync() await cleanup.catch(() => {}) vi.useRealTimers() + vi.restoreAllMocks() + if (originalPlatform) { + Object.defineProperty(process, 'platform', originalPlatform) + } }) it('registers all expected handlers', () => { @@ -687,6 +699,60 @@ describe('PtyHandler', () => { } }) + // Why: both spellings classify as a POSIX startup family, so the relay must not be the one host + // that hard-fails a setting the local and daemon PTYs accept. + it.each(['bash', 'bash.exe'])( + 'accepts the %s shell override and routes it through Git Bash resolution', + async (shellOverride) => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { + configurable: true, + value: 'win32' + }) + const resolveGitBashSpy = vi + .spyOn(gitBash, 'resolveWindowsGitBashShellPath') + .mockReturnValue('C:\\Program Files\\Git\\bin\\bash.exe') + try { + await dispatcher.callRequest('pty.spawn', { cols: 80, rows: 24, shellOverride }) + + expect(resolveGitBashSpy).toHaveBeenCalledWith(shellOverride) + expect(mockPtySpawn).toHaveBeenCalledWith( + 'C:\\Program Files\\Git\\bin\\bash.exe', + expect.any(Array), + expect.any(Object) + ) + } finally { + resolveGitBashSpy.mockRestore() + Object.defineProperty(process, 'platform', { + configurable: true, + value: originalPlatform + }) + } + } + ) + + it('falls back to the literal bash override when Git Bash is not installed', async () => { + const originalPlatform = process.platform + Object.defineProperty(process, 'platform', { + configurable: true, + value: 'win32' + }) + const resolveGitBashSpy = vi + .spyOn(gitBash, 'resolveWindowsGitBashShellPath') + .mockReturnValue(null) + try { + await dispatcher.callRequest('pty.spawn', { cols: 80, rows: 24, shellOverride: 'bash' }) + + expect(mockPtySpawn).toHaveBeenCalledWith('bash', expect.any(Array), expect.any(Object)) + } finally { + resolveGitBashSpy.mockRestore() + Object.defineProperty(process, 'platform', { + configurable: true, + value: originalPlatform + }) + } + }) + it('resolves the Git Bash sentinel to the remote bash.exe path on Windows', async () => { const originalPlatform = process.platform Object.defineProperty(process, 'platform', { @@ -2503,6 +2569,27 @@ describe('PtyHandler', () => { expect(spawnEnv.env.TERM_PROGRAM).toBe('Orca') }) + it('expands variables in PATH before spawning a Windows relay shell', async () => { + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' }) + + try { + await dispatcher.callRequest('pty.spawn', { + env: { + ORCA_PATH_ROOT: 'C:\\Users\\orca\\AppData\\Local', + PATH: '%orca_path_root%\\agy\\bin;C:\\Windows' + } + }) + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + const spawnEnv = mockPtySpawn.mock.calls[0][2] as { env: Record } + expect(spawnEnv.env.PATH).toBe('C:\\Users\\orca\\AppData\\Local\\agy\\bin;C:\\Windows') + }) + it('uses the safe terminal default when TERM is deleted without a custom value', async () => { await dispatcher.callRequest('pty.spawn', { envToDelete: ['TERM'] diff --git a/src/relay/pty-handler.ts b/src/relay/pty-handler.ts index 243cc758943..6e8116158b6 100644 --- a/src/relay/pty-handler.ts +++ b/src/relay/pty-handler.ts @@ -50,6 +50,7 @@ import { } from '../shared/pty-startup-ingress' import { resolvePtyOwnerBackend, type PtyOwnerBackend } from '../shared/pty-owner-backend' import { RecentPtyOutputBuffer } from '../main/runtime/recent-pty-output-buffer' +import { expandWindowsPathEnvironmentVariables } from '../shared/windows-environment-expansion' import { agentSessionOwnerBindingsEqual, ClaimedAgentPtyOwnerRegistry @@ -68,6 +69,7 @@ import { isAgentSessionSurfaceBinding, type AgentSessionOwnerBinding } from '../shared/agent-session-host-authority' +import { createPtySlaveEchoProbe, readPtySlavePath } from '../shared/pty-slave-line-discipline-echo' // Why: only Linux compiles node-pty (no prebuilt), so the build-tools remedy is a closable setup gap // there and wrong advice anywhere node-pty ships one. The relay only sees an unloadable binding, never @@ -263,6 +265,10 @@ const ALLOWED_WINDOWS_SHELL_OVERRIDES = new Set([ 'cmd', 'wsl.exe', 'wsl', + // Why: both spellings classify as a POSIX startup family, so rejecting them here made the relay + // the one host that hard-failed a setting the local and daemon PTYs accept. + 'bash.exe', + 'bash', WINDOWS_GIT_BASH_SHELL ]) @@ -609,6 +615,7 @@ export class PtyHandler { if (!result.TERM) { result.TERM = 'xterm-256color' } + expandWindowsPathEnvironmentVariables(result) return result } @@ -683,11 +690,13 @@ export class PtyHandler { : {} ) } + const echoProbe = createPtySlaveEchoProbe(readPtySlavePath(managed.pty)) managed.startupIngress ??= new PtyStartupIngress({ ...(managed.startupIngressIntent ? { intent: managed.startupIngressIntent } : {}), ownerBackend: managed.ownerBackend, write: (data) => managed.pty.write(data), - onEmission: emitIngressData + onEmission: emitIngressData, + ...(echoProbe ? { echoProbe } : {}) }) managed.pty.onData((data: string) => { const startup = managed.startupCommand diff --git a/src/relay/relay.ts b/src/relay/relay.ts index 4bfc8bf3e92..d5003bdf649 100644 --- a/src/relay/relay.ts +++ b/src/relay/relay.ts @@ -32,6 +32,7 @@ import { ExternalAutomationsHandler } from './external-automations-handler' import { PortScanHandler } from './port-scan-handler' import { AgentExecHandler } from './agent-exec-handler' import { WorkspaceSessionHandler } from './workspace-session-handler' +import { AiVaultHandler } from './ai-vault-handler' import { endpointDirForRelaySocket, RelayAgentHookServer } from './agent-hook-server' import { PluginOverlayManager } from './plugin-overlay' import { @@ -663,6 +664,9 @@ async function main(): Promise { const _workspaceSessionHandler = new WorkspaceSessionHandler(dispatcher) void _workspaceSessionHandler + const _aiVaultHandler = new AiVaultHandler(dispatcher) + void _aiVaultHandler + // Why: relay-hosted plugin provisioning is a later phase. Register the // enforcement boundary now with no consented identities or runtime services. registerRelayPluginHostCallHandlers( diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 29aa2971bc8..2518ed5f5d1 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -123,6 +123,8 @@ import { shouldPersistWorkspaceSession } from './lib/workspace-session' import { createSessionWriteSubscriber } from './lib/session-write-subscriber' +import { sweepRestoredCodexPanesForStaleAccounts } from './lib/codex-stale-pane-sweep' +import { installCodexDetachedPaneRestartExecutor } from '@/components/terminal-pane/codex-detached-pane-restart-scheduler' import { buildActiveViewUnloadPatch } from './lib/active-view-persist' import { buildWorkspaceSessionHostSnapshots, @@ -213,7 +215,7 @@ import { } from './components/terminal/background-terminal-worktree-mount' import { collectTerminalProviderSnapshotPtyIds, - synchronizeTerminalProviderSnapshotCapabilities + refreshTerminalProviderSnapshotCapabilities } from './components/terminal/terminal-provider-snapshot-capability' import { useRemoteRuntimeRecoveryTriggers } from './runtime/use-remote-runtime-recovery-triggers' @@ -1080,7 +1082,7 @@ function App(): React.JSX.Element { window.api.app.recoverLegacyWorkerTerminalsForRendererStartup() ) await timeRendererStartupStep('terminal-provider-snapshot-capabilities', () => { - return synchronizeTerminalProviderSnapshotCapabilities( + return refreshTerminalProviderSnapshotCapabilities( collectTerminalProviderSnapshotPtyIds(useAppStore.getState()) ) }) @@ -1091,6 +1093,9 @@ function App(): React.JSX.Element { await timeRendererStartupStep('recover-legacy-worker-terminals-post-reconnect', () => window.api.app.recoverLegacyWorkerTerminalsForRendererStartup() ) + // Why here: reconnect just published restored PTY ids; sweeping them now + // re-offers stale Codex panes whose tabs never mount this session. + sweepRestoredCodexPanesForStaleAccounts(useAppStore.getState()) syncZoomCSSVar() // Why (issue #1158): unlock the session writer only after hydration and all dependent steps succeeded, so a mid-startup throw can't serialize partially-mutated state to disk. actions.setHydrationSucceeded(true) @@ -1166,6 +1171,9 @@ function App(): React.JSX.Element { try { await window.api.app.awaitFirstWindowStartupServices() await window.api.app.recoverLegacyWorkerTerminalsForRendererStartup() + await refreshTerminalProviderSnapshotCapabilities( + collectTerminalProviderSnapshotPtyIds(useAppStore.getState()) + ) await actions.reconnectPersistedTerminals(abortController.signal) await window.api.app.recoverLegacyWorkerTerminalsForRendererStartup() } catch (reconnectErr) { @@ -1211,6 +1219,8 @@ function App(): React.JSX.Element { } }, []) + useEffect(() => installCodexDetachedPaneRestartExecutor(), []) + useEffect(() => { let previousKey = getRuntimeMobileSessionSyncKey(useAppStore.getState()) return useAppStore.subscribe((state, previousState) => { diff --git a/src/renderer/src/app-startup-routing.test.ts b/src/renderer/src/app-startup-routing.test.ts index bfe17737970..80bb0037eac 100644 --- a/src/renderer/src/app-startup-routing.test.ts +++ b/src/renderer/src/app-startup-routing.test.ts @@ -139,6 +139,10 @@ describe('renderer startup runtime routing', () => { 'window.api.app.recoverLegacyWorkerTerminalsForRendererStartup()', servicesIndex ) + const capabilityRefreshIndex = source.indexOf( + 'refreshTerminalProviderSnapshotCapabilities(', + preReconnectRecoveryIndex + ) const reconnectIndex = source.indexOf( 'actions.reconnectPersistedTerminals(abortController.signal)', preReconnectRecoveryIndex @@ -150,10 +154,40 @@ describe('renderer startup runtime routing', () => { expect(servicesIndex).toBeGreaterThanOrEqual(0) expect(preReconnectRecoveryIndex).toBeGreaterThan(servicesIndex) - expect(reconnectIndex).toBeGreaterThan(preReconnectRecoveryIndex) + expect(capabilityRefreshIndex).toBeGreaterThan(preReconnectRecoveryIndex) + expect(reconnectIndex).toBeGreaterThan(capabilityRefreshIndex) expect(postReconnectRecoveryIndex).toBeGreaterThan(reconnectIndex) }) + it('refreshes terminal snapshot capability before degraded reconnect', () => { + const source = readFileSync(join(process.cwd(), 'src/renderer/src/App.tsx'), 'utf8') + const degradedStart = source.indexOf( + '[startup] Workspace session hydration failed; leaving disk state untouched:' + ) + const servicesIndex = source.indexOf( + 'await window.api.app.awaitFirstWindowStartupServices()', + degradedStart + ) + const recoveryIndex = source.indexOf( + 'window.api.app.recoverLegacyWorkerTerminalsForRendererStartup()', + servicesIndex + ) + const capabilityRefreshIndex = source.indexOf( + 'refreshTerminalProviderSnapshotCapabilities(', + recoveryIndex + ) + const reconnectIndex = source.indexOf( + 'actions.reconnectPersistedTerminals(abortController.signal)', + recoveryIndex + ) + + expect(degradedStart).toBeGreaterThanOrEqual(0) + expect(servicesIndex).toBeGreaterThan(degradedStart) + expect(recoveryIndex).toBeGreaterThan(servicesIndex) + expect(capabilityRefreshIndex).toBeGreaterThan(recoveryIndex) + expect(reconnectIndex).toBeGreaterThan(capabilityRefreshIndex) + }) + it('keeps the persisted Automations view from starting its own bootstrap worktree scan', () => { const source = readFileSync( join(process.cwd(), 'src/renderer/src/components/automations/AutomationsPage.tsx'), diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index 315dd34c67a..47d81257dde 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -1455,6 +1455,26 @@ html.native-shell .app-layout { grid-template-rows: 1fr; } +/* Why: must stay a compositor-driven CSS animation — a JS clock writing + per-element transforms blocks the renderer input thread (STA-3328: 41 + spinners ⇒ ~490 style writes/s, keystroke p90 363ms). The component anchors + each animation's startTime once; steps(12) preserves the retired cadence. */ +@keyframes agent-spinner-rotate { + to { + transform: rotate(360deg); + } +} + +.agent-working-spinner { + animation: agent-spinner-rotate 1s steps(12, end) infinite; +} + +@media (prefers-reduced-motion: reduce) { + .agent-working-spinner { + animation: none; + } +} + /* Why: keyframes run when the content mounts already in its final state. */ @keyframes compact-agent-expansion-reveal { from { diff --git a/src/renderer/src/components/AgentStateDot.test.ts b/src/renderer/src/components/AgentStateDot.test.ts index 72fbc6223a6..b721c3d8a01 100644 --- a/src/renderer/src/components/AgentStateDot.test.ts +++ b/src/renderer/src/components/AgentStateDot.test.ts @@ -22,15 +22,13 @@ describe('AgentStateDot', () => { expect(markup).toContain('border-yellow-500') expect(markup).toContain('border-t-transparent') - // Why: rotation comes from the shared agent-spinner clock (which also - // honors prefers-reduced-motion), not a per-element CSS animation that - // would keep the compositor awake. + // Why: rotation must come from the compositor-driven CSS animation, not a + // JS clock writing per-element styles on the input thread (STA-3328). + expect(markup).toContain('agent-working-spinner') expect(markup).toContain('data-agent-spinner') // Why: under reduced motion the top border is filled so the static ring // reads as a complete marker, not a broken partial spinner (#9515). expect(markup).toContain('motion-reduce:border-t-yellow-500') - expect(markup).not.toContain('animate-spin') - expect(markup).not.toContain('animation:spin') }) it('renders done as an emerald check icon', () => { diff --git a/src/renderer/src/components/AgentWorkingSpinner.test.tsx b/src/renderer/src/components/AgentWorkingSpinner.test.tsx new file mode 100644 index 00000000000..25c04f39783 --- /dev/null +++ b/src/renderer/src/components/AgentWorkingSpinner.test.tsx @@ -0,0 +1,112 @@ +// @vitest-environment happy-dom + +import { readFileSync } from 'node:fs' +import { join } from 'node:path' +import React, { act } from 'react' +import { createRoot } from 'react-dom/client' +import { renderToStaticMarkup } from 'react-dom/server' +import { describe, expect, it, vi } from 'vitest' +import { AgentWorkingSpinner } from './AgentWorkingSpinner' + +globalThis.IS_REACT_ACT_ENVIRONMENT = true + +describe('AgentWorkingSpinner', () => { + it('hooks the compositor-driven CSS animation, not a JS clock', () => { + const markup = renderToStaticMarkup(React.createElement(AgentWorkingSpinner)) + + expect(markup).toContain('agent-working-spinner') + expect(markup).toContain('data-agent-spinner') + expect(markup).toContain('border-yellow-500') + expect(markup).toContain('border-t-transparent') + expect(markup).toContain('motion-reduce:border-t-yellow-500') + }) + + it('renders when the Web Animations API is unavailable', async () => { + const originalGetAnimations = Object.getOwnPropertyDescriptor( + HTMLElement.prototype, + 'getAnimations' + ) + Object.defineProperty(HTMLElement.prototype, 'getAnimations', { + configurable: true, + value: undefined + }) + const container = document.createElement('div') + document.body.appendChild(container) + const root = createRoot(container) + + try { + await act(async () => { + root.render() + }) + expect(container.querySelector('[data-agent-spinner]')).not.toBeNull() + } finally { + act(() => root.unmount()) + container.remove() + if (originalGetAnimations === undefined) { + Reflect.deleteProperty(HTMLElement.prototype, 'getAnimations') + } else { + Object.defineProperty(HTMLElement.prototype, 'getAnimations', originalGetAnimations) + } + } + }) + + it('anchors mount and restart animations to the shared document epoch', async () => { + const animation = { + animationName: 'agent-spinner-rotate', + startTime: 321 + } as unknown as Animation + const getAnimations = vi.fn(() => [animation]) + const originalGetAnimations = Object.getOwnPropertyDescriptor( + HTMLElement.prototype, + 'getAnimations' + ) + Object.defineProperty(HTMLElement.prototype, 'getAnimations', { + configurable: true, + value: getAnimations + }) + const container = document.createElement('div') + document.body.appendChild(container) + const root = createRoot(container) + + try { + await act(async () => { + root.render() + }) + expect(animation.startTime).toBe(0) + + animation.startTime = 654 + const restart = new Event('animationstart', { bubbles: true }) + Object.defineProperty(restart, 'animationName', { value: 'agent-spinner-rotate' }) + await act(async () => { + container.querySelector('[data-agent-spinner]')!.dispatchEvent(restart) + }) + expect(animation.startTime).toBe(0) + expect(getAnimations).toHaveBeenCalledTimes(2) + } finally { + act(() => root.unmount()) + container.remove() + if (originalGetAnimations === undefined) { + Reflect.deleteProperty(HTMLElement.prototype, 'getAnimations') + } else { + Object.defineProperty(HTMLElement.prototype, 'getAnimations', originalGetAnimations) + } + } + }) + + // Why: the class only spins if main.css defines it — pin the wiring across + // both files so neither side can be renamed or dropped alone (STA-3328 + // regressed typing latency when rotation moved onto the input thread). + it('is backed by a steps(12) keyframe animation in main.css', () => { + const css = readFileSync(join(__dirname, '../assets/main.css'), 'utf8') + + const rule = css.match(/\.agent-working-spinner\s*\{[^}]*\}/)?.[0] + expect(rule).toBeDefined() + expect(rule).toContain('animation: agent-spinner-rotate 1s steps(12, end) infinite') + expect(css).toContain('@keyframes agent-spinner-rotate') + + const reducedMotionBlock = css.match( + /@media \(prefers-reduced-motion: reduce\)\s*\{\s*\.agent-working-spinner\s*\{[^}]*\}/ + )?.[0] + expect(reducedMotionBlock).toContain('animation: none') + }) +}) diff --git a/src/renderer/src/components/AgentWorkingSpinner.tsx b/src/renderer/src/components/AgentWorkingSpinner.tsx index 7e3d3302a7e..9b20a862b09 100644 --- a/src/renderer/src/components/AgentWorkingSpinner.tsx +++ b/src/renderer/src/components/AgentWorkingSpinner.tsx @@ -1,21 +1,46 @@ import React from 'react' import { cn } from '@/lib/utils' -import { agentSpinnerRef } from '@/lib/agent-spinner-clock' -// Why: the working-state ring must not carry its own infinite CSS animation — -// that keeps the compositor awake per element for the whole agent run. The -// shared agent-spinner clock rotates every mounted ring in phase and stops -// cleanly when nothing can be seen. Callers size it via className (size-2 etc.). +const SPINNER_ANIMATION_NAME = 'agent-spinner-rotate' + +// Why: CSS assigns per-element start times after refs run; anchoring the Web +// Animation timeline gives late mounts exact phase sync without recurring JS. +function syncSpinnerPhase(el: HTMLSpanElement | null): void { + if (el === null || typeof el.getAnimations !== 'function') { + return + } + + const animation = el + .getAnimations() + .find( + (candidate) => + 'animationName' in candidate && candidate.animationName === SPINNER_ANIMATION_NAME + ) + if (animation !== undefined) { + animation.startTime = 0 + } +} + +function handleSpinnerAnimationStart(event: React.AnimationEvent): void { + if (event.animationName === SPINNER_ANIMATION_NAME) { + syncSpinnerPhase(event.currentTarget) + } +} + +// Why: the working-state ring animates via CSS (.agent-working-spinner in +// main.css) so rotation runs on the compositor and never touches the input +// thread. Callers size it via className (size-2 etc.). export function AgentWorkingSpinner({ className }: { className?: string }): React.JSX.Element { return ( diff --git a/src/renderer/src/components/CodexRestartChip.tsx b/src/renderer/src/components/CodexRestartChip.tsx index 4df9c54a9ed..09835b71302 100644 --- a/src/renderer/src/components/CodexRestartChip.tsx +++ b/src/renderer/src/components/CodexRestartChip.tsx @@ -1,70 +1,11 @@ -import { useEffect, useId, useMemo, useRef } from 'react' -import { useShallow } from 'zustand/react/shallow' +import { useEffect, useId, useRef } from 'react' import { RefreshCw } from 'lucide-react' import { Button } from '@/components/ui/button' import { useAppStore } from '../store' -import { selectCodexRestartInputs } from './codex-restart-chip-inputs' import { translate } from '@/i18n/i18n' import { shouldFocusMobileDriverAction } from './terminal-pane/mobile-driver-overlay-focus' import { buildCodexRestartNoticeKey } from './codex-restart-notice-key' import { awaitsCodexRestartAnswer } from './codex-restart-notice-state' -import type { CodexRestartNotice } from '../store/slices/terminals' - -const EMPTY_TABS: { id: string }[] = [] - -export function collectStalePtyIdsForTabs({ - tabs, - ptyIdsByTabId, - codexRestartNoticeByPtyId -}: { - tabs: { id: string }[] - ptyIdsByTabId: Record - codexRestartNoticeByPtyId: Record -}): string[] { - // Why: an already-requested restart runs when its pane next mounts. Keeping it - // out of the prompt is what stops the panel from sticking on a worktree whose - // stale pane is parked or deferred and cannot answer the request yet. A - // dismissed notice is likewise answered — it only survives as launch-account - // memory. - return tabs.flatMap((tab) => - (ptyIdsByTabId[tab.id] ?? []).filter((ptyId) => - awaitsCodexRestartAnswer(codexRestartNoticeByPtyId[ptyId]) - ) - ) -} - -export function collectStaleWorktreePtyIds({ - tabsByWorktree, - ptyIdsByTabId, - codexRestartNoticeByPtyId, - worktreeId -}: { - tabsByWorktree: Record - ptyIdsByTabId: Record - codexRestartNoticeByPtyId: Record - worktreeId: string -}): string[] { - return collectStalePtyIdsForTabs({ - tabs: tabsByWorktree[worktreeId] ?? EMPTY_TABS, - ptyIdsByTabId, - codexRestartNoticeByPtyId - }) -} - -export function dismissStaleWorktreePtyIds( - staleWorktreePtyIds: string[], - dismissCodexRestartNotices: (ptyIds: string[]) => void, - forgetLaunchAccounts: (ptyIds: string[]) => void -): void { - // Why: restart notices are stored per PTY, but the workspace host presents - // one shared prompt. Dismissing all matching PTY notices keeps every pane in - // that worktree consistent with the dismissal. - dismissCodexRestartNotices(staleWorktreePtyIds) - // Why: notices are renderer-only, so without dropping the on-disk launch - // record the startup sweep re-raises this exact prompt — and re-blocks the - // pane's input — after every app restart the user already answered. - forgetLaunchAccounts(staleWorktreePtyIds) -} function isInsideHiddenTree(element: HTMLElement): boolean { return element.closest('[aria-hidden="true"], [hidden], [inert]') !== null @@ -78,58 +19,39 @@ type RestartNotice = { export default function CodexRestartChip({ isVisible = true, - worktreeId + ptyId, + shouldFocus = false }: { isVisible?: boolean - worktreeId: string + ptyId: string + shouldFocus?: boolean }): React.JSX.Element | null { - const tabs = useAppStore((s) => s.tabsByWorktree[worktreeId] ?? EMPTY_TABS) - // Why: both of these maps churn on unrelated pty lifecycle events (ptyIdsByTabId - // on attach/detach; codexRestartNoticeByPtyId is re-spread even when empty on - // pty teardown), so subscribe to them only while a restart notice actually - // exists. Otherwise this per-worktree chip re-rendered on every pty event to - // compute "no notice → render nothing". See codex-restart-chip-inputs. - const { ptyIdsByTabId, codexRestartNoticeByPtyId } = useAppStore( - useShallow(selectCodexRestartInputs) - ) - const staleWorktreePtyIds = useMemo( - () => - collectStalePtyIdsForTabs({ - tabs, - ptyIdsByTabId, - codexRestartNoticeByPtyId - }), - [codexRestartNoticeByPtyId, ptyIdsByTabId, tabs] - ) - const restartNotice = staleWorktreePtyIds[0] - ? codexRestartNoticeByPtyId[staleWorktreePtyIds[0]] - : undefined - const queueCodexPaneRestarts = useAppStore((s) => s.queueCodexPaneRestarts) - const dismissCodexRestartNotices = useAppStore((s) => s.dismissCodexRestartNotices) - - const noticeKey = restartNotice ? buildCodexRestartNoticeKey(restartNotice) : null - - if (staleWorktreePtyIds.length === 0 || !restartNotice) { + // Why: one O(1) selector per mounted pane stays idle when unrelated PTY maps + // churn and prevents a worktree-wide scan for every split pane. + const restartNotice = useAppStore((state) => state.codexRestartNoticeByPtyId[ptyId]) + if (!restartNotice || !awaitsCodexRestartAnswer(restartNotice)) { return null } const handleRestart = (): void => { - queueCodexPaneRestarts(staleWorktreePtyIds) + useAppStore.getState().queueCodexPaneRestarts([ptyId]) } const handleDismiss = (): void => { - dismissStaleWorktreePtyIds(staleWorktreePtyIds, dismissCodexRestartNotices, (ptyIds) => { - void window.api.codexAccounts.forgetStalePanes({ ptyIds }).catch((err: unknown) => { - console.warn('Failed to forget dismissed Codex pane accounts:', err) - }) + useAppStore.getState().dismissCodexRestartNotices([ptyId]) + // Why: notices are renderer-only, so the persisted launch record must be + // cleared for this pane or the startup sweep re-raises its answered prompt. + void window.api.codexAccounts.forgetStalePanes({ ptyIds: [ptyId] }).catch((err: unknown) => { + console.warn('Failed to forget dismissed Codex pane account:', err) }) } return ( @@ -140,12 +62,14 @@ function LoudRestartOverlay({ isVisible, noticeKey, restartNotice, + shouldFocus, onDismiss, onRestart }: { isVisible: boolean noticeKey: string | null restartNotice: RestartNotice + shouldFocus: boolean onDismiss: () => void onRestart: () => void }): React.JSX.Element { @@ -156,15 +80,10 @@ function LoudRestartOverlay({ // Why: move focus to the card only when the user isn't typing elsewhere; // unconditional autoFocus would steal keys from an active composer. // - // The target is the dialog itself, never Restart. This card is mounted per - // WORKTREE (a sibling of the split layout), so its focus scope is every - // terminal in the worktree — a notice for one pane lands while the user may - // be typing in a different, perfectly healthy pane. With Restart focused, the - // next Space/Enter of their prose queued a restart of every stale pane here - // and destroyed those sessions. Focus must not land on a destructive action - // the user never aimed at. See #10863. + // The target is the dialog itself, never Restart, so the next Space/Enter + // cannot destroy a session the user did not explicitly choose. See #10863. useEffect(() => { - if (!isVisible) { + if (!isVisible || !shouldFocus) { return } const root = rootRef.current @@ -175,7 +94,7 @@ function LoudRestartOverlay({ if (shouldFocusMobileDriverAction(document.activeElement, document.body, paneScope)) { root.focus() } - }, [isVisible, noticeKey]) + }, [isVisible, noticeKey, shouldFocus]) return (
= {} +): LinuxPackageInstallRecovery { + return { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'package-install-failed', + version: '1.4.200', + ...overrides + } +} + +type CardOptions = { recovery?: LinuxPackageInstallRecovery; diagnostic?: string } + +function cardElement(options: CardOptions = {}): React.ReactElement { + return ( + + ) +} + +function renderCard(options: CardOptions = {}): RenderResult { + return render(cardElement(options)) +} + +/** + * Main force-sends a new recovery object on every attempt, which re-renders this card rather than + * remounting it. That push is the only signal a retry failed — quitAndInstall already resolved. + */ +function pushFreshRecovery(view: RenderResult, options: CardOptions = {}): void { + view.rerender(cardElement({ ...options, recovery: makeRecovery(options.recovery) })) +} + +// Why: each action chains several promises; drain them without depending on timer faking. +async function flushActions(): Promise { + await act(async () => { + for (let i = 0; i < 8; i += 1) { + await Promise.resolve() + } + }) +} + +function deferred(): { promise: Promise; resolve: (value: T) => void } { + let resolve!: (value: T) => void + const promise = new Promise((res) => { + resolve = res + }) + return { promise, resolve } +} + +function button(name: string): HTMLElement { + return screen.getByRole('button', { name }) +} + +/** The card marks busy actions with aria-disabled so pressed buttons keep focus. */ +function isAriaDisabled(element: HTMLElement): boolean { + return element.getAttribute('aria-disabled') === 'true' +} + +/** + * Trailing

of the actions column. It owns no live-region role of its own — the surrounding + * update Card is already aria-live, and nesting one inside another duplicates announcements. + */ +function footnoteElement(): HTMLElement | null { + const cardRoot = document.body.firstElementChild?.firstElementChild + const last = cardRoot?.lastElementChild?.lastElementChild + return last?.tagName === 'P' ? (last as HTMLElement) : null +} + +function footnoteText(): string | null { + return footnoteElement()?.textContent ?? null +} + +beforeEach(() => { + allMocks.forEach((mock) => mock.mockReset()) + getInstructions.mockResolvedValue(INSTRUCTIONS) + showLinuxPackage.mockResolvedValue(undefined) + quitAndInstall.mockResolvedValue(undefined) + writeClipboardText.mockResolvedValue(undefined) + Object.defineProperty(window, 'api', { + configurable: true, + value: { + shell: { openUrl }, + ui: { writeClipboardText }, + updater: { + getLinuxPackageInstallInstructions: getInstructions, + showLinuxPackage, + quitAndInstall + } + } + }) +}) + +afterEach(() => { + cleanup() + vi.restoreAllMocks() +}) + +describe('LinuxPackageInstallRecoveryCard copy', () => { + it('leads with the recovery copy and the three dedicated actions', () => { + renderCard() + + expect(screen.getByText('Automatic Install Failed')).toBeTruthy() + expect(screen.getByText(SUMMARY)).toBeTruthy() + expect( + screen.getByText(/a system terminal on the computer where Orca is installed/) + ).toBeTruthy() + expect(screen.getByText(/quit and reopen Orca to run the new version/)).toBeTruthy() + + expect(button('Copy Install Command')).toBeTruthy() + expect(button('Try Automatic Install Again')).toBeTruthy() + expect(button('Show Package')).toBeTruthy() + }) + + it('never offers the generic Retry Download action', () => { + renderCard() + + expect(screen.queryByRole('button', { name: 'Retry Download' })).toBeNull() + // The release fallback only appears once no command can be built. + expect(screen.queryByRole('button', { name: 'Download Manually' })).toBeNull() + }) + + it('minimizes to the status bar from the header control', () => { + renderCard() + + fireEvent.click(button('Minimize to status bar')) + expect(onClose).toHaveBeenCalledTimes(1) + }) +}) + +describe('LinuxPackageInstallRecoveryCard copy action', () => { + it('writes the main-generated command to the clipboard and confirms it', async () => { + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(1) + expect(writeClipboardText).toHaveBeenCalledWith(INSTALL_COMMAND) + // The confirmation names the artifact and never replaces the button's own label. + expect(footnoteText()).toBe(COPIED_NOTE) + expect(footnoteText()).toContain(PACKAGE_FILE_NAME) + expect(button('Copy Install Command')).toBeTruthy() + expect(screen.queryByRole('button', { name: 'Command copied' })).toBeNull() + }) + + it('announces through the card, not a nested live region', async () => { + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(footnoteText()).toBe(COPIED_NOTE) + expect(footnoteElement()?.hasAttribute('role')).toBe(false) + expect(screen.queryByRole('status')).toBeNull() + }) + + it('clears the confirmation when another action starts', async () => { + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + expect(footnoteText()).toBe(COPIED_NOTE) + + fireEvent.click(button('Show Package')) + await flushActions() + + expect(footnoteElement()).toBeNull() + }) + + it('clears the confirmation when the automatic install is retried', async () => { + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + expect(footnoteText()).toBe(COPIED_NOTE) + + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + + expect(quitAndInstall).toHaveBeenCalledTimes(1) + expect(footnoteElement()).toBeNull() + }) + + it('retires the copy confirmation after the transient window', async () => { + // Why: happy-dom's window timers escape Vitest's fake clock, so capture the scheduled callback. + const scheduled: { handler: () => void; delay?: number }[] = [] + vi.spyOn(window, 'setTimeout').mockImplementation(((handler: () => void, delay?: number) => { + scheduled.push({ handler, delay }) + return scheduled.length + }) as unknown as typeof window.setTimeout) + vi.spyOn(window, 'clearTimeout').mockImplementation(() => undefined) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + expect(footnoteText()).toBe(COPIED_NOTE) + + const expiry = scheduled.find((entry) => entry.delay === 4_000) + expect(expiry).toBeTruthy() + act(() => expiry?.handler()) + + expect(footnoteElement()).toBeNull() + expect(button('Copy Install Command')).toBeTruthy() + }) + + it('keeps the copy path when the instruction call rejects', async () => { + getInstructions.mockRejectedValue( + new Error( + "Error invoking remote method 'updater:getLinuxPackageInstallInstructions': " + + 'Error: Unauthorized updater package recovery sender' + ) + ) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + // Why: the Electron channel prefix must be stripped before the user sees the message. + expect(footnoteText()).toBe('Unauthorized updater package recovery sender') + expect(footnoteElement()?.className).toContain('text-destructive') + // Why: only main can rule out a command; a rejection must not push the 160 MB redownload. + expect(button('Copy Install Command').dataset.variant).toBe('default') + expect(screen.getByText(/Copy the command and run it/)).toBeTruthy() + expect(screen.queryByRole('button', { name: 'Download Manually' })).toBeNull() + expect(writeClipboardText).not.toHaveBeenCalled() + }) + + it('keeps the copy path when the artifact fails revalidation', async () => { + getInstructions.mockRejectedValue( + new Error('Error: The downloaded package no longer matches the verified release.') + ) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(footnoteText()).toBe('The downloaded package no longer matches the verified release.') + expect(screen.getByText('Automatic Install Failed')).toBeTruthy() + expect(button('Copy Install Command').dataset.variant).toBe('default') + expect(button('Show Package').dataset.variant).toBe('link') + }) + + it('retries the instruction call after a rejection', async () => { + getInstructions.mockRejectedValueOnce(new Error('Unauthorized updater package recovery sender')) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(2) + expect(footnoteText()).toBe(COPIED_NOTE) + }) + + it('keeps the copy path when only the clipboard write fails', async () => { + writeClipboardText.mockRejectedValue(new Error('Clipboard is unavailable.')) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(footnoteText()).toBe('Clipboard is unavailable.') + expect(screen.queryByText(COPIED_NOTE)).toBeNull() + // Why: the command was built and validated — only the clipboard failed, so nothing is demoted. + const copyButton = button('Copy Install Command') + expect(copyButton.dataset.variant).toBe('default') + expect(isAriaDisabled(copyButton)).toBe(false) + expect(button('Show Package').dataset.variant).toBe('link') + expect(screen.getByText(/Copy the command and run it/)).toBeTruthy() + expect(screen.queryByRole('button', { name: 'Download Manually' })).toBeNull() + }) + + it('recovers from a clipboard failure on the next copy attempt', async () => { + writeClipboardText.mockRejectedValueOnce(new Error('Clipboard is unavailable.')) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(writeClipboardText).toHaveBeenCalledTimes(2) + expect(footnoteText()).toBe(COPIED_NOTE) + }) +}) + +describe('LinuxPackageInstallRecoveryCard hashing state', () => { + it('names the work and blocks parallel jobs from repeated clicks', async () => { + const pending = deferred() + getInstructions.mockReturnValue(pending.promise) + renderCard() + + fireEvent.click(button('Copy Install Command')) + + const checking = button('Checking package...') + expect(isAriaDisabled(checking)).toBe(true) + expect(isAriaDisabled(button('Show Package'))).toBe(true) + expect(isAriaDisabled(button('Try Automatic Install Again'))).toBe(true) + + fireEvent.click(checking) + fireEvent.click(button('Show Package')) + fireEvent.click(button('Try Automatic Install Again')) + + // Why: the buttons stay clickable for focus reasons, so the handlers must do the refusing. + expect(getInstructions).toHaveBeenCalledTimes(1) + expect(showLinuxPackage).not.toHaveBeenCalled() + expect(quitAndInstall).not.toHaveBeenCalled() + + pending.resolve(INSTRUCTIONS) + await flushActions() + + expect(footnoteText()).toBe(COPIED_NOTE) + expect(isAriaDisabled(button('Show Package'))).toBe(false) + }) + + it('dims busy actions instead of relying on the native disabled styling', () => { + const pending = deferred() + getInstructions.mockReturnValue(pending.promise) + renderCard() + + fireEvent.click(button('Copy Install Command')) + + // Why: ui/button styles only `disabled:`, so without these an inert action looks fully live. + for (const name of ['Checking package...', 'Try Automatic Install Again', 'Show Package']) { + expect(button(name).className).toContain('aria-disabled:opacity-50') + expect(button(name).className).toContain('aria-disabled:cursor-default') + } + + pending.resolve(INSTRUCTIONS) + }) + + it('keeps focus on the pressed action while it hashes', () => { + const pending = deferred() + getInstructions.mockReturnValue(pending.promise) + renderCard() + + const copyButton = button('Copy Install Command') + copyButton.focus() + fireEvent.click(copyButton) + + // Why: a native `disabled` here would blur the button and dump focus to . + expect(document.activeElement).toBe(button('Checking package...')) + expect(document.activeElement).not.toBe(document.body) + + pending.resolve(INSTRUCTIONS) + }) + + it('names the work while revealing the package and re-enables afterwards', async () => { + const pending = deferred() + showLinuxPackage.mockReturnValue(pending.promise) + renderCard() + + fireEvent.click(button('Show Package')) + + expect(button('Checking package...')).toBeTruthy() + expect(isAriaDisabled(button('Copy Install Command'))).toBe(true) + + pending.resolve() + await flushActions() + + expect(showLinuxPackage).toHaveBeenCalledTimes(1) + expect(isAriaDisabled(button('Copy Install Command'))).toBe(false) + }) +}) + +describe('LinuxPackageInstallRecoveryCard details', () => { + it('adds the neutral no-agent note for authentication-agent-unavailable', () => { + renderCard({ recovery: makeRecovery({ reason: 'authentication-agent-unavailable' }) }) + + expect(screen.queryByText(/No usable authentication agent/)).toBeNull() + + const disclosure = button('Show details') + expect(disclosure.getAttribute('aria-expanded')).toBe('false') + fireEvent.click(disclosure) + + const detail = screen.getByText(/No usable authentication agent answered/) + expect(detail.textContent).toContain(DIAGNOSTIC) + expect(button('Hide details').getAttribute('aria-expanded')).toBe('true') + + fireEvent.click(button('Hide details')) + expect(screen.queryByText(/No usable authentication agent/)).toBeNull() + expect(button('Show details').getAttribute('aria-expanded')).toBe('false') + }) + + it('scopes the trust note to the moment the command is built', () => { + renderCard() + + fireEvent.click(button('Show details')) + + // Why: the digest check is a point-in-time claim, not a standing guarantee about the file. + const detail = screen.getByText(/Orca checks the downloaded file against the release metadata/) + expect(detail.textContent).toContain('at the moment it builds this command') + expect(detail.textContent).toContain( + 'The system package itself is not signature-checked, and Orca cannot vouch for the file ' + + 'after that point.' + ) + }) + + it('omits the no-agent note for other failure reasons', () => { + renderCard({ recovery: makeRecovery({ reason: 'authentication-denied' }) }) + + fireEvent.click(button('Show details')) + + expect(screen.queryByText(/No usable authentication agent/)).toBeNull() + expect(screen.getByText(new RegExp(DIAGNOSTIC))).toBeTruthy() + }) + + it('scrolls long diagnostics instead of widening the card', () => { + const long = `${DIAGNOSTIC} ${'diagnostic-overflow '.repeat(400)}` + const { container } = renderCard({ diagnostic: long }) + + fireEvent.click(button('Show details')) + + const detail = container.querySelector('p.font-mono') + expect(detail?.className).toContain('max-h-20') + expect(detail?.className).toContain('overflow-auto') + expect(detail?.className).toContain('break-words') + expect(detail?.textContent).toContain('diagnostic-overflow') + }) +}) + +describe('LinuxPackageInstallRecoveryCard retry', () => { + it('retries the automatic install through quitAndInstall', () => { + renderCard() + + fireEvent.click(button('Try Automatic Install Again')) + + expect(quitAndInstall).toHaveBeenCalledTimes(1) + expect(getInstructions).not.toHaveBeenCalled() + }) + + it('holds the busy slot while the quit is in flight', async () => { + renderCard() + + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + + // Why: quitAndInstall resolves as soon as main schedules the install, so a resolved promise is + // not an outcome — the slot stays held until a real status arrives. + expect(isAriaDisabled(button('Copy Install Command'))).toBe(true) + expect(isAriaDisabled(button('Show Package'))).toBe(true) + + fireEvent.click(button('Copy Install Command')) + fireEvent.click(button('Show Package')) + await flushActions() + + expect(getInstructions).not.toHaveBeenCalled() + expect(showLinuxPackage).not.toHaveBeenCalled() + expect(quitAndInstall).toHaveBeenCalledTimes(1) + }) + + it('releases the busy slot when a fresh recovery status arrives', async () => { + const view = renderCard() + + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + expect(isAriaDisabled(button('Copy Install Command'))).toBe(true) + + // A failed retry never rejects — main pushes a new recovery status a moment later. + pushFreshRecovery(view) + + expect(isAriaDisabled(button('Copy Install Command'))).toBe(false) + expect(isAriaDisabled(button('Show Package'))).toBe(false) + expect(isAriaDisabled(button('Try Automatic Install Again'))).toBe(false) + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(1) + expect(writeClipboardText).toHaveBeenCalledWith(INSTALL_COMMAND) + expect(footnoteText()).toBe(COPIED_NOTE) + }) + + it('leaves an in-flight hash job busy when a fresh recovery status arrives', () => { + const pending = deferred() + getInstructions.mockReturnValue(pending.promise) + const view = renderCard() + + fireEvent.click(button('Copy Install Command')) + pushFreshRecovery(view) + + // Why: the release is scoped to the retry slot — a running hash must keep its busy state. + expect(button('Checking package...')).toBeTruthy() + expect(isAriaDisabled(button('Show Package'))).toBe(true) + + pending.resolve(INSTRUCTIONS) + }) + + it('also releases the busy slot if the preload call itself rejects', async () => { + quitAndInstall.mockRejectedValue(new Error('Error: updater is not initialized')) + renderCard() + + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + + expect(footnoteText()).toBe('updater is not initialized') + expect(isAriaDisabled(button('Copy Install Command'))).toBe(false) + expect(isAriaDisabled(button('Show Package'))).toBe(false) + }) +}) + +describe('LinuxPackageInstallRecoveryCard reveal', () => { + it('reveals the retained package from the link-style action', async () => { + renderCard() + + const show = button('Show Package') + expect(show.dataset.variant).toBe('link') + // The link-style action still has to meet the touch-target floor. + expect(show.className).toContain('min-h-[44px]') + + fireEvent.click(show) + await flushActions() + + expect(showLinuxPackage).toHaveBeenCalledTimes(1) + expect(footnoteElement()).toBeNull() + }) + + it('reports a failed reveal in place', async () => { + showLinuxPackage.mockRejectedValue(new Error('Package file is missing.')) + renderCard() + + fireEvent.click(button('Show Package')) + await flushActions() + + expect(footnoteText()).toBe('Package file is missing.') + // Why: a reveal failure is not a command-build failure, so the copy path must survive it. + expect(button('Copy Install Command')).toBeTruthy() + }) +}) + +describe('LinuxPackageInstallRecoveryCard without a usable command', () => { + it('promotes Show Package and keeps the official-release fallback', async () => { + getInstructions.mockResolvedValue(NO_PACKAGE_MANAGER) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(screen.queryByRole('button', { name: 'Copy Install Command' })).toBeNull() + expect(button('Show Package').dataset.variant).toBe('default') + expect(button('Try Automatic Install Again')).toBeTruthy() + expect(footnoteText()).toBe(NO_PACKAGE_MANAGER.message) + // The copy-and-run explainer would be dead advice with no command to copy. + expect(screen.queryByText(/Copy the command and run it/)).toBeNull() + + fireEvent.click(button('Download Manually')) + expect(openUrl).toHaveBeenCalledWith(RELEASE_URL) + }) + + it('demotes on a no-sudo verdict without needing a rejection', async () => { + getInstructions.mockResolvedValue({ + ok: false, + reason: 'no-sudo', + message: 'No sudo binary is available on this machine.' + }) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(footnoteText()).toBe('No sudo binary is available on this machine.') + expect(button('Show Package').dataset.variant).toBe('default') + expect(button('Download Manually')).toBeTruthy() + }) + + it('still reveals the package after the command build failed', async () => { + getInstructions.mockResolvedValue(NO_PACKAGE_MANAGER) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + fireEvent.click(button('Show Package')) + await flushActions() + + expect(showLinuxPackage).toHaveBeenCalledTimes(1) + }) + + it('restores the copy path when the automatic install is retried', async () => { + getInstructions.mockResolvedValueOnce(NO_PACKAGE_MANAGER) + renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + expect(screen.queryByRole('button', { name: 'Copy Install Command' })).toBeNull() + + // Why: a retry re-evaluates the machine, so the earlier "no command" verdict must not stick. + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + + expect(quitAndInstall).toHaveBeenCalledTimes(1) + expect(button('Copy Install Command').dataset.variant).toBe('default') + expect(button('Show Package').dataset.variant).toBe('link') + expect(screen.getByText(/Copy the command and run it/)).toBeTruthy() + expect(screen.queryByRole('button', { name: 'Download Manually' })).toBeNull() + }) + + it('copies again once a fresh recovery status follows a failed retry', async () => { + getInstructions.mockResolvedValueOnce(NO_PACKAGE_MANAGER) + const view = renderCard() + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + fireEvent.click(button('Try Automatic Install Again')) + await flushActions() + pushFreshRecovery(view) + + fireEvent.click(button('Copy Install Command')) + await flushActions() + + expect(writeClipboardText).toHaveBeenCalledWith(INSTALL_COMMAND) + expect(footnoteText()).toBe(COPIED_NOTE) + }) +}) + +describe('LinuxPackageInstallRecoveryCard keyboard', () => { + it('activates the primary action with Enter from the keyboard', async () => { + const user = userEvent.setup() + renderCard() + + const copyButton = button('Copy Install Command') + copyButton.focus() + expect(document.activeElement).toBe(copyButton) + + await user.keyboard('{Enter}') + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(1) + expect(writeClipboardText).toHaveBeenCalledWith(INSTALL_COMMAND) + }) + + it('reaches every recovery action in tab order', async () => { + const user = userEvent.setup() + renderCard() + + const order = [ + 'Minimize to status bar', + 'Show details', + 'Copy Install Command', + 'Try Automatic Install Again', + 'Show Package' + ] + for (const name of order) { + await user.tab() + expect(document.activeElement).toBe(button(name)) + } + }) + + it('keeps busy actions reachable by keyboard', () => { + const pending = deferred() + getInstructions.mockReturnValue(pending.promise) + renderCard() + + fireEvent.click(button('Copy Install Command')) + + // Why: aria-disabled keeps the control in the tab sequence; native disabled would remove it. + const show = button('Show Package') + show.focus() + expect(document.activeElement).toBe(show) + expect(show.hasAttribute('disabled')).toBe(false) + + pending.resolve(INSTRUCTIONS) + }) +}) diff --git a/src/renderer/src/components/LinuxPackageInstallRecoveryCard.tsx b/src/renderer/src/components/LinuxPackageInstallRecoveryCard.tsx new file mode 100644 index 00000000000..96d6b3cd5ee --- /dev/null +++ b/src/renderer/src/components/LinuxPackageInstallRecoveryCard.tsx @@ -0,0 +1,242 @@ +import { useCallback, useEffect, useRef, useState } from 'react' +import type { + LinuxPackageInstallInstructions, + LinuxPackageInstallRecovery +} from '../../../shared/types' +import { UpdateErrorCardContent } from './UpdateErrorCardContent' +import { translate } from '@/i18n/i18n' + +const COPY_CONFIRMATION_MS = 4_000 + +function copiedNote(packageFileName: string): string { + return translate( + 'auto.components.LinuxPackageInstallRecoveryCard.aa57fa4f80', + 'Command copied. Run it in a system terminal to install {{value0}}, then quit and reopen Orca.', + { + value0: packageFileName + } + ) +} + +function toMessage(error: unknown): string { + const message = String((error as Error)?.message ?? error) + // Electron prefixes rejected invoke() results with the channel; keep only the user-safe tail. + return message.replace(/^Error invoking remote method '[^']*':\s*/, '').replace(/^Error:\s*/, '') +} + +export function LinuxPackageInstallRecoveryCard({ + recovery, + diagnostic, + releaseUrl, + onClose +}: { + recovery: LinuxPackageInstallRecovery + diagnostic: string + releaseUrl?: string + onClose: () => void +}) { + // Why: i18n boots in English and swaps catalogs after the persisted language loads, so these must + // be resolved per render — at module scope they would freeze the whole card in English. + const TITLE = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.53e1559f99', + 'Automatic Install Failed' + ) + const SUMMARY = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.a7ac6ec78b', + 'Orca downloaded the update but could not install the system package automatically.' + ) + const EXPLAINER = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.82c6dbea00', + 'Copy the command and run it in a system terminal on the computer where Orca is installed. After it finishes, quit and reopen Orca to run the new version.' + ) + const AGENT_NOTE = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.53c4b8e148', + 'No usable authentication agent answered the privileged install request.' + ) + const TRUST_NOTE = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.b7e7c5bc95', + 'Orca checks the downloaded file against the release metadata at the moment it builds this command. The system package itself is not signature-checked, and Orca cannot vouch for the file after that point.' + ) + const CHECKING_LABEL = translate( + 'auto.components.LinuxPackageInstallRecoveryCard.c732bcbf8f', + 'Checking package...' + ) + const [pendingAction, setPendingAction] = useState<'copy' | 'show' | 'retry' | null>(null) + const [actionError, setActionError] = useState(null) + const [copiedFileName, setCopiedFileName] = useState(null) + // Why: the trusted system directories lack sudo or a package manager — no command can be offered at all. + const [commandUnavailable, setCommandUnavailable] = useState(false) + const mountedRef = useRef(true) + + useEffect(() => { + mountedRef.current = true + return () => { + mountedRef.current = false + } + }, []) + + // Why: quitAndInstall resolves as soon as main schedules the install, so a failed retry never + // rejects — it arrives as a new recovery status. Without this the busy slot never clears and every + // action stays inert for the rest of the session. + useEffect(() => { + setPendingAction((current) => (current === 'retry' ? null : current)) + }, [recovery]) + + useEffect(() => { + if (!copiedFileName) { + return + } + const timer = window.setTimeout(() => setCopiedFileName(null), COPY_CONFIRMATION_MS) + return () => window.clearTimeout(timer) + }, [copiedFileName]) + + const handleCopyCommand = useCallback(() => { + if (pendingAction) { + return + } + setPendingAction('copy') + setActionError(null) + setCopiedFileName(null) + void (async () => { + let instructions: LinuxPackageInstallInstructions + try { + instructions = await window.api.updater.getLinuxPackageInstallInstructions() + } catch (error) { + // Why: only main knows whether the machine simply has no package manager; any other failure + // (stale status, untrusted sender, invalid artifact) must not demote the copy path. + if (mountedRef.current) { + setActionError(toMessage(error)) + } + return + } + if (!instructions.ok) { + if (mountedRef.current) { + setCommandUnavailable(true) + setActionError(instructions.message) + } + return + } + try { + await window.api.ui.writeClipboardText(instructions.command) + if (mountedRef.current) { + setCopiedFileName(instructions.packageFileName) + } + } catch (error) { + // Why: the command itself is valid — only the clipboard failed, so keep the copy action. + if (mountedRef.current) { + setActionError(toMessage(error)) + } + } + })().finally(() => { + if (mountedRef.current) { + setPendingAction(null) + } + }) + }, [pendingAction]) + + const handleShowPackage = useCallback(() => { + if (pendingAction) { + return + } + setPendingAction('show') + setActionError(null) + setCopiedFileName(null) + void window.api.updater + .showLinuxPackage() + .catch((error: unknown) => { + if (mountedRef.current) { + setActionError(toMessage(error)) + } + }) + .finally(() => { + if (mountedRef.current) { + setPendingAction(null) + } + }) + }, [pendingAction]) + + const handleRetryAutomatic = useCallback(() => { + // Why: guard in the handler, not only through the disabled prop, so no path can quit and install mid-hash. + if (pendingAction) { + return + } + // Why: the quit sequence owns the app from here; hold the busy slot so no other action starts + // work mid-quit. Released by the effect above when a fresh recovery status says Orca stayed open. + setPendingAction('retry') + setActionError(null) + setCopiedFileName(null) + // Why: a fresh install attempt re-evaluates the machine, so an earlier "no command" verdict must not stick. + setCommandUnavailable(false) + void window.api.updater.quitAndInstall().catch((error: unknown) => { + if (mountedRef.current) { + setActionError(toMessage(error)) + setPendingAction(null) + } + }) + }, [pendingAction]) + + // Why: the label keeps naming its action — the footnote below the buttons carries the confirmation. + const copyAction = { + label: translate( + 'auto.components.LinuxPackageInstallRecoveryCard.55c86654b7', + 'Copy Install Command' + ), + pendingLabel: CHECKING_LABEL, + isPending: pendingAction === 'copy', + disabled: pendingAction !== null, + onClick: handleCopyCommand + } + const showAction = { + label: translate('auto.components.LinuxPackageInstallRecoveryCard.e3de29c86a', 'Show Package'), + pendingLabel: CHECKING_LABEL, + isPending: pendingAction === 'show', + disabled: pendingAction !== null, + onClick: handleShowPackage + } + const retryAction = { + label: translate( + 'auto.components.LinuxPackageInstallRecoveryCard.3da99454c6', + 'Try Automatic Install Again' + ), + disabled: pendingAction !== null, + onClick: handleRetryAutomatic + } + + const officialReleaseAction = releaseUrl + ? { + label: translate('auto.components.UpdateCard.47126bcf57', 'Download Manually'), + onClick: () => void window.api.shell.openUrl(releaseUrl) + } + : undefined + + const detail = [ + recovery.reason === 'authentication-agent-unavailable' ? AGENT_NOTE : null, + diagnostic, + TRUST_NOTE + ] + .filter(Boolean) + .join(' ') + + const footnote = actionError + ? { text: actionError, tone: 'destructive' as const } + : copiedFileName + ? { text: copiedNote(copiedFileName) } + : undefined + + return ( + + ) +} diff --git a/src/renderer/src/components/NewWorkspaceComposerCard.test.tsx b/src/renderer/src/components/NewWorkspaceComposerCard.test.tsx index e7001fcc783..ea41091f6a3 100644 --- a/src/renderer/src/components/NewWorkspaceComposerCard.test.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerCard.test.tsx @@ -153,7 +153,7 @@ const devboxNeedsSetupHostOption: ProjectHostSetupOption = { projectId: 'project-group:platform', hostId: 'ssh:devbox', label: 'Devbox', - detail: 'Project not set up on this host', + detail: 'Project location not set', isAvailable: true, attention: false } @@ -581,7 +581,7 @@ describe('NewWorkspaceComposerCard folder task source mode', () => { openRunTargetPicker(current.container) const devboxItem = findRunTargetItem('Devbox') - expect(devboxItem?.textContent).toContain('Project not set up on this host') + expect(devboxItem?.textContent).toContain('Project location not set') // Not-connected rows stay highlightable (never `disabled`) so they hover like // the other rows; they're quieted visually instead. expect(devboxItem?.hasAttribute('data-disabled')).toBe(false) diff --git a/src/renderer/src/components/PullRequestPage.tsx b/src/renderer/src/components/PullRequestPage.tsx index 43198a9be9d..4b46d0148e5 100644 --- a/src/renderer/src/components/PullRequestPage.tsx +++ b/src/renderer/src/components/PullRequestPage.tsx @@ -126,6 +126,11 @@ import { type PRCommentGroup } from '@/lib/pr-comment-groups' import { resolveCommentReplyTarget } from '@/components/comment-reply-target-state' +import { + attachPRReviewReplyParent, + canPostPRReviewThreadReply +} from '@/components/right-sidebar/pr-comments-ai-launch-ack' +import { buildPRCommentConversationReplyBody } from '@/components/right-sidebar/pr-comment-fixing-reply-body' import { useAppStore } from '@/store' import { useAllWorktrees } from '@/store/selectors' import { callRuntimeRpc, getActiveRuntimeTarget } from '@/runtime/runtime-rpc-client' @@ -2273,29 +2278,32 @@ function ConversationTab({ ) return false } - const result = - comment.path && item.type === 'pr' - ? await addPRReviewCommentReplyForRepo({ - repoPath: repoPath ?? '', - repoId: item.repoId, - sourceContext, - prNumber: item.number, - prRepo, - commentId: comment.id, - body: replyBody, - threadId: comment.threadId, - path: comment.path, - line: comment.line - }) - : await addIssueCommentForRepo({ - repoPath: repoPath ?? '', - repoId: item.repoId, - sourceContext, - number: item.number, - body: `@${comment.author} ${replyBody}`, - type: item.type, - prRepo - }) + // Why: nest under review threads (path/threadId/discussion_r); never post a + // separate top-level conversation comment for those. + const isReviewThreadReply = item.type === 'pr' && canPostPRReviewThreadReply(comment) + const result = isReviewThreadReply + ? await addPRReviewCommentReplyForRepo({ + repoPath: repoPath ?? '', + repoId: item.repoId, + sourceContext, + prNumber: item.number, + prRepo, + commentId: comment.id, + body: replyBody, + threadId: comment.threadId, + path: comment.path, + line: comment.line + }) + : await addIssueCommentForRepo({ + repoPath: repoPath ?? '', + repoId: item.repoId, + sourceContext, + number: item.number, + // Why: a GitHub App login carries a [bot] suffix that never resolves as a mention. + body: buildPRCommentConversationReplyBody(comment.author, replyBody), + type: item.type, + prRepo + }) if (!result.ok) { toast.error( @@ -2304,7 +2312,9 @@ function ConversationTab({ ) return false } - onCommentAdded(result.comment) + onCommentAdded( + isReviewThreadReply ? attachPRReviewReplyParent(result.comment, comment) : result.comment + ) setReplyingTo(null) toast.success(translate('auto.components.PullRequestPage.11505c7a71', 'Reply posted.')) return true diff --git a/src/renderer/src/components/TaskPage.tsx b/src/renderer/src/components/TaskPage.tsx index 3ff8a909b7e..b430b0c33a3 100644 --- a/src/renderer/src/components/TaskPage.tsx +++ b/src/renderer/src/components/TaskPage.tsx @@ -205,7 +205,12 @@ import { } from '@/components/task-page-cache-selectors' import { shouldHideTaskPageListChrome } from '@/components/task-page-list-chrome-visibility' import { + applyEmptyPageClamp, + applyWindowPageLimit, + buildSelectedReposKey, + deriveAdvertisedTotalPages, getTaskPagePerRepoLimit, + resolveEmptyPageOutcome, taskPageToGitHubApiPage } from '@/components/task-page-work-item-pagination' import { sortWorkItemsByNumber } from '../../../shared/work-items' @@ -234,6 +239,13 @@ import { resolveUserRepoSwitchReset, resolveVanishedNewIssueRepoReset } from '@/components/task-page-new-issue-draft' +import { + isTaskCreationDraftContentful, + type NewJiraIssueDraft, + type NewLinearIssueDraft, + type NewLinearProjectDraft +} from '@/store/slices/task-creation-drafts' +import { useTaskCreationDraftRetention } from '@/components/use-task-creation-draft-retention' import { findTaskPageJiraIssue } from '@/components/task-page-jira-cache-selectors' import { getRepoBackedTaskEmptyState } from '@/components/task-page-empty-state' import { @@ -3040,6 +3052,33 @@ const hasUpstreamCandidateDivergence = ( !!s.sources.upstreamCandidate && !sameGitHubOwnerRepo(s.sources.originCandidate, s.sources.upstreamCandidate) +function writeNewLinearProjectDraft(draft: NewLinearProjectDraft | null): void { + const state = useAppStore.getState() + if (draft && isTaskCreationDraftContentful(draft)) { + state.setNewLinearProjectDraft(draft) + } else { + state.clearNewLinearProjectDraft() + } +} + +function writeNewLinearIssueDraft(draft: NewLinearIssueDraft | null): void { + const state = useAppStore.getState() + if (draft && isTaskCreationDraftContentful(draft)) { + state.setNewLinearIssueDraft(draft) + } else { + state.clearNewLinearIssueDraft() + } +} + +function writeNewJiraIssueDraft(draft: NewJiraIssueDraft | null): void { + const state = useAppStore.getState() + if (draft && isTaskCreationDraftContentful(draft)) { + state.setNewJiraIssueDraft(draft) + } else { + state.clearNewJiraIssueDraft() + } +} + export default function TaskPage(): React.JSX.Element { useTranslation() const settings = useAppStore((s) => s.settings) @@ -3175,6 +3214,18 @@ export default function TaskPage(): React.JSX.Element { [eligibleRepos, repoSelection] ) + // Why: see buildSelectedReposKey — array-identity deps re-fire on every + // repos:changed even when the selection is unchanged. The context part is + // resolved as GitHub, but every provider-independent field (projectId, + // hostId, projectHostSetupId, repoId) is identical across providers, so the + // GitLab effect can key off this too — it passes no gitlabProjectRef, so its + // context carries no providerIdentity of its own. Thread a projectRef into + // that call and this key needs a GitLab-scoped part. + const selectedReposKey = useMemo( + () => buildSelectedReposKey(selectedRepos, (r) => getTaskPageRepoSourceContext(r, 'github')), + [selectedRepos] + ) + // Why: many affordances need *a* repo; use the first selected as default, while cross-repo dialogs still let the user override per-action. const primaryRepo = selectedRepos[0] ?? null const linearWorkspaces = linearStatus.workspaces ?? [] @@ -3777,14 +3828,34 @@ export default function TaskPage(): React.JSX.Element { const [paginationLoading, setPaginationLoading] = useState(false) const [loadingTargetPage, setLoadingTargetPage] = useState(null) const [countedTotalPages, setCountedTotalPages] = useState(null) + // Proven window-422 page limit — separate from the count so a late count + // can't resurrect proven-unreachable pages, nor be pinned by a speculative + // withdrawal (see deriveAdvertisedTotalPages). + const [provenPageLimit, setProvenPageLimit] = useState(null) + // Why: synchronous mirror of countedTotalPages — the empty-page branch needs + // the committed value, not a click-time closure, and refs update immediately. + const countedTotalPagesRef = useRef(null) const fetchWorkItemsNextPage = useAppStore((s) => s.fetchWorkItemsNextPage) const countWorkItemsAcrossRepos = useAppStore((s) => s.countWorkItemsAcrossRepos) + // Why: keyed on selectedReposKey, not the selectedRepos array — a background + // repos:changed refresh mid-flight would otherwise bump the generation and + // silently discard the user's page navigation (#11485). Mirrors every dep of + // the fetch effect that resets page state, so a reset always invalidates + // in-flight page requests. useEffect(() => { paginationGenerationRef.current += 1 setPaginationLoading(false) setLoadingTargetPage(null) - }, [selectedRepos, appliedTaskSearch, workItemsInvalidationNonce]) + }, [ + selectedReposKey, + appliedTaskSearch, + workItemsInvalidationNonce, + taskRefreshNonce, + taskSource, + githubMode, + taskResumeApplied + ]) // Why: the dialog's "Use" button routes through the same direct-launch flow as the row-level "Use" CTA so behavior is consistent regardless of entry point. const githubTaskDrawerWorkItem = useAppStore((s) => s.githubTaskDrawerWorkItem) @@ -4799,15 +4870,6 @@ export default function TaskPage(): React.JSX.Element { jiraTaskSourceContext ]) - // Why: stable string key for selectedRepos so the GitLab effect doesn't re-run on every parent render from a new array ref. - const selectedReposKey = useMemo( - () => - selectedRepos - .map((r) => `${r.id}|${r.path}|${r.connectionId ?? ''}|${r.executionHostId ?? ''}`) - .join(','), - [selectedRepos] - ) - // Why: fetch GitLab Issues and MRs separately so errors stay isolated per tab (mirrors GitHub's split endpoints). useEffect(() => { if (taskSource !== 'gitlab') { @@ -4914,7 +4976,7 @@ export default function TaskPage(): React.JSX.Element { return () => { stale = true } - // eslint-disable-next-line react-hooks/exhaustive-deps -- selectedReposKey encodes the only selectedRepos fields read above; keying off the array ref would re-run on every parent render. + // eslint-disable-next-line react-hooks/exhaustive-deps -- selectedReposKey covers every selectedRepos field read above (see its GitHub-scoped-context note); keying off the array ref would re-run on every parent render. }, [taskSource, gitlabView, activeGitlabFilter, gitlabRefreshNonce, selectedReposKey]) // Why: Todos fetch has its own effect — different trigger (no chip filter) and data path (gl.todos is user-scoped, not repo-scoped). @@ -5610,6 +5672,16 @@ export default function TaskPage(): React.JSX.Element { setNewLinearProjectLabelIds([]) }, [newLinearProjectTargetTeam?.id, newLinearProjectTargetTeam?.workspaceId]) + const discardNewLinearProjectDraft = useTaskCreationDraftRetention({ + open: newLinearProjectOpen, + draft: { + name: newLinearProjectName, + description: newLinearProjectDescription, + content: newLinearProjectContent + }, + writeDraft: writeNewLinearProjectDraft + }) + // New Linear issue dialog state const [newLinearIssueOpen, setNewLinearIssueOpen] = useState(false) const [newLinearIssueTitle, setNewLinearIssueTitle] = useState('') @@ -5623,6 +5695,12 @@ export default function TaskPage(): React.JSX.Element { const [newLinearIssueProjectId, setNewLinearIssueProjectId] = useState(null) const [newLinearIssueLabelIds, setNewLinearIssueLabelIds] = useState([]) + const discardNewLinearIssueDraft = useTaskCreationDraftRetention({ + open: newLinearIssueOpen, + draft: { title: newLinearIssueTitle, body: newLinearIssueBody }, + writeDraft: writeNewLinearIssueDraft + }) + const newLinearIssueTargetTeam = useMemo( () => availableTeams.find((t) => t.id === newLinearIssueTeamId) ?? availableTeams[0] ?? null, [availableTeams, newLinearIssueTeamId] @@ -5760,6 +5838,12 @@ export default function TaskPage(): React.JSX.Element { const [newJiraIssueCustomFieldValues, setNewJiraIssueCustomFieldValues] = useState< Record >({}) + + const discardNewJiraIssueDraft = useTaskCreationDraftRetention({ + open: newJiraIssueOpen, + draft: { title: newJiraIssueTitle, body: newJiraIssueBody }, + writeDraft: writeNewJiraIssueDraft + }) const includeJiraSiteNameInProjectLabel = selectedJiraSiteId === 'all' const previousProviderRuntimeContextKeyRef = useRef(providerRuntimeContextKey) @@ -6111,10 +6195,12 @@ export default function TaskPage(): React.JSX.Element { const fallbackTotalPages = lastLoadedPageFull ? Math.max(pages.length, lastLoadedPageIndex + 2) : Math.max(1, pages.length) - const totalPages = - countedTotalPages && countedTotalPages > 0 - ? Math.max(pages.length, countedTotalPages) - : fallbackTotalPages + const totalPages = deriveAdvertisedTotalPages({ + loadedPages: pages.length, + countedTotalPages, + fallbackTotalPages, + provenPageLimit + }) // Why: load only the clicked page so a high-page jump doesn't exhaust GitHub's Search API rate bucket. const handleLoadNextPage = useCallback( @@ -6135,7 +6221,7 @@ export default function TaskPage(): React.JSX.Element { setPaginationLoading(true) setLoadingTargetPage(target) try { - const { items } = await fetchWorkItemsNextPage( + const { items, failedCount, errorTypes } = await fetchWorkItemsNextPage( repoArgs, githubPerRepoPageLimit, githubPageSize, @@ -6146,6 +6232,55 @@ export default function TaskPage(): React.JSX.Element { return } if (items.length === 0) { + // Why: see resolveEmptyPageOutcome — a dead click needs feedback only + // when something actually failed; a clean empty probe is end-of-data. + // The reason never depends on the count, so it's safe to derive here; + // the clamp is not (see applyEmptyPageClamp) and runs in the updater. + const { reason } = resolveEmptyPageOutcome({ + target, + failedCount, + errorTypes, + countedTotalPages: null + }) + if (reason === 'window-unreachable') { + toast.error( + translate( + 'auto.components.TaskPage.loadPageUnreachable', + 'Page {{value0}} is beyond what GitHub search can return.', + { value0: String(target + 1) } + ), + { id: 'work-items-page-unreachable' } + ) + setProvenPageLimit((previous) => applyWindowPageLimit(previous, target)) + } else if (reason === 'load-failed') { + toast.error( + translate( + 'auto.components.TaskPage.loadPageFailed', + 'Page {{value0}} could not be loaded from GitHub.', + { value0: String(target + 1) } + ), + { id: 'work-items-page-load-failed' } + ) + } else { + // Why: with a real count the clamp is refused, so without feedback + // the click would look dead — the count over-advertised; nothing + // failed, so the copy stays neutral. The ref carries the committed + // count, immune to the click-time closure race. + const committedCount = countedTotalPagesRef.current + if (committedCount !== null && committedCount > 0) { + toast( + translate( + 'auto.components.TaskPage.loadPageNoMoreResults', + 'No more results on page {{value0}}.', + { value0: String(target + 1) } + ), + { id: 'work-items-page-no-more-results' } + ) + } + const next = applyEmptyPageClamp(committedCount, { target, failedCount, errorTypes }) + countedTotalPagesRef.current = next + setCountedTotalPages(next) + } return } setPages((previous) => { @@ -6253,6 +6388,8 @@ export default function TaskPage(): React.JSX.Element { setPages([page0]) setCurrentPage(0) setCountedTotalPages(null) + countedTotalPagesRef.current = null + setProvenPageLimit(null) setTasksError(null) setFailedCount(0) // reset so a prior failure banner doesn't linger setGithubUnavailable(false) @@ -6357,6 +6494,10 @@ export default function TaskPage(): React.JSX.Element { githubPerRepoPageLimit ).then(({ totalPages: countedPages }) => { if (!cancelled) { + // Why: the count overwrites unconditionally — proven window limits live + // in provenPageLimit, so a late count can't be pinned by a speculative + // end-of-data withdrawal, and can't resurrect proven-dead pages either. + countedTotalPagesRef.current = countedPages setCountedTotalPages(countedPages) } }) @@ -6365,9 +6506,13 @@ export default function TaskPage(): React.JSX.Element { cancelled = true } // Why: store selectors are stable (omit from deps); workItemsInvalidationNonce included so a preference flip re-dispatches. + // selectedReposKey stands in for selectedRepos — the array gets a fresh + // identity on every repos:changed event, and re-running this effect then + // resets pagination mid-click (#11485). The key covers every repo field the + // requests read. // eslint-disable-next-line react-hooks/exhaustive-deps }, [ - selectedRepos, + selectedReposKey, appliedTaskSearch, taskRefreshNonce, taskSource, @@ -6840,6 +6985,7 @@ export default function TaskPage(): React.JSX.Element { : undefined } ) + discardNewLinearProjectDraft() setNewLinearProjectOpen(false) setNewLinearProjectName('') setNewLinearProjectDescription('') @@ -6882,7 +7028,8 @@ export default function TaskPage(): React.JSX.Element { newLinearProjectTargetTeam, openLinearProjectContext, linearTaskSourceContext, - settings + settings, + discardNewLinearProjectDraft ]) const handleCreateNewLinearIssue = useCallback(async (): Promise => { @@ -6943,6 +7090,7 @@ export default function TaskPage(): React.JSX.Element { : undefined } ) + discardNewLinearIssueDraft() setNewLinearIssueOpen(false) setNewLinearIssueTitle('') setNewLinearIssueBody('') @@ -6988,7 +7136,8 @@ export default function TaskPage(): React.JSX.Element { selectedLinearProject, setSelectedLinearIssue, linearTaskSourceContext, - settings + settings, + discardNewLinearIssueDraft ]) const handleCreateNewJiraIssue = useCallback(async (): Promise => { @@ -7037,6 +7186,7 @@ export default function TaskPage(): React.JSX.Element { : undefined } ) + discardNewJiraIssueDraft() setNewJiraIssueOpen(false) setNewJiraIssueTitle('') setNewJiraIssueBody('') @@ -7077,7 +7227,8 @@ export default function TaskPage(): React.JSX.Element { jiraTaskSourceContext, settings, setSelectedJiraIssue, - visibleJiraCreateFields + visibleJiraCreateFields, + discardNewJiraIssueDraft ]) const githubTasksBusy = tasksLoading || tasksRefreshing || tasksFiltering @@ -8506,9 +8657,11 @@ export default function TaskPage(): React.JSX.Element { size="icon" onClick={() => { if (linearMode === 'projects' && !selectedLinearProject) { - setNewLinearProjectName('') - setNewLinearProjectDescription('') - setNewLinearProjectContent('') + // Why: restore dismissed typed text (accidental dismissal recoverable); pickers keep their fresh open-time defaults. + const draft = useAppStore.getState().newLinearProjectDraft + setNewLinearProjectName(draft?.name ?? '') + setNewLinearProjectDescription(draft?.description ?? '') + setNewLinearProjectContent(draft?.content ?? '') setNewLinearProjectTeamId(availableTeams[0]?.id ?? null) setNewLinearProjectLeadId(null) setNewLinearProjectMemberIds([]) @@ -8519,8 +8672,10 @@ export default function TaskPage(): React.JSX.Element { setNewLinearProjectOpen(true) return } - setNewLinearIssueTitle('') - setNewLinearIssueBody('') + // Why: restore dismissed typed text (accidental dismissal recoverable); pickers keep their fresh open-time defaults. + const issueDraft = useAppStore.getState().newLinearIssueDraft + setNewLinearIssueTitle(issueDraft?.title ?? '') + setNewLinearIssueBody(issueDraft?.body ?? '') const projectTeamId = selectedLinearProject?.teams?.[0]?.id ?? availableTeams.find( @@ -8737,8 +8892,10 @@ export default function TaskPage(): React.JSX.Element { variant="outline" size="icon" onClick={() => { - setNewJiraIssueTitle('') - setNewJiraIssueBody('') + // Why: restore dismissed typed text (accidental dismissal recoverable); pickers keep their fresh open-time defaults. + const draft = useAppStore.getState().newJiraIssueDraft + setNewJiraIssueTitle(draft?.title ?? '') + setNewJiraIssueBody(draft?.body ?? '') setNewJiraIssueProjectId( sortedAvailableJiraProjects[0] ? getJiraProjectSelectionKey(sortedAvailableJiraProjects[0]) diff --git a/src/renderer/src/components/Terminal.tsx b/src/renderer/src/components/Terminal.tsx index 4189b0e44a1..deae7c9d1a8 100644 --- a/src/renderer/src/components/Terminal.tsx +++ b/src/renderer/src/components/Terminal.tsx @@ -45,16 +45,34 @@ import type { } from '../../../shared/types' import { hasFeatureInteraction } from '../../../shared/feature-interactions' import BrowserPane from './browser-pane/BrowserPane' -import BrowserPaneOverlayLayer from './browser-pane/BrowserPaneOverlayLayer' +import { RetainedBrowserPaneOverlayLayer } from './browser-pane/BrowserPaneOverlayLayer' import EmulatorPaneOverlayLayer from './emulator-pane/EmulatorPaneOverlayLayer' -import { useBrowserAutomationVisibilityForAny } from './browser-pane/browser-automation-visibility' -import { useBrowserMobileDriverForAny } from '@/lib/pane-manager/browser-mobile-driver-state' +import { + isBrowserAutomationVisible, + useBrowserAutomationVisibilityForAny +} from './browser-pane/browser-automation-visibility' +import { + isBrowserPageMobileDriven, + useBrowserMobileDriverForAny +} from '@/lib/pane-manager/browser-mobile-driver-state' import TerminalPaneOverlayLayer from './terminal-pane/TerminalPaneOverlayLayer' import { collectBrowserWebviewIds, destroyRemovedBrowserWebview, - destroyWorkspaceWebviews + destroyWorkspaceWebviews, + destroyWorktreeBrowserGuests } from '../store/slices/browser-webview-cleanup' +import { + browserTabVisibilityPageIds, + selectBrowserGuestEvictionWorktreeIds, + touchBrowserGuestWorktreeRecency, + worktreeHoldsLiveBrowserGuests +} from './browser-pane/browser-guest-worktree-retention' +import { + hasActiveBrowserPageDownload, + installBrowserPageDownloadActivityTracking +} from './browser-pane/browser-page-download-activity' +import { hasLiveBrowserGuest } from './browser-pane/webview-registry' import { handleSwitchRecentTab, handleSwitchTab, @@ -119,7 +137,6 @@ import { import { isMainTerminalSideEffectAuthorityForPty } from './terminal-pane/terminal-side-effect-facts-handler' import { appendUniqueOpenFileIds } from './terminal/unsaved-close-queue' import { setWindowCloseRequestHandler } from './window-close-request-coordinator' -import CodexRestartChip from './CodexRestartChip' import { findActivityTerminalPortal, useActivityTerminalPortals, @@ -273,6 +290,8 @@ function getKeybindingContext(target: EventTarget | null): KeybindingContext { function Terminal(): React.JSX.Element | null { const mountedWorktreeIdsRef = useRef(new Set()) + // Why an array: browser-guest eviction needs activation order (LRU), not just membership. + const browserGuestWorktreeRecencyRef = useRef([]) const measurableBackgroundWorktreeIdsRef = useRef(new Set()) const terminalWorktreeHiddenSinceRef = useRef(new Map()) // Why two extra clocks: hiddenSince survives a background-measure window (so @@ -312,6 +331,9 @@ function Terminal(): React.JSX.Element | null { const terminalRetentionBudgetEnabled = useAppStore( (s) => s.settings?.terminalHiddenWorktreeRetentionBudget !== false ) + const browserGuestRetentionBudgetEnabled = useAppStore( + (s) => s.settings?.browserGuestWorktreeRetentionBudget !== false + ) const terminalTitleSnapshotAuthorityEnabled = useAppStore((s) => isMainTerminalSideEffectAuthorityForPty({ settings: s.settings, @@ -1142,6 +1164,74 @@ function Terminal(): React.JSX.Element | null { terminalSshParkingEnabled, workspaceSurfaces ]) + // Why here: downloads outlive the pane-local state of hidden (unmounted) + // BrowserPanes, and the eviction veto below must see them. + useEffect(() => installBrowserPageDownloadActivityTracking(), []) + // Browser-guest retention budget (#12137 follow-up): hidden worktrees keep + // webview guests alive for instant revisits, but only the most recently + // activated few. Older ones have every guest FULLY destroyed through the + // sanctioned cleanup path while the worktree surface stays mounted: slots + // never unmount-detach a live guest (the STA-3228 blank-forever state), the + // hidden slot mounts no BrowserPane so nothing resurrects the guest early, + // and terminal panes/watchers/capture contracts are untouched. A revisit + // rebuilds guests from store state. + useEffect(() => { + if (!renderedActiveWorktreeId) { + return + } + const recency = browserGuestWorktreeRecencyRef.current + touchBrowserGuestWorktreeRecency(recency, renderedActiveWorktreeId) + const surfaceIds = new Set(workspaceSurfaces.map((workspace) => workspace.id)) + for (let index = recency.length - 1; index >= 0; index--) { + if (!surfaceIds.has(recency[index])) { + recency.splice(index, 1) + } + } + // Why after the bookkeeping: recency must track activation order even while + // the kill switch is off, or re-enabling would evict by worktree-list order. + if (!browserGuestRetentionBudgetEnabled) { + return + } + const state = useAppStore.getState() + // Why appended: a mounted worktree missing from recency (background mount) ranks oldest. + const recencyIds = new Set(recency) + const orderedWorktreeIds = [ + ...recency, + ...workspaceSurfaces.map((workspace) => workspace.id).filter((id) => !recencyIds.has(id)) + ] + const evictedWorktreeIds = selectBrowserGuestEvictionWorktreeIds({ + orderedWorktreeIds, + activeWorktreeId: renderedActiveWorktreeId, + isRetained: (worktreeId) => mountedWorktreeIdsRef.current.has(worktreeId), + holdsLiveGuests: (worktreeId) => + worktreeHoldsLiveBrowserGuests( + state.browserTabsByWorktree[worktreeId] ?? [], + state.browserPagesByWorkspace, + hasLiveBrowserGuest + ), + // Why these vetoes: automation/mobile keeps a hidden guest painted for a + // remote controller mid-drive, and main cancels a page's active downloads + // when its guest unregisters (tab-close semantics). Terminal state never + // vetoes — eviction only destroys guests and leaves the surface (panes, + // watchers) alone. + isEvictable: (worktreeId) => + !(state.browserTabsByWorktree[worktreeId] ?? []).some((tab) => + browserTabVisibilityPageIds(tab).some( + (pageId) => + isBrowserAutomationVisible(pageId) || + isBrowserPageMobileDriven(pageId) || + hasActiveBrowserPageDownload(pageId) + ) + ) + }) + for (const worktreeId of evictedWorktreeIds) { + destroyWorktreeBrowserGuests( + state.browserTabsByWorktree, + state.browserPagesByWorkspace, + worktreeId + ) + } + }, [renderedActiveWorktreeId, workspaceSurfaces, browserGuestRetentionBudgetEnabled]) // Why: a slow post-reconnect step exposes workspaceSessionReady before hydration can populate snapshot capabilities. if ( renderedActiveWorktreeId && @@ -2400,7 +2490,6 @@ function Terminal(): React.JSX.Element | null { } aria-hidden={!isVisible} > - {(tabsByWorktree[workspace.id] ?? []) .filter((tab) => shouldMountBackgroundWorktreeTab( @@ -2656,7 +2745,6 @@ const WorktreeSplitSurface = React.memo(function WorktreeSplitSurface({ inert={!isVisible} aria-hidden={!isVisible} > - + {/* Why: once eligible, retain slot DOM so hidden worktrees keep their Electron guests alive (STA-3228). */} + {isVisible || backgroundMountTabIds === null ? ( - <> - - - + ) : null}

diff --git a/src/renderer/src/components/UpdateCard.error-card.test.tsx b/src/renderer/src/components/UpdateCard.error-card.test.tsx index d9b74c7fdee..0e41c46f07b 100644 --- a/src/renderer/src/components/UpdateCard.error-card.test.tsx +++ b/src/renderer/src/components/UpdateCard.error-card.test.tsx @@ -1,14 +1,29 @@ // @vitest-environment happy-dom -import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' +import { act, cleanup, fireEvent, render, screen, type RenderResult } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { LinuxPackageInstallRecovery } from '../../../shared/types' import { useAppStore } from '../store' import { UpdateCard } from './UpdateCard' const openUrl = vi.fn() const download = vi.fn() const check = vi.fn() +const quitAndInstall = vi.fn() +const getInstructions = vi.fn() +const showLinuxPackage = vi.fn() +const writeClipboardText = vi.fn() +const relaunch = vi.fn() +const setSettings = vi.fn() -function renderAfterAvailableStatus(): void { +const PACKAGE_RECOVERY: LinuxPackageInstallRecovery = { + kind: 'linux-package-install', + packageType: 'deb', + reason: 'authentication-agent-unavailable', + version: '1.4.200' +} + +function renderAfterAvailableStatus(): RenderResult { useAppStore.setState({ updateStatus: { state: 'available', @@ -20,7 +35,18 @@ function renderAfterAvailableStatus(): void { updateCardCollapsed: false, updateReassuranceSeen: true }) - render() + return render() +} + +function mockReducedMotion(matches: boolean): void { + Object.defineProperty(window, 'matchMedia', { + configurable: true, + value: vi.fn().mockReturnValue({ + matches, + addEventListener: vi.fn(), + removeEventListener: vi.fn() + }) + }) } beforeEach(() => { @@ -28,30 +54,35 @@ beforeEach(() => { openUrl.mockReset() download.mockReset() check.mockReset() + quitAndInstall.mockReset().mockResolvedValue(undefined) + showLinuxPackage.mockReset().mockResolvedValue(undefined) + writeClipboardText.mockReset().mockResolvedValue(undefined) + relaunch.mockReset() + setSettings.mockReset().mockResolvedValue(undefined) + getInstructions.mockReset().mockResolvedValue({ + ok: true, + command: 'sudo apt-get install -y /tmp/orca_1.4.200_amd64.deb', + packageFileName: 'orca_1.4.200_amd64.deb' + }) Object.defineProperty(window, 'api', { configurable: true, value: { - app: { relaunch: vi.fn() }, - settings: { set: vi.fn().mockResolvedValue(undefined) }, + app: { relaunch }, + settings: { set: setSettings }, shell: { openUrl }, - ui: { set: vi.fn().mockResolvedValue(undefined) }, + ui: { set: vi.fn().mockResolvedValue(undefined), writeClipboardText }, updater: { check, dismissNudge: vi.fn(), dismissAvailableUpdate: vi.fn().mockResolvedValue(undefined), download, - quitAndInstall: vi.fn().mockResolvedValue(undefined) + getLinuxPackageInstallInstructions: getInstructions, + showLinuxPackage, + quitAndInstall } } }) - Object.defineProperty(window, 'matchMedia', { - configurable: true, - value: vi.fn().mockReturnValue({ - matches: false, - addEventListener: vi.fn(), - removeEventListener: vi.fn() - }) - }) + mockReducedMotion(false) }) afterEach(() => { @@ -154,3 +185,194 @@ describe('UpdateCard local builds', () => { expect(check).toHaveBeenCalledWith({ localBuild: true }) }) }) + +// ── Linux package-install recovery routing ─────────────────────────── + +async function flushActions(): Promise { + await act(async () => { + for (let i = 0; i < 8; i += 1) { + await Promise.resolve() + } + }) +} + +function showPackageRecovery(recovery = PACKAGE_RECOVERY): void { + act(() => + useAppStore.getState().setUpdateStatus({ + state: 'error', + message: 'pkexec: no polkit authentication agent found', + recovery + }) + ) +} + +describe('UpdateCard Linux package-install recovery', () => { + it('routes package-install errors to the recovery card instead of the generic one', () => { + renderAfterAvailableStatus() + + showPackageRecovery() + + expect(screen.getByText('Automatic Install Failed')).toBeTruthy() + expect(screen.queryByText('Update Error')).toBeNull() + expect(screen.queryByRole('button', { name: 'Retry Download' })).toBeNull() + expect(screen.getByRole('button', { name: 'Copy Install Command' })).toBeTruthy() + expect(screen.getByRole('button', { name: 'Try Automatic Install Again' })).toBeTruthy() + expect(screen.getByRole('button', { name: 'Show Package' })).toBeTruthy() + }) + + it('drives the copy action through the real preload surface', async () => { + renderAfterAvailableStatus() + showPackageRecovery() + + fireEvent.click(screen.getByRole('button', { name: 'Copy Install Command' })) + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(1) + expect(writeClipboardText).toHaveBeenCalledWith( + 'sudo apt-get install -y /tmp/orca_1.4.200_amd64.deb' + ) + }) + + it('offers the version release fallback once no command can be built', async () => { + getInstructions.mockResolvedValue({ + ok: false, + reason: 'no-package-manager', + message: 'No supported package manager was found.' + }) + renderAfterAvailableStatus() + showPackageRecovery() + + fireEvent.click(screen.getByRole('button', { name: 'Copy Install Command' })) + await flushActions() + + fireEvent.click(screen.getByRole('button', { name: 'Download Manually' })) + expect(openUrl).toHaveBeenCalledWith('https://github.com/stablyai/orca/releases/tag/v1.4.200') + }) + + it('keeps generic errors on the generic card when no recovery is attached', () => { + renderAfterAvailableStatus() + + act(() => useAppStore.getState().setUpdateStatus({ state: 'error', message: 'ENOSPC' })) + + expect(screen.getByText('Update Error')).toBeTruthy() + expect(screen.queryByText('Automatic Install Failed')).toBeNull() + fireEvent.click(screen.getByRole('button', { name: 'Retry Download' })) + expect(download).toHaveBeenCalledTimes(1) + }) + + it('leaves the HTTP/1.1 compatibility branch untouched', () => { + renderAfterAvailableStatus() + + act(() => + useAppStore + .getState() + .setUpdateStatus({ state: 'error', message: 'net::ERR_HTTP2_PROTOCOL_ERROR' }) + ) + + expect(screen.getByText('HTTP/2 Download Blocked')).toBeTruthy() + expect(screen.queryByText('Automatic Install Failed')).toBeNull() + expect(screen.getByRole('button', { name: 'Enable & Restart' })).toBeTruthy() + }) + + it('relaunches once when Enable & Restart is double-clicked', async () => { + renderAfterAvailableStatus() + + act(() => + useAppStore + .getState() + .setUpdateStatus({ state: 'error', message: 'net::ERR_HTTP2_PROTOCOL_ERROR' }) + ) + + // Why: the shared card marks the pending action aria-disabled, so the second click still + // reaches the handler and only its own guard can stop a double relaunch. + const enable = screen.getByRole('button', { name: 'Enable & Restart' }) + fireEvent.click(enable) + + const pending = screen.getByRole('button', { name: 'Restarting...' }) + expect(pending.getAttribute('aria-disabled')).toBe('true') + let secondClickDispatched = false + pending.addEventListener('click', () => { + secondClickDispatched = true + }) + fireEvent.click(pending) + await flushActions() + + expect(secondClickDispatched).toBe(true) + + expect(setSettings).toHaveBeenCalledTimes(1) + expect(setSettings).toHaveBeenCalledWith({ electronHttp1CompatibilityMode: true }) + expect(relaunch).toHaveBeenCalledTimes(1) + }) + + it('keeps long diagnostics inside the fixed-width card', () => { + const { container } = renderAfterAvailableStatus() + + act(() => + useAppStore.getState().setUpdateStatus({ + state: 'error', + message: `pkexec failed ${'overflow-token '.repeat(400)}`, + recovery: PACKAGE_RECOVERY + }) + ) + fireEvent.click(screen.getByRole('button', { name: 'Show details' })) + + const surface = container.firstElementChild as HTMLElement + expect(surface.className).toContain('w-[360px]') + expect(surface.className).toContain('max-w-[calc(100vw-32px)]') + const detail = container.querySelector('p.font-mono') + expect(detail?.className).toContain('max-h-20') + expect(detail?.className).toContain('overflow-auto') + expect(detail?.className).toContain('break-words') + }) +}) + +describe('UpdateCard recovery keyboard and motion', () => { + it('minimizes the recovery card on Escape', () => { + mockReducedMotion(true) + renderAfterAvailableStatus() + showPackageRecovery() + + fireEvent.keyDown(screen.getByRole('complementary'), { key: 'Escape' }) + + expect(useAppStore.getState().updateCardCollapsed).toBe(true) + expect(screen.queryByText('Automatic Install Failed')).toBeNull() + }) + + it('plays the exit animation before minimizing when motion is allowed', () => { + renderAfterAvailableStatus() + showPackageRecovery() + + const card = screen.getByRole('complementary') + expect(card.className).toContain('animate-update-card-enter') + + fireEvent.keyDown(card, { key: 'Escape' }) + expect(screen.getByRole('complementary').className).toContain('animate-update-card-exit') + }) + + it('drops card animation classes under reduced motion', () => { + mockReducedMotion(true) + renderAfterAvailableStatus() + showPackageRecovery() + + const card = screen.getByRole('complementary') + expect(card.className).not.toContain('animate-update-card-enter') + expect(card.className).not.toContain('animate-update-card-exit') + }) + + it('activates the recovery primary action with Enter without minimizing', async () => { + const user = userEvent.setup() + renderAfterAvailableStatus() + showPackageRecovery() + + const copyButton = screen.getByRole('button', { name: 'Copy Install Command' }) + copyButton.focus() + expect(document.activeElement).toBe(copyButton) + + await user.keyboard('{Enter}') + await flushActions() + + expect(getInstructions).toHaveBeenCalledTimes(1) + // Why: the card's Escape handler sits on the wrapper and must not swallow action keys. + expect(useAppStore.getState().updateCardCollapsed).toBe(false) + }) +}) diff --git a/src/renderer/src/components/UpdateCard.tsx b/src/renderer/src/components/UpdateCard.tsx index 4a23897df15..b47e9fedd72 100644 --- a/src/renderer/src/components/UpdateCard.tsx +++ b/src/renderer/src/components/UpdateCard.tsx @@ -1,22 +1,14 @@ /* eslint-disable max-lines -- Why: keeps the updater state machine and its presentation variants in one file. */ -import { useCallback, useEffect, useId, useRef, useState } from 'react' +import { useCallback, useEffect, useRef, useState } from 'react' import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion' import { useAppStore } from '../store' import { Card } from './ui/card' import { Button } from './ui/button' import { Progress } from './ui/progress' -import { - AlertCircle, - Check, - ChevronRight, - Loader2, - Minus, - Network, - RotateCw, - ShieldAlert, - X -} from 'lucide-react' +import { AlertCircle, Check, Loader2, Minus, X } from 'lucide-react' import type { ChangelogData } from '../../../shared/types' +import { UpdateErrorCardContent, type UpdateErrorCardModel } from './UpdateErrorCardContent' +import { LinuxPackageInstallRecoveryCard } from './LinuxPackageInstallRecoveryCard' import { isWindowsSignatureCheckUnavailableFailure, isWindowsSignatureMismatchFailure @@ -39,25 +31,6 @@ export function isHttp2ProtocolError(message: string): boolean { ) } -type ErrorCardModel = { - variant?: 'default' | 'http1Compatibility' | 'security' - title: string - summary: string - /** Optional guidance box between the summary and the raw error output. */ - explainer?: string - /** Raw error text, shown only when the user expands "Show details". */ - detail?: string - releaseUrl?: string - /** Overrides the secondary button label (defaults to "Download Manually"). */ - manualLabel?: string - primaryAction?: { - label: string - pendingLabel?: string - isPending?: boolean - onClick: () => void - } -} - // ── Compact card (transient check feedback) ───────────────────────── function CompactCardContent({ @@ -298,6 +271,11 @@ export function UpdateCard() { } const handleEnableHttp1Compatibility = () => { + // Why: the shared error card marks a pending action aria-disabled rather than disabled, so the + // second click of a double-click now reaches this handler and would relaunch twice. + if (compatibilityRelaunching) { + return + } setCompatibilityRelaunching(true) setCompatibilitySetupError(null) void window.api.settings @@ -317,7 +295,12 @@ export function UpdateCard() { status.state === 'error' && isWindowsSignatureMismatchFailure(status.message) const isSignatureCheckBlockedError = status.state === 'error' && isWindowsSignatureCheckUnavailableFailure(status.message) - const errorCard: ErrorCardModel | null = + // Carries the diagnostic alongside the recovery so the render branch needs no second state check. + const linuxPackageRecovery = + status.state === 'error' && status.recovery?.kind === 'linux-package-install' + ? { recovery: status.recovery, diagnostic: status.message } + : null + const errorCard: UpdateErrorCardModel | null = status.state === 'error' ? isLocalBuild ? { @@ -526,22 +509,22 @@ export function UpdateCard() { // ── Error states ───────────────────────────────────────────────── - if (errorCard) { + // Why: the package-recovery card owns its own async validation state, so it branches before the generic models. + if (linuxPackageRecovery) { return ( - ) } + if (errorCard) { + return + } + // ── Downloaded state ───────────────────────────────────────────── if (status.state === 'downloaded') { @@ -928,139 +911,6 @@ function DownloadingContent({ ) } -// ── Error card content ─────────────────────────────────────────────── - -function ErrorCardContent({ - variant = 'default', - title, - summary, - explainer, - detail, - releaseUrl, - manualLabel, - primaryAction, - onClose -}: { - variant?: 'default' | 'http1Compatibility' | 'security' - title: string - summary: string - explainer?: string - detail?: string - releaseUrl?: string - manualLabel?: string - primaryAction?: { - label: string - pendingLabel?: string - isPending?: boolean - onClick: () => void - } - onClose: () => void -}) { - // Why: raw error starts collapsed so the card leads with the plain summary, not a stack dump. - const [showDetails, setShowDetails] = useState(false) - const detailId = useId() - const isCompatibility = variant === 'http1Compatibility' - const isSecurity = variant === 'security' - const Icon = isCompatibility ? Network : isSecurity ? ShieldAlert : AlertCircle - return ( -
-
-
- -
-
-

{title}

-

{summary}

-
- -
- - {explainer ? ( -
-

{explainer}

-
- ) : null} - - {/* Caret disclosure that reveals the raw error while the plain summary stays the lead. */} - {detail ? ( -
- - {showDetails ? ( -
-

- {translate('auto.components.UpdateCard.3553a8672f', 'Last error')} -

-

- {detail} -

-
- ) : null} -
- ) : null} - -
- {primaryAction && ( - - )} - {releaseUrl && ( - - )} -
-
- ) -} - // ── Ready to install content ───────────────────────────────────────── function ReadyToInstallContent({ diff --git a/src/renderer/src/components/UpdateErrorCardContent.tsx b/src/renderer/src/components/UpdateErrorCardContent.tsx new file mode 100644 index 00000000000..f6665a706dd --- /dev/null +++ b/src/renderer/src/components/UpdateErrorCardContent.tsx @@ -0,0 +1,206 @@ +import { useId, useState } from 'react' +import { + AlertCircle, + ChevronRight, + Loader2, + Minus, + Network, + RotateCw, + ShieldAlert +} from 'lucide-react' +import { Button } from './ui/button' +import { translate } from '@/i18n/i18n' + +export type UpdateErrorCardAction = { + label: string + pendingLabel?: string + isPending?: boolean + disabled?: boolean + onClick: () => void +} + +export type UpdateErrorCardModel = { + variant?: 'default' | 'http1Compatibility' | 'security' + title: string + summary: string + /** Optional guidance box between the summary and the raw error output. */ + explainer?: string + /** Raw error text, shown only when the user expands "Show details". */ + detail?: string + releaseUrl?: string + /** Overrides the secondary button label (defaults to "Download Manually"). */ + manualLabel?: string + primaryAction?: UpdateErrorCardAction + /** Outline button rendered beside the primary action, before any release-URL fallback. */ + secondaryAction?: UpdateErrorCardAction + /** Link-style action rendered on its own row below the buttons. */ + tertiaryAction?: UpdateErrorCardAction + /** Short line under the actions — a copy confirmation or a recoverable action failure. */ + footnote?: { text: string; tone?: 'muted' | 'destructive' } +} + +function ActionButton({ + action, + variant, + leadingIcon +}: { + action: UpdateErrorCardAction + variant: 'default' | 'outline' + leadingIcon?: React.ReactNode +}) { + return ( + + ) +} + +export function UpdateErrorCardContent({ + variant = 'default', + title, + summary, + explainer, + detail, + releaseUrl, + manualLabel, + primaryAction, + secondaryAction, + tertiaryAction, + footnote, + onClose +}: UpdateErrorCardModel & { onClose: () => void }) { + // Why: raw error starts collapsed so the card leads with the plain summary, not a stack dump. + const [showDetails, setShowDetails] = useState(false) + const detailId = useId() + const isCompatibility = variant === 'http1Compatibility' + const isSecurity = variant === 'security' + const Icon = isCompatibility ? Network : isSecurity ? ShieldAlert : AlertCircle + return ( +
+
+
+ +
+
+

{title}

+

{summary}

+
+ +
+ + {explainer ? ( +
+

{explainer}

+
+ ) : null} + + {/* Caret disclosure that reveals the raw error while the plain summary stays the lead. */} + {detail ? ( +
+ + {showDetails ? ( +
+

+ {translate('auto.components.UpdateCard.3553a8672f', 'Last error')} +

+

+ {detail} +

+
+ ) : null} +
+ ) : null} + +
+
+ {primaryAction && ( + : undefined} + /> + )} + {secondaryAction && } + {releaseUrl && ( + + )} +
+ {tertiaryAction && ( + + )} + {footnote && ( +

+ {footnote.text} +

+ )} +
+
+ ) +} diff --git a/src/renderer/src/components/WorktreeJumpPalette.tsx b/src/renderer/src/components/WorktreeJumpPalette.tsx index 9eee43a6a4b..c85a2d700e7 100644 --- a/src/renderer/src/components/WorktreeJumpPalette.tsx +++ b/src/renderer/src/components/WorktreeJumpPalette.tsx @@ -1838,7 +1838,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
@@ -1966,7 +1966,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
@@ -2013,7 +2013,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
@@ -2054,7 +2054,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
@@ -2135,7 +2135,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
@@ -2213,7 +2213,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null { 'data-[selected=true]:border-border data-[selected=true]:bg-accent data-[selected=true]:text-foreground' )} > -
+
diff --git a/src/renderer/src/components/activity/activity-portal-readiness-loop.react185.test.tsx b/src/renderer/src/components/activity/activity-portal-readiness-loop.react185.test.tsx index 10d9fc2afa6..13260d457ae 100644 --- a/src/renderer/src/components/activity/activity-portal-readiness-loop.react185.test.tsx +++ b/src/renderer/src/components/activity/activity-portal-readiness-loop.react185.test.tsx @@ -20,6 +20,11 @@ import { type ActivityPortalReadinessStatus } from './activity-portal-readiness-oscillation' +// Why: re-applying ready DOM never consumes the readiness flip budget (a 'ready' +// status resets the latch), so this retry budget is independent of +// ACTIVITY_PORTAL_READINESS_MAX_FLIPS and must not be derived from it. +const PORTAL_READY_REAPPLY_ATTEMPTS = 32 + const WORKTREE_ID = 'wt-1' const TAB_ID = 'tab-react185' const OTHER_TAB_ID = 'tab-react185-other' @@ -79,6 +84,33 @@ function installAnimationFrameController(): { } } +function installMutationObserverController(): { notify: () => void } { + const callbacks = new Map() + class ControlledMutationObserver implements MutationObserver { + constructor(callback: MutationCallback) { + callbacks.set(this, callback) + } + + observe(): void {} + + disconnect(): void { + callbacks.delete(this) + } + + takeRecords(): MutationRecord[] { + return [] + } + } + vi.stubGlobal('MutationObserver', ControlledMutationObserver) + return { + notify() { + for (const [observer, callback] of callbacks) { + callback([], observer) + } + } + } +} + async function flushPortalFramesUntil( frames: ReturnType, settled: () => boolean @@ -342,6 +374,7 @@ describe('Activity portal pane switching', () => { it('releases a latched readiness once the terminal attaches', async () => { const frames = installAnimationFrameController() + const mutations = installMutationObserverController() const target = document.createElement('div') document.body.append(target) const buildRoot = (mode: 'hidden' | 'sibling' | 'ready'): void => { @@ -397,7 +430,7 @@ describe('Activity portal pane switching', () => { const statusesBefore = statuses.length await act(async () => { buildRoot(mode) - await Promise.resolve() + mutations.notify() }) expect(await flushPortalReadiness(frames)).toBe(true) if (mode !== 'sibling') { @@ -415,12 +448,18 @@ describe('Activity portal pane switching', () => { expect(sawLatchedSibling).toBe(true) expect(statuses.at(-1)).toBe('unavailable') - await act(async () => { - buildRoot('ready') - await Promise.resolve() - }) - expect(await flushPortalReadiness(frames)).toBe(true) - await flushPortalFramesUntil(frames, () => statuses.at(-1) === 'ready') + // Why: under CI load MutationObserver may miss one replaceChildren; re-apply ready DOM + // and keep draining until attach is observed. + let sawReady = false + for (let attempt = 0; attempt < PORTAL_READY_REAPPLY_ATTEMPTS && !sawReady; attempt += 1) { + await act(async () => { + buildRoot('ready') + mutations.notify() + }) + expect(await flushPortalReadiness(frames)).toBe(true) + await flushPortalFramesUntil(frames, () => statuses.at(-1) === 'ready') + sawReady = statuses.at(-1) === 'ready' + } expect(statuses.at(-1)).toBe('ready') }) }) diff --git a/src/renderer/src/components/browser-pane/BrowserPane.tsx b/src/renderer/src/components/browser-pane/BrowserPane.tsx index 1a2c0279543..33319c24dde 100644 --- a/src/renderer/src/components/browser-pane/BrowserPane.tsx +++ b/src/renderer/src/components/browser-pane/BrowserPane.tsx @@ -86,7 +86,9 @@ import { rememberLiveBrowserUrl } from './browser-runtime' import { ensureBrowserPageWebview } from './browser-page-webview' import { destroyPersistentWebview, + isBrowserPageRendererRecoveryPending, moveFocusToRendererBeforeWebviewDetach, + replacePersistentWebview, registeredWebContentsIds } from './webview-registry' import { @@ -188,6 +190,11 @@ import { MarkupOverlay } from './markup/MarkupOverlay' import { MarkupDrawButton } from './markup/MarkupDrawButton' import { deliverMarkupToClipboard } from './markup/markup-clipboard-delivery' import { BrowserLoadFailureOverlay } from './browser-load-failure-overlay' +import { + BROWSER_GUEST_RECOVERY_ERROR_CODE, + createBrowserPageGuestRecovery +} from './browser-page-guest-recovery' +import { subscribeBrowserSystemResume } from './browser-system-resume' type BrowserTabPageState = Partial< Pick< @@ -196,6 +203,12 @@ type BrowserTabPageState = Partial< > > +type BrowserPageUrlSetter = ( + tabId: string, + url: string, + options?: { preserveLoadError?: boolean } +) => void + type BrowserDownloadState = Omit & { receivedBytes: number status: 'downloading' | 'completed' | 'failed' | 'canceled' @@ -903,7 +916,7 @@ function RemoteBrowserPagePane({ worktreeId: string isActive: boolean onUpdatePageState: (tabId: string, updates: BrowserTabPageState) => void - onSetUrl: (tabId: string, url: string) => void + onSetUrl: BrowserPageUrlSetter }): React.JSX.Element { const activeRuntimeEnvironmentId = runtimeEnvironmentId const addressBarInputRef = useRef(null) @@ -2794,7 +2807,7 @@ function BrowserPagePane({ isMobileDriven: boolean inputLocked: boolean onUpdatePageState: (tabId: string, updates: BrowserTabPageState) => void - onSetUrl: (tabId: string, url: string) => void + onSetUrl: BrowserPageUrlSetter }): React.JSX.Element { const isPaintable = isBrowserPagePanePaintable({ isActive, @@ -2818,6 +2831,11 @@ function BrowserPagePane({ const [slotViewportReady, setSlotViewportReady] = useState( () => getBrowserOverlaySlotViewport(workspaceId) !== null ) + const [guestRecoveryGeneration, setGuestRecoveryGeneration] = useState(0) + const guestRecoveryPendingRef = useRef(false) + const validateVisibleGuestRegistrationRef = useRef<() => void>(() => {}) + const retryGuestRecoveryRef = useRef<() => void>(() => {}) + const wasPaintableForGuestValidationRef = useRef(isPaintable) useLayoutEffect(() => { if (getBrowserOverlaySlotViewport(workspaceId)) { setSlotViewportReady(true) @@ -2865,6 +2883,11 @@ function BrowserPagePane({ const initialBrowserUrlRef = useRef(browserTab.url) const browserTabUrlRef = useRef(browserTab.url) const activeLoadFailureRef = useRef(browserTab.loadError) + const recoveryNavigationValidationRef = useRef<{ + committed: boolean + started: boolean + targetUrl: string + } | null>(null) // Why: CDP viewport emulation doesn't survive renderer process swaps, so reapply the preset from this ref on every dom-ready. const viewportPresetIdRef = useRef(browserTab.viewportPresetId ?? null) viewportPresetIdRef.current = browserTab.viewportPresetId ?? null @@ -2927,6 +2950,10 @@ function BrowserPagePane({ }) const isActiveRef = useRef(isActive) isActiveRef.current = isActive + const isPaintableRef = useRef(isPaintable) + useLayoutEffect(() => { + isPaintableRef.current = isPaintable + }, [isPaintable]) const annotationViewportBridgeTokenRef = useRef(createBrowserUuid().replaceAll('-', '')) const browserAnnotations = useAppStore( (s) => s.browserAnnotationsByPageId[browserTab.id] ?? EMPTY_BROWSER_ANNOTATIONS @@ -3729,11 +3756,16 @@ function BrowserPagePane({ dismissAddressBarSuggestionsRef.current?.() } - let registrationInFlight: { webContentsId: number; promise: Promise } | null = null - const registerGuest = (): Promise => { - const webContentsId = webview.getWebContentsId() - if (registeredWebContentsIds.get(browserTab.id) === webContentsId) { - return Promise.resolve(true) + let registrationInFlight: { + webContentsId: number + promise: Promise + } | null = null + const registerGuest = (): Promise => { + let webContentsId: number + try { + webContentsId = webview.getWebContentsId() + } catch { + return Promise.resolve(null) } if (registrationInFlight?.webContentsId === webContentsId) { return registrationInFlight.promise @@ -3749,11 +3781,12 @@ function BrowserPagePane({ .then((registered) => { if (registered) { registeredWebContentsIds.set(browserTab.id, webContentsId) + return true } - return registered + return null }) - // Why: normalize IPC rejection to false so the dom-ready fallback can retry attach-policy races. - .catch(() => false) + // Why: registration rejection can be an attach-policy race; only validation of an identified guest proves loss. + .catch(() => null) .finally(() => { if (registrationInFlight?.promise === promise) { registrationInFlight = null @@ -3763,16 +3796,110 @@ function BrowserPagePane({ return promise } + const clearGuestRecoveryError = (): void => { + if (activeLoadFailureRef.current?.code !== BROWSER_GUEST_RECOVERY_ERROR_CODE) { + return + } + activeLoadFailureRef.current = null + onUpdatePageStateRef.current(browserTab.id, { loading: false, loadError: null }) + } + + const guestRecovery = createBrowserPageGuestRecovery({ + webview, + browserPageExists: () => browserPageExists(browserTab.id), + shouldValidate: () => isPaintableRef.current, + isCurrentWebview: () => webviewRef.current === webview, + isPending: () => guestRecoveryPendingRef.current, + setPending: (pending) => { + guestRecoveryPendingRef.current = pending + }, + validateRegistration: async () => { + let webContentsId: number + try { + webContentsId = webview.getWebContentsId() + } catch { + // Why: a reused webview can remount before dom-ready; only an identified guest can be declared missing. + return null + } + if (registeredWebContentsIds.get(browserTab.id) !== webContentsId) { + return registerGuest() + } + const registered = await window.api.browser.isGuestRegistered({ + browserPageId: browserTab.id, + webContentsId + }) + if (registered) { + return true + } + return window.api.browser.repairGuestRegistration({ + browserPageId: browserTab.id, + workspaceId, + worktreeId, + sessionProfileId, + webContentsId + }) + }, + replaceGuest: () => replacePersistentWebview(browserTab.id), + onReplacementReady: () => setGuestRecoveryGeneration((generation) => generation + 1), + onRecoveryFailed: () => { + const loadError = { + code: BROWSER_GUEST_RECOVERY_ERROR_CODE, + description: translate( + 'browser.guestRecovery.failed', + 'The browser page stopped unexpectedly. Retry to restore it.' + ), + validatedUrl: redactKagiSessionToken( + browserTabUrlRef.current || addressBarValueRef.current || 'about:blank' + ) + } + activeLoadFailureRef.current = loadError + onUpdatePageStateRef.current(browserTab.id, { loading: false, loadError }) + }, + onRecoverySucceeded: clearGuestRecoveryError + }) + const handleDidAttach = (): void => { // Why: register at attach since cert failures can precede dom-ready; the dom-ready path stays an idempotent fallback. - void registerGuest().finally(() => syncBrowserAnnotationViewportBridge()) + void registerGuest().then((registered) => { + if (registered === true) { + guestRecovery.confirmRegistration() + } + syncBrowserAnnotationViewportBridge() + }) } const handleDomReady = (): void => { + const validateRecoveryAfterNavigation = + recoveryNavigationValidationRef.current?.committed === true + if (validateRecoveryAfterNavigation) { + recoveryNavigationValidationRef.current = null + } + let liveWebContentsId: number | null = null + try { + liveWebContentsId = webview.getWebContentsId() + } catch { + // Why: the guest can detach between dom-ready and registration. + } const queuedAnnotationViewportBridgeSync = - registeredWebContentsIds.get(browserTab.id) !== webview.getWebContentsId() + liveWebContentsId === null || + registeredWebContentsIds.get(browserTab.id) !== liveWebContentsId if (queuedAnnotationViewportBridgeSync) { - void registerGuest().finally(() => syncBrowserAnnotationViewportBridge()) + void registerGuest().then((registered) => { + const completedRecovery = guestRecovery.finish() + if (registered === true) { + guestRecovery.confirmRegistration() + clearGuestRecoveryError() + } + if (registered === null || completedRecovery || validateRecoveryAfterNavigation) { + guestRecovery.validateAfterResume() + } + syncBrowserAnnotationViewportBridge() + }) + } else { + const completedRecovery = guestRecovery.finish() + if (completedRecovery || validateRecoveryAfterNavigation) { + guestRecovery.validateAfterResume() + } } syncNavigationState(webview) if (keepAddressBarFocusRef.current) { @@ -3836,7 +3963,18 @@ function BrowserPagePane({ }) return } - if (activeLoadFailure) { + if (activeLoadFailure?.code === BROWSER_GUEST_RECOVERY_ERROR_CODE) { + trackNextLoadingEventRef.current = false + onUpdatePageStateRef.current(browserTab.id, { + loading: false, + title: getBrowserDisplayTitle(webview.getTitle(), browserModelUrl), + faviconUrl: faviconUrlRef.current, + canGoBack: webview.canGoBack(), + canGoForward: webview.canGoForward(), + loadError: activeLoadFailure + }) + return + } else if (activeLoadFailure) { const normalizedAttemptedUrl = normalizeBrowserNavigationUrl(activeLoadFailure.validatedUrl) ?? activeLoadFailure.validatedUrl @@ -3881,7 +4019,23 @@ function BrowserPagePane({ }) } - const handleDidNavigate = (event: { url?: string; isMainFrame?: boolean }): void => { + const handleDidStartNavigation = (event: Electron.DidStartNavigationEvent): void => { + if (!event.isMainFrame || event.isInPlace || !event.url) { + return + } + const pendingRecoveryNavigation = recoveryNavigationValidationRef.current + const browserStartedUrl = redactKagiSessionToken(event.url) + const startedUrl = normalizeBrowserNavigationUrl(browserStartedUrl) ?? browserStartedUrl + if (pendingRecoveryNavigation?.targetUrl === startedUrl) { + pendingRecoveryNavigation.started = true + } + } + + const handleDidNavigate = ( + event: { url?: string; isMainFrame?: boolean }, + persistUrl = true, + preserveLoadError = false + ): void => { if (event.isMainFrame === false) { return } @@ -3890,14 +4044,17 @@ function BrowserPagePane({ return } const browserModelUrl = redactKagiSessionToken(currentUrl) - lastKnownWebviewUrlRef.current = + const normalizedBrowserModelUrl = normalizeBrowserNavigationUrl(browserModelUrl) ?? browserModelUrl + lastKnownWebviewUrlRef.current = normalizedBrowserModelUrl rememberLiveBrowserUrl(browserTab.id, browserModelUrl) // Why: don't overwrite in-progress typing (see above). if (document.activeElement !== addressBarInputRef.current) { setAddressBarValue(toDisplayUrl(browserModelUrl)) } - onSetUrlRef.current(browserTab.id, browserModelUrl) + if (persistUrl) { + onSetUrlRef.current(browserTab.id, browserModelUrl, { preserveLoadError }) + } onUpdatePageStateRef.current(browserTab.id, { title: webview.getTitle() || browserModelUrl, canGoBack: webview.canGoBack(), @@ -3905,6 +4062,22 @@ function BrowserPagePane({ }) } + const handleFullDidNavigate = (event: { url?: string; isMainFrame?: boolean }): void => { + const pendingRecoveryNavigation = recoveryNavigationValidationRef.current + if (event.isMainFrame !== false && pendingRecoveryNavigation?.started) { + pendingRecoveryNavigation.committed = true + } + const preserveRecoveryError = + activeLoadFailureRef.current?.code === BROWSER_GUEST_RECOVERY_ERROR_CODE + handleDidNavigate(event, true, preserveRecoveryError) + } + + const handleDidNavigateInPage = (event: { url?: string; isMainFrame?: boolean }): void => { + const preserveRecoveryError = + activeLoadFailureRef.current?.code === BROWSER_GUEST_RECOVERY_ERROR_CODE + handleDidNavigate(event, !preserveRecoveryError) + } + const handleTitleUpdate = (event: { title?: string }): void => { try { const currentUrl = webview.getURL() || browserTab.url @@ -3943,6 +4116,10 @@ function BrowserPagePane({ return } trackNextLoadingEventRef.current = false + const pendingRecoveryNavigation = recoveryNavigationValidationRef.current + if (pendingRecoveryNavigation?.started) { + recoveryNavigationValidationRef.current = null + } const loadError = buildLoadError(event) activeLoadFailureRef.current = loadError onUpdatePageStateRef.current(browserTab.id, { @@ -3977,19 +4154,25 @@ function BrowserPagePane({ } } + const unsubscribeSystemResumed = subscribeBrowserSystemResume(guestRecovery.validateAfterResume) + validateVisibleGuestRegistrationRef.current = guestRecovery.validateAfterResume + retryGuestRecoveryRef.current = guestRecovery.retryRecovery + webview.addEventListener('did-attach', handleDidAttach) webview.addEventListener('dom-ready', handleDomReady) + webview.addEventListener('render-process-gone', guestRecovery.recoverRenderer) webview.addEventListener('focus', dismissAddressBarSuggestions) webview.addEventListener('did-start-loading', handleDidStartLoading) + webview.addEventListener('did-start-navigation', handleDidStartNavigation) webview.addEventListener('did-stop-loading', handleDidStopLoading) // Why: close find only on full 'did-navigate', not the shared handler, which also fires on SPA in-page hash/pushState changes. const handleFindCloseOnNavigate = (): void => { setFindOpen(false) } - webview.addEventListener('did-navigate', handleDidNavigate) + webview.addEventListener('did-navigate', handleFullDidNavigate) webview.addEventListener('did-navigate', handleFindCloseOnNavigate) - webview.addEventListener('did-navigate-in-page', handleDidNavigate) + webview.addEventListener('did-navigate-in-page', handleDidNavigateInPage) webview.addEventListener('page-title-updated', handleTitleUpdate) webview.addEventListener('page-favicon-updated', handleFaviconUpdate) webview.addEventListener('did-fail-load', handleFailLoad) @@ -4002,23 +4185,39 @@ function BrowserPagePane({ trackNextLoadingEventRef.current = initialUrl !== ORCA_BROWSER_BLANK_URL lastKnownWebviewUrlRef.current = initialUrl webview.src = initialUrl + } else if (isPaintableRef.current) { + if (isBrowserPageRendererRecoveryPending(browserTab.id)) { + guestRecovery.recoverRenderer() + } else { + guestRecovery.validateAfterResume() + } } return () => { webview.removeEventListener('did-attach', handleDidAttach) webview.removeEventListener('dom-ready', handleDomReady) + webview.removeEventListener('render-process-gone', guestRecovery.recoverRenderer) webview.removeEventListener('focus', dismissAddressBarSuggestions) webview.removeEventListener('did-start-loading', handleDidStartLoading) + webview.removeEventListener('did-start-navigation', handleDidStartNavigation) webview.removeEventListener('did-stop-loading', handleDidStopLoading) - webview.removeEventListener('did-navigate', handleDidNavigate) + webview.removeEventListener('did-navigate', handleFullDidNavigate) webview.removeEventListener('did-navigate', handleFindCloseOnNavigate) - webview.removeEventListener('did-navigate-in-page', handleDidNavigate) + webview.removeEventListener('did-navigate-in-page', handleDidNavigateInPage) webview.removeEventListener('page-title-updated', handleTitleUpdate) webview.removeEventListener('page-favicon-updated', handleFaviconUpdate) webview.removeEventListener('did-fail-load', handleFailLoad) webview.removeEventListener('console-message', handleAnnotationViewportMessage) container.removeEventListener('dragover', onContainerDragOver) container.removeEventListener('drop', onContainerDrop) + unsubscribeSystemResumed() + guestRecovery.dispose() + if (validateVisibleGuestRegistrationRef.current === guestRecovery.validateAfterResume) { + validateVisibleGuestRegistrationRef.current = () => {} + } + if (retryGuestRecoveryRef.current === guestRecovery.retryRecovery) { + retryGuestRecoveryRef.current = () => {} + } if (webviewRef.current === webview) { webviewRef.current = null @@ -4033,6 +4232,7 @@ function BrowserPagePane({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [ browserTab.id, + guestRecoveryGeneration, workspaceId, slotViewportReady, webviewPartition, @@ -4044,6 +4244,14 @@ function BrowserPagePane({ syncBrowserAnnotationViewportBridge ]) + useEffect(() => { + const becamePaintable = isPaintable && !wasPaintableForGuestValidationRef.current + wasPaintableForGuestValidationRef.current = isPaintable + if (becamePaintable) { + validateVisibleGuestRegistrationRef.current() + } + }, [isPaintable]) + useLayoutEffect(() => { applyBrowserPageViewportLayout(browserTab.id, { paintable: isPaintable, active: isActive }) const syncChromeInset = (): void => { @@ -4525,11 +4733,17 @@ function BrowserPagePane({ (url: string): void => { const navigateBrowserUrl = (targetUrl: string): void => { const browserModelUrl = redactKagiSessionToken(targetUrl) + const normalizedBrowserModelUrl = + normalizeBrowserNavigationUrl(browserModelUrl) ?? browserModelUrl + const recoveryLoadError = + activeLoadFailureRef.current?.code === BROWSER_GUEST_RECOVERY_ERROR_CODE + ? activeLoadFailureRef.current + : null setAddressBarValue(toDisplayUrl(browserModelUrl)) onSetUrlRef.current(browserTab.id, browserModelUrl) onUpdatePageStateRef.current(browserTab.id, { loading: true, - loadError: null, + loadError: recoveryLoadError, title: getBrowserDisplayTitle(browserModelUrl, browserModelUrl) }) setResourceNotice(null) @@ -4539,8 +4753,10 @@ function BrowserPagePane({ return } trackNextLoadingEventRef.current = targetUrl !== ORCA_BROWSER_BLANK_URL - lastKnownWebviewUrlRef.current = - normalizeBrowserNavigationUrl(browserModelUrl) ?? browserModelUrl + lastKnownWebviewUrlRef.current = normalizedBrowserModelUrl + recoveryNavigationValidationRef.current = recoveryLoadError + ? { committed: false, started: false, targetUrl: normalizedBrowserModelUrl } + : null webview.src = targetUrl if (targetUrl !== ORCA_BROWSER_BLANK_URL) { focusWebviewNow() @@ -4768,6 +4984,7 @@ function BrowserPagePane({ return (
({ destroyPersistentWebview: vi.fn(), registerPersistentWebview: vi.fn(), + replacePersistentWebview: vi.fn(), webviewRegistry: new Map() })) vi.mock('./webview-registry', () => ({ destroyPersistentWebview: registryMocks.destroyPersistentWebview, registerPersistentWebview: registryMocks.registerPersistentWebview, + replacePersistentWebview: registryMocks.replacePersistentWebview, webviewRegistry: registryMocks.webviewRegistry })) @@ -27,6 +29,7 @@ describe('BrowserPane webview preferences', () => { beforeEach(() => { registryMocks.destroyPersistentWebview.mockReset() registryMocks.registerPersistentWebview.mockReset() + registryMocks.replacePersistentWebview.mockReset() registryMocks.webviewRegistry.clear() document.body.innerHTML = '' }) @@ -103,4 +106,38 @@ describe('BrowserPane webview preferences', () => { expect(ensuredWebview?.webview.style.pointerEvents).toBe('none') expect(refreshedContainer.lastElementChild).toBe(ensuredWebview?.webview as unknown as Element) }) + + it('keeps a replacement viewport while rebuilding a parent-drifted webview (STA-3228)', () => { + const staleContainer = createContainer('stale') + const staleWebview = document.createElement('webview') as Electron.WebviewTag + staleWebview.setAttribute('partition', 'persist:orca-browser') + staleContainer.appendChild(staleWebview) + registryMocks.webviewRegistry.set('browser-page-1', staleWebview) + const requestedContainer = createContainer('requested') + const replacementContainer = createContainer('replacement') + const resolveContainer = vi.fn(() => replacementContainer) + registryMocks.replacePersistentWebview.mockImplementation(() => { + staleWebview.remove() + staleContainer.remove() + registryMocks.webviewRegistry.delete('browser-page-1') + }) + + const ensuredWebview = ensureBrowserPageWebview({ + browserTabId: 'browser-page-1', + container: requestedContainer, + inputLocked: false, + webviewPartition: 'persist:orca-browser', + resolveContainer + }) + + expect(registryMocks.replacePersistentWebview).toHaveBeenCalledWith('browser-page-1', { + preserveViewport: true + }) + expect(resolveContainer).toHaveBeenCalledTimes(1) + expect(ensuredWebview?.container).toBe(replacementContainer) + expect(replacementContainer.isConnected).toBe(true) + expect(replacementContainer.lastElementChild).toBe( + ensuredWebview?.webview as unknown as Element + ) + }) }) diff --git a/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.test.tsx b/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.test.tsx index 4e49c241722..111890288f4 100644 --- a/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.test.tsx +++ b/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.test.tsx @@ -1,5 +1,8 @@ +// @vitest-environment happy-dom +import { cleanup, render } from '@testing-library/react' +import { Suspense } from 'react' import { renderToStaticMarkup } from 'react-dom/server' -import { beforeEach, describe, expect, it, vi } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { BrowserTab as BrowserTabState, Tab, TabGroup } from '../../../../shared/types' type MockAppState = { @@ -54,7 +57,7 @@ vi.mock('./BrowserPane', () => ({ ) })) -import BrowserPaneOverlayLayer from './BrowserPaneOverlayLayer' +import BrowserPaneOverlayLayer, { RetainedBrowserPaneOverlayLayer } from './BrowserPaneOverlayLayer' describe('BrowserPaneOverlayLayer', () => { beforeEach(() => { @@ -64,6 +67,86 @@ describe('BrowserPaneOverlayLayer', () => { mocks.state = createState() }) + afterEach(() => cleanup()) + + it('defers browser slots for a restricted hidden mount, then retains them after activation', () => { + const view = render( + + ) + + expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(0) + + view.rerender( + + ) + expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(2) + + view.rerender( + + ) + expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(2) + }) + + it('discards the retained latch when the worktree surface unmounts', () => { + const view = render( + + ) + expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(2) + + // Worktree removal (or Terminal teardown) unmounts the layer with its surface. + view.unmount() + + // A remount starts a fresh layer: the latch must reset, deferring until eligible again. + const revisit = render( + + ) + expect(revisit.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(0) + + revisit.rerender( + + ) + expect(revisit.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(2) + }) + + it('does not retain browser slots from an eligible render that never commits', () => { + const pending = new Promise(() => {}) + const BlockCommit = ({ blocked }: { blocked: boolean }): null => { + if (blocked) { + throw pending + } + return null + } + const renderBoundary = (mountEligible: boolean, blocked: boolean) => ( + }> + + + + ) + const view = render(renderBoundary(false, false)) + + view.rerender(renderBoundary(true, true)) + expect(view.container.querySelector('[data-suspended]')).not.toBeNull() + + view.rerender(renderBoundary(false, false)) + expect(view.container.querySelectorAll('[data-browser-overlay-tab-id]')).toHaveLength(0) + }) + it('keeps inactive browser panes mounted for a visible worktree', () => { const markup = renderOverlay({ isWorktreeActive: true }) diff --git a/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.tsx b/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.tsx index b019f1025e7..67d6aa4da9e 100644 --- a/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.tsx +++ b/src/renderer/src/components/browser-pane/BrowserPaneOverlayLayer.tsx @@ -1,4 +1,4 @@ -import { memo, useCallback, useMemo } from 'react' +import { memo, useCallback, useLayoutEffect, useMemo, useState } from 'react' import { registerBrowserOverlaySlotViewport } from './browser-page-viewport' import { useShallow } from 'zustand/react/shallow' import { useAppStore } from '../../store' @@ -194,4 +194,26 @@ const BrowserPaneOverlayLayer = memo(function BrowserPaneOverlayLayer({ ) }) +export const RetainedBrowserPaneOverlayLayer = memo(function RetainedBrowserPaneOverlayLayer({ + worktreeId, + isWorktreeActive, + mountEligible +}: { + worktreeId: string + isWorktreeActive: boolean + mountEligible: boolean +}): React.JSX.Element | null { + const [hasCommittedMount, setHasCommittedMount] = useState(false) + // Why: commit the latch with the persistent slot DOM so discarded renders cannot retain a guest host. + useLayoutEffect(() => { + if (mountEligible && !hasCommittedMount) { + setHasCommittedMount(true) + } + }, [hasCommittedMount, mountEligible]) + if (!mountEligible && !hasCommittedMount) { + return null + } + return +}) + export default BrowserPaneOverlayLayer diff --git a/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.test.ts b/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.test.ts new file mode 100644 index 00000000000..5557664f602 --- /dev/null +++ b/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.test.ts @@ -0,0 +1,177 @@ +import { describe, expect, it } from 'vitest' +import type { BrowserPage, BrowserWorkspace } from '../../../../shared/types' +import { + BROWSER_GUEST_HIDDEN_WORKTREE_RETENTION_LIMIT, + browserTabVisibilityPageIds, + selectBrowserGuestEvictionWorktreeIds, + touchBrowserGuestWorktreeRecency, + worktreeHoldsLiveBrowserGuests +} from './browser-guest-worktree-retention' + +function browserTab( + id: string, + pageIds: string[] = [], + activePageId: string | null = null +): BrowserWorkspace { + return { + id, + worktreeId: 'wt-1', + label: id, + sessionProfileId: null, + pageIds, + activePageId, + url: 'about:blank', + title: id, + loading: false, + faviconUrl: null, + canGoBack: false, + canGoForward: false, + loadError: null, + createdAt: 1 + } +} + +function page(id: string, workspaceId: string): BrowserPage { + return { + id, + workspaceId, + worktreeId: 'wt-1', + url: 'about:blank', + title: id, + loading: false, + faviconUrl: null, + canGoBack: false, + canGoForward: false, + loadError: null, + createdAt: 1 + } +} + +type SelectionOverrides = Partial[0]> + +function selectEvicted(overrides: SelectionOverrides): string[] { + return selectBrowserGuestEvictionWorktreeIds({ + orderedWorktreeIds: [], + activeWorktreeId: null, + isRetained: () => true, + holdsLiveGuests: () => true, + isEvictable: () => true, + ...overrides + }) +} + +describe('selectBrowserGuestEvictionWorktreeIds', () => { + const sixWorktrees = ['wt-1', 'wt-2', 'wt-3', 'wt-4', 'wt-5', 'wt-6'] + + it('is a no-op while retained guest-holding worktrees fit the budget', () => { + expect( + selectEvicted({ + orderedWorktreeIds: sixWorktrees.slice(0, BROWSER_GUEST_HIDDEN_WORKTREE_RETENTION_LIMIT) + }) + ).toEqual([]) + }) + + it('evicts the least-recently-activated worktrees beyond the budget', () => { + expect(selectEvicted({ orderedWorktreeIds: sixWorktrees })).toEqual(['wt-5', 'wt-6']) + }) + + it('never evicts or counts the active worktree', () => { + // Active most-recent: five hidden holders remain, so only the LRU one goes. + expect(selectEvicted({ orderedWorktreeIds: sixWorktrees, activeWorktreeId: 'wt-1' })).toEqual([ + 'wt-6' + ]) + // Active in LRU position: it is spared even though it ranks past the budget. + expect(selectEvicted({ orderedWorktreeIds: sixWorktrees, activeWorktreeId: 'wt-6' })).toEqual([ + 'wt-5' + ]) + }) + + it('counts only worktrees that actually hold live guests', () => { + const holders = new Set(['wt-5', 'wt-6']) + expect( + selectEvicted({ + orderedWorktreeIds: sixWorktrees, + holdsLiveGuests: (worktreeId) => holders.has(worktreeId) + }) + ).toEqual([]) + }) + + it('skips worktrees that are no longer retained', () => { + expect( + selectEvicted({ + orderedWorktreeIds: sixWorktrees, + isRetained: (worktreeId) => worktreeId !== 'wt-1' && worktreeId !== 'wt-2' + }) + ).toEqual([]) + }) + + it('keeps a non-evictable worktree retained over budget instead of evicting it', () => { + expect( + selectEvicted({ + orderedWorktreeIds: sixWorktrees, + isEvictable: (worktreeId) => worktreeId !== 'wt-5' + }) + ).toEqual(['wt-6']) + }) + + it('lets a protected worktree within the budget occupy a retained slot', () => { + expect( + selectEvicted({ + orderedWorktreeIds: ['wt-1', 'wt-2', 'wt-3', 'wt-4', 'wt-5'], + isEvictable: (worktreeId) => worktreeId !== 'wt-3' + }) + ).toEqual(['wt-5']) + }) + + it('counts duplicated recency entries once', () => { + expect( + selectEvicted({ orderedWorktreeIds: ['wt-1', 'wt-1', 'wt-2', 'wt-3', 'wt-4', 'wt-5'] }) + ).toEqual(['wt-5']) + }) + + it('honors a custom limit', () => { + expect(selectEvicted({ orderedWorktreeIds: sixWorktrees.slice(0, 3), limit: 1 })).toEqual([ + 'wt-2', + 'wt-3' + ]) + }) +}) + +describe('worktreeHoldsLiveBrowserGuests', () => { + it('detects live guests keyed by page id', () => { + const tabs = [browserTab('workspace-1', ['page-1'])] + const pages = { 'workspace-1': [page('page-1', 'workspace-1')] } + + expect(worktreeHoldsLiveBrowserGuests(tabs, pages, (id) => id === 'page-1')).toBe(true) + expect(worktreeHoldsLiveBrowserGuests(tabs, pages, () => false)).toBe(false) + }) + + it('falls back to the workspace tab id for legacy sessions without pages', () => { + const tabs = [browserTab('legacy-workspace')] + + expect(worktreeHoldsLiveBrowserGuests(tabs, {}, (id) => id === 'legacy-workspace')).toBe(true) + }) +}) + +describe('browserTabVisibilityPageIds', () => { + it('mirrors the overlay slot derivation: pageIds, then activePageId, then tab id', () => { + expect(browserTabVisibilityPageIds(browserTab('tab-1', ['page-1', 'page-2']))).toEqual([ + 'page-1', + 'page-2' + ]) + expect(browserTabVisibilityPageIds(browserTab('tab-1', [], 'page-3'))).toEqual(['page-3']) + expect(browserTabVisibilityPageIds(browserTab('tab-1'))).toEqual(['tab-1']) + }) +}) + +describe('touchBrowserGuestWorktreeRecency', () => { + it('moves a re-activated worktree to the front without duplicating it', () => { + const recency = ['wt-2', 'wt-1'] + + touchBrowserGuestWorktreeRecency(recency, 'wt-1') + expect(recency).toEqual(['wt-1', 'wt-2']) + + touchBrowserGuestWorktreeRecency(recency, 'wt-3') + expect(recency).toEqual(['wt-3', 'wt-1', 'wt-2']) + }) +}) diff --git a/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.ts b/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.ts new file mode 100644 index 00000000000..322899c279f --- /dev/null +++ b/src/renderer/src/components/browser-pane/browser-guest-worktree-retention.ts @@ -0,0 +1,84 @@ +import type { BrowserPage, BrowserWorkspace } from '../../../../shared/types' + +// Why 4: every hidden worktree that retains browser guests keeps one Electron +// guest process per page alive purely for instant revisits, so guest memory +// grew linearly with worktrees visited (#12137). Four hidden worktrees covers +// the common switch-back working set; older ones are destroyed and rebuild +// from persisted tab state on the next visit. +export const BROWSER_GUEST_HIDDEN_WORKTREE_RETENTION_LIMIT = 4 + +/** + * Hidden worktrees whose retained guests fall beyond the budget, LRU-first. + * + * orderedWorktreeIds must be most-recently-activated first (LRU order = + * worktree activation order). Only worktrees that actually hold live guests + * count toward the limit. The active worktree never counts and is never + * evicted. isEvictable is consulted lazily, only for worktrees beyond the + * limit — a non-evictable one (a guest an automation/mobile controller is + * actively driving, or one still writing a download) stays retained over + * budget. + */ +export function selectBrowserGuestEvictionWorktreeIds(args: { + orderedWorktreeIds: readonly string[] + activeWorktreeId: string | null + isRetained: (worktreeId: string) => boolean + holdsLiveGuests: (worktreeId: string) => boolean + isEvictable: (worktreeId: string) => boolean + limit?: number +}): string[] { + const limit = args.limit ?? BROWSER_GUEST_HIDDEN_WORKTREE_RETENTION_LIMIT + const evictedIds: string[] = [] + const seen = new Set() + let retained = 0 + for (const worktreeId of args.orderedWorktreeIds) { + if ( + seen.has(worktreeId) || + worktreeId === args.activeWorktreeId || + !args.isRetained(worktreeId) || + !args.holdsLiveGuests(worktreeId) + ) { + seen.add(worktreeId) + continue + } + seen.add(worktreeId) + if (retained < limit) { + retained += 1 + continue + } + if (args.isEvictable(worktreeId)) { + evictedIds.push(worktreeId) + } + } + return evictedIds +} + +// Why the fallback: webviews key by page id, but legacy sessions persisted +// before pages existed key by the workspace tab id (see collectBrowserWebviewIds). +export function worktreeHoldsLiveBrowserGuests( + browserTabs: readonly BrowserWorkspace[], + browserPagesByWorkspace: Record, + hasLiveGuest: (browserPageId: string) => boolean +): boolean { + return browserTabs.some((tab) => { + const pages = browserPagesByWorkspace[tab.id] ?? [] + if (pages.length === 0) { + return hasLiveGuest(tab.id) + } + return pages.some((page) => hasLiveGuest(page.id)) + }) +} + +// Mirrors BrowserOverlaySlot's page-id derivation so visibility pinning +// (automation-visible / mobile-driven) protects exactly the slots it paints. +export function browserTabVisibilityPageIds(tab: BrowserWorkspace): readonly string[] { + return tab.pageIds && tab.pageIds.length > 0 ? tab.pageIds : [tab.activePageId ?? tab.id] +} + +// LRU order = worktree activation order; activating moves the id to the front. +export function touchBrowserGuestWorktreeRecency(recency: string[], worktreeId: string): void { + const index = recency.indexOf(worktreeId) + if (index !== -1) { + recency.splice(index, 1) + } + recency.unshift(worktreeId) +} diff --git a/src/renderer/src/components/browser-pane/browser-load-failure-overlay.test.tsx b/src/renderer/src/components/browser-pane/browser-load-failure-overlay.test.tsx index d49e8ccdc9f..e840900c5a2 100644 --- a/src/renderer/src/components/browser-pane/browser-load-failure-overlay.test.tsx +++ b/src/renderer/src/components/browser-pane/browser-load-failure-overlay.test.tsx @@ -4,6 +4,7 @@ import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-libra import { afterEach, describe, expect, it, vi } from 'vitest' import { BrowserLoadFailureOverlay } from './browser-load-failure-overlay' +import { BROWSER_GUEST_RECOVERY_ERROR_CODE } from './browser-page-guest-recovery' const callbacks = { onRetry: vi.fn(), @@ -111,6 +112,30 @@ describe('BrowserLoadFailureOverlay', () => { expect(screen.queryByRole('button', { name: 'Try HTTPS' })).toBeNull() }) + it('presents guest recovery failures without network troubleshooting', () => { + render( + + ) + + expect(screen.getByText('Browser page stopped')).toBeInTheDocument() + expect( + screen.getByText('The browser page stopped unexpectedly. Retry to restore it.') + ).toBeInTheDocument() + expect(screen.queryByText(/make sure the server is running/i)).not.toBeInTheDocument() + expect(screen.queryByRole('button', { name: 'Try HTTPS' })).toBeNull() + expect(screen.getByRole('button', { name: 'Retry' })).toBeEnabled() + }) + it('hides Open Externally and works without an external handler', () => { render( {certificateError ? translate('browser.loadFailure.connectionNotSecure', "Connection isn't secure") - : meta.host - ? translate('browser.loadFailure.cantReachHost', "Can't reach {{value0}}", { - value0: meta.host - }) - : translate('browser.loadFailure.cantLoadPage', "Can't load this page")} + : guestRecoveryError + ? translate('browser.guestRecovery.title', 'Browser page stopped') + : meta.host + ? translate('browser.loadFailure.cantReachHost', "Can't reach {{value0}}", { + value0: meta.host + }) + : translate('browser.loadFailure.cantLoadPage', "Can't load this page")}

{formatLoadFailureDescription(presentationLoadError, meta)} @@ -312,7 +316,7 @@ export function BrowserLoadFailureOverlay({ ) : ( <> - {httpsRecoveryUrl ? ( + {httpsRecoveryUrl && !guestRecoveryError ? (